From efe4bc244daf74c1e7c1b25b69caa18750617e7f Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Tue, 22 Nov 2005 17:09:36 +0000 Subject: [PATCH] ext/dv/: Fractional framerates for DV. Original commit message from CVS: * ext/dv/gstdvdec.c: (gst_dvdec_init), (gst_dvdec_sink_setcaps): * ext/dv/gstdvdec.h: * ext/dv/gstdvdemux.c: (gst_dvdemux_init), (gst_dvdemux_src_convert), (gst_dvdemux_sink_convert), (gst_dvdemux_demux_video), (gst_dvdemux_demux_frame), (gst_dvdemux_flush): * ext/dv/gstdvdemux.h: Fractional framerates for DV. --- ChangeLog | 11 +++++++++++ ext/dv/gstdvdec.c | 23 +++++++++++++--------- ext/dv/gstdvdec.h | 3 ++- ext/dv/gstdvdemux.c | 48 ++++++++++++++++++++++++++++++++------------- ext/dv/gstdvdemux.h | 4 +++- 5 files changed, 64 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2820f98dd5..1fc8b592ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2005-11-22 Michael Smith + + * ext/dv/gstdvdec.c: (gst_dvdec_init), (gst_dvdec_sink_setcaps): + * ext/dv/gstdvdec.h: + * ext/dv/gstdvdemux.c: (gst_dvdemux_init), + (gst_dvdemux_src_convert), (gst_dvdemux_sink_convert), + (gst_dvdemux_demux_video), (gst_dvdemux_demux_frame), + (gst_dvdemux_flush): + * ext/dv/gstdvdemux.h: + Fractional framerates for DV. + 2005-11-22 Tim-Philipp Müller * gst/autodetect/gstautoaudiosink.c: diff --git a/ext/dv/gstdvdec.c b/ext/dv/gstdvdec.c index 44c52ccf38..113dc341ad 100644 --- a/ext/dv/gstdvdec.c +++ b/ext/dv/gstdvdec.c @@ -67,7 +67,7 @@ static GstStaticPadTemplate src_temp = GST_STATIC_PAD_TEMPLATE ("src", GST_STATIC_CAPS ("video/x-raw-yuv, " "format = (fourcc) YUY2, " "width = (int) 720, " - "framerate = (double) [ 1.0, 60.0 ];" + "framerate = (fraction) [ 1/1, 60/1 ];" "video/x-raw-rgb, " "bpp = (int) 32, " "depth = (int) 24, " @@ -76,7 +76,7 @@ static GstStaticPadTemplate src_temp = GST_STATIC_PAD_TEMPLATE ("src", "green_mask = (int) 0x00ff0000, " "blue_mask = (int) 0xff000000, " "width = (int) 720, " - "framerate = (double) [ 1.0, 60.0 ];" + "framerate = (fraction) [ 1/1, 60/1 ];" "video/x-raw-rgb, " "bpp = (int) 24, " "depth = (int) 24, " @@ -84,7 +84,7 @@ static GstStaticPadTemplate src_temp = GST_STATIC_PAD_TEMPLATE ("src", "red_mask = (int) 0x00ff0000, " "green_mask = (int) 0x0000ff00, " "blue_mask = (int) 0x000000ff, " - "width = (int) 720, " "framerate = (double) [ 1.0, 60.0 ]") + "width = (int) 720, " "framerate = (fraction) [ 1/1, 60/1 ]") ); #define GST_TYPE_DVDEC_QUALITY (gst_dvdec_quality_get_type()) @@ -186,7 +186,8 @@ gst_dvdec_init (GstDVDec * dvdec, GstDVDecClass * g_class) gst_element_add_pad (GST_ELEMENT (dvdec), dvdec->srcpad); - dvdec->framerate = 0; + dvdec->framerate_numerator = 0; + dvdec->framerate_denominator = 0; dvdec->height = 0; dvdec->wide = FALSE; dvdec->drop_factor = 1; @@ -203,7 +204,7 @@ gst_dvdec_sink_setcaps (GstPad * pad, GstCaps * caps) GstDVDec *dvdec; GstStructure *s; GstCaps *othercaps; - const GValue *v; + const GValue *par, *rate; dvdec = GST_DVDEC (gst_pad_get_parent (pad)); @@ -212,11 +213,14 @@ gst_dvdec_sink_setcaps (GstPad * pad, GstCaps * caps) if (!gst_structure_get_int (s, "height", &dvdec->height)) goto error; - if (!(v = gst_structure_get_value (s, "pixel-aspect-ratio"))) + if (!(par = gst_structure_get_value (s, "pixel-aspect-ratio"))) goto error; - if (!gst_structure_get_double (s, "framerate", &dvdec->framerate)) + if (!(rate = gst_structure_get_value (s, "framerate"))) goto error; + dvdec->framerate_numerator = gst_value_get_fraction_numerator (rate); + dvdec->framerate_denominator = gst_value_get_fraction_denominator (rate); + /* ignoring rgb, bgr0 for now */ dvdec->bpp = 2; @@ -225,9 +229,10 @@ gst_dvdec_sink_setcaps (GstPad * pad, GstCaps * caps) "format", GST_TYPE_FOURCC, GST_STR_FOURCC ("YUY2"), "width", G_TYPE_INT, 720, "height", G_TYPE_INT, dvdec->height, - "framerate", G_TYPE_DOUBLE, dvdec->framerate, NULL); + "framerate", GST_TYPE_FRACTION, dvdec->framerate_numerator, + dvdec->framerate_denominator, NULL); gst_structure_set_value (gst_caps_get_structure (othercaps, 0), - "pixel-aspect-ratio", v); + "pixel-aspect-ratio", par); gst_pad_set_caps (dvdec->srcpad, othercaps); diff --git a/ext/dv/gstdvdec.h b/ext/dv/gstdvdec.h index 9f1fba4c94..3fc58d9620 100644 --- a/ext/dv/gstdvdec.h +++ b/ext/dv/gstdvdec.h @@ -58,7 +58,8 @@ struct _GstDVDec { gint frame_len; gboolean PAL; - gdouble framerate; + gint framerate_numerator; + gint framerate_denominator; gint height; gboolean wide; diff --git a/ext/dv/gstdvdemux.c b/ext/dv/gstdvdemux.c index 882b270ff0..f7f90f804d 100644 --- a/ext/dv/gstdvdemux.c +++ b/ext/dv/gstdvdemux.c @@ -66,11 +66,13 @@ #define NTSC_HEIGHT 480 #define NTSC_BUFFER 120000 -#define NTSC_FRAMERATE 30000/1001. +#define NTSC_FRAMERATE_NUMERATOR 30000 +#define NTSC_FRAMERATE_DENOMINATOR 1001 #define PAL_HEIGHT 576 #define PAL_BUFFER 144000 -#define PAL_FRAMERATE 25.0 +#define PAL_FRAMERATE_NUMERATOR 25 +#define PAL_FRAMERATE_DENOMINATOR 1 #define PAL_NORMAL_PAR_X 59 #define PAL_NORMAL_PAR_Y 54 @@ -187,7 +189,9 @@ gst_dvdemux_init (GstDVDemux * dvdemux, GstDVDemuxClass * g_class) dvdemux->stop_timestamp = -1LL; dvdemux->need_discont = FALSE; dvdemux->new_media = FALSE; - dvdemux->framerate = 0; + dvdemux->framerate_numerator = 0; + dvdemux->framerate_denominator = 0; + dvdemux->total_frames = 0; dvdemux->height = 0; dvdemux->frequency = 0; dvdemux->channels = 0; @@ -263,8 +267,9 @@ gst_dvdemux_src_convert (GstPad * pad, GstFormat src_format, gint64 src_value, case GST_FORMAT_TIME: *dest_format = GST_FORMAT_TIME; if (pad == dvdemux->videosrcpad) - *dest_value = src_value * GST_SECOND / - (dvdemux->frame_len * dvdemux->framerate); + *dest_value = src_value * GST_SECOND * + dvdemux->framerate_denominator / + (dvdemux->frame_len * dvdemux->framerate_numerator); else if (pad == dvdemux->audiosrcpad) *dest_value = src_value * GST_SECOND / (2 * dvdemux->frequency * dvdemux->channels); @@ -277,8 +282,9 @@ gst_dvdemux_src_convert (GstPad * pad, GstFormat src_format, gint64 src_value, switch (*dest_format) { case GST_FORMAT_BYTES: if (pad == dvdemux->videosrcpad) - *dest_value = src_value * dvdemux->frame_len * dvdemux->framerate - / GST_SECOND; + *dest_value = src_value * dvdemux->frame_len * + dvdemux->framerate_numerator / + (dvdemux->framerate_denominator * GST_SECOND); else if (pad == dvdemux->audiosrcpad) *dest_value = 2 * src_value * dvdemux->frequency * dvdemux->channels / GST_SECOND; @@ -286,7 +292,8 @@ gst_dvdemux_src_convert (GstPad * pad, GstFormat src_format, gint64 src_value, case GST_FORMAT_DEFAULT: if (pad == dvdemux->videosrcpad) { if (src_value) - *dest_value = src_value * dvdemux->framerate / GST_SECOND; + *dest_value = src_value * dvdemux->framerate_numerator / + (dvdemux->framerate_denominator * GST_SECOND); else *dest_value = 0; } else if (pad == dvdemux->audiosrcpad) { @@ -303,7 +310,8 @@ gst_dvdemux_src_convert (GstPad * pad, GstFormat src_format, gint64 src_value, switch (*dest_format) { case GST_FORMAT_TIME: if (pad == dvdemux->videosrcpad) { - *dest_value = src_value * GST_SECOND / dvdemux->framerate; + *dest_value = src_value * GST_SECOND * + dvdemux->framerate_denominator / dvdemux->framerate_numerator; } else if (pad == dvdemux->audiosrcpad) { if (src_value) *dest_value = @@ -376,7 +384,8 @@ gst_dvdemux_sink_convert (GstPad * pad, GstFormat src_format, gint64 src_value, /* get frame number */ frame = src_value / dvdemux->frame_len; - *dest_value = (frame * GST_SECOND) / dvdemux->framerate; + *dest_value = (frame * GST_SECOND * dvdemux->framerate_denominator) / + dvdemux->framerate_numerator; break; } default: @@ -390,7 +399,8 @@ gst_dvdemux_sink_convert (GstPad * pad, GstFormat src_format, gint64 src_value, guint64 frame; /* calculate the frame */ - frame = src_value * dvdemux->framerate / GST_SECOND; + frame = src_value * dvdemux->framerate_numerator / + (dvdemux->framerate_denominator * GST_SECOND); /* calculate the offset */ *dest_value = frame * dvdemux->frame_len; break; @@ -825,7 +835,8 @@ gst_dvdemux_demux_video (GstDVDemux * dvdemux, const guint8 * data) "systemstream", G_TYPE_BOOLEAN, FALSE, "width", G_TYPE_INT, 720, "height", G_TYPE_INT, height, - "framerate", G_TYPE_DOUBLE, dvdemux->framerate, + "framerate", GST_TYPE_FRACTION, dvdemux->framerate_numerator, + dvdemux->framerate_denominator, "pixel-aspect-ratio", GST_TYPE_FRACTION, par_x, par_y, NULL); gst_pad_set_caps (dvdemux->videosrcpad, caps); gst_caps_unref (caps); @@ -893,7 +904,10 @@ gst_dvdemux_demux_frame (GstDVDemux * dvdemux, const guint8 * data) dvdemux->need_discont = FALSE; } - next_ts = dvdemux->timestamp + GST_SECOND / dvdemux->framerate; + dvdemux->total_frames++; + + next_ts = dvdemux->total_frames * GST_SECOND * + dvdemux->framerate_denominator / dvdemux->framerate_numerator; dvdemux->duration = next_ts - dvdemux->timestamp; dv_parse_packs (dvdemux->decoder, data); @@ -948,7 +962,13 @@ gst_dvdemux_flush (GstDVDemux * dvdemux) /* after parsing the header we know the length of the data */ dvdemux->PAL = dv_system_50_fields (dvdemux->decoder); length = dvdemux->frame_len = (dvdemux->PAL ? PAL_BUFFER : NTSC_BUFFER); - dvdemux->framerate = dvdemux->PAL ? PAL_FRAMERATE : NTSC_FRAMERATE; + if (dvdemux->PAL) { + dvdemux->framerate_numerator = PAL_FRAMERATE_NUMERATOR; + dvdemux->framerate_denominator = PAL_FRAMERATE_DENOMINATOR; + } else { + dvdemux->framerate_numerator = NTSC_FRAMERATE_NUMERATOR; + dvdemux->framerate_denominator = NTSC_FRAMERATE_DENOMINATOR; + } /* let demux_video set the height, it needs to detect when things change so * it can reset caps */ diff --git a/ext/dv/gstdvdemux.h b/ext/dv/gstdvdemux.h index dde236a533..53121e348d 100644 --- a/ext/dv/gstdvdemux.h +++ b/ext/dv/gstdvdemux.h @@ -61,7 +61,8 @@ struct _GstDVDemux { /* PAL or NTSC flag */ gboolean PAL; /* video params */ - gdouble framerate; + gint framerate_numerator; + gint framerate_denominator; gint height; gboolean wide; /* audio params */ @@ -72,6 +73,7 @@ struct _GstDVDemux { guint64 timestamp; guint64 duration; + guint total_frames; guint64 audio_offset; guint64 video_offset;