From: David Schleef Date: Sat, 15 Nov 2008 02:56:31 +0000 (+0000) Subject: gst/quicktime/gstqtmux.*: Use dts from GST_BUFFER_OFFSET_END() for video/x-qt-part. X-Git-Tag: 1.19.3~509^2~7136^2~811 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b11186eba4be193159e868e5dbf04c6ae7fed59b;p=platform%2Fupstream%2Fgstreamer.git gst/quicktime/gstqtmux.*: Use dts from GST_BUFFER_OFFSET_END() for video/x-qt-part. Original commit message from CVS: * gst/quicktime/gstqtmux.c: * gst/quicktime/gstqtmux.h: Use dts from GST_BUFFER_OFFSET_END() for video/x-qt-part. --- diff --git a/gst/quicktime/gstqtmux.c b/gst/quicktime/gstqtmux.c index ab59b48..2a6b792 100644 --- a/gst/quicktime/gstqtmux.c +++ b/gst/quicktime/gstqtmux.c @@ -206,6 +206,7 @@ gst_qt_mux_pad_reset (GstQTPad * qtpad) { qtpad->fourcc = 0; qtpad->is_out_of_order = FALSE; + qtpad->have_dts = FALSE; qtpad->sample_size = 0; qtpad->sync = FALSE; qtpad->last_dts = 0; @@ -921,7 +922,7 @@ gst_qt_mux_add_buffer (GstQTMux * qtmux, GstQTPad * pad, GstBuffer * buf) GstClockTime duration; guint nsamples, sample_size; guint64 scaled_duration, chunk_offset; - guint64 last_dts; + gint64 last_dts; gint64 pts_offset = 0; gboolean sync = FALSE, do_pts = FALSE; @@ -960,8 +961,9 @@ gst_qt_mux_add_buffer (GstQTMux * qtmux, GstQTPad * pad, GstBuffer * buf) GST_WARNING_OBJECT (qtmux, "no duration for last buffer"); /* iso spec recommends some small value, try 0 */ duration = 0; - } else + } else { duration = GST_BUFFER_DURATION (last_buf); + } } else { duration = GST_BUFFER_TIMESTAMP (buf) - GST_BUFFER_TIMESTAMP (last_buf); } @@ -982,17 +984,32 @@ gst_qt_mux_add_buffer (GstQTMux * qtmux, GstQTPad * pad, GstBuffer * buf) duration = GST_BUFFER_DURATION (last_buf) / nsamples; /* timescale = samplerate */ scaled_duration = 1; + pad->last_dts += duration * nsamples; } else { nsamples = 1; sample_size = GST_BUFFER_SIZE (last_buf); - /* first convert intended timestamp (in GstClockTime resolution) to - * trak timescale, then derive delta; - * this ensures sums of (scale)delta add up to converted timestamp, - * which only deviates at most 1/scale from timestamp itself */ - scaled_duration = gst_util_uint64_scale (pad->last_dts + duration, - atom_trak_get_timescale (pad->trak), GST_SECOND) - last_dts; + if (pad->have_dts) { + gint64 scaled_dts; + pad->last_dts = GST_BUFFER_OFFSET_END (last_buf); + if ((gint64) (pad->last_dts) < 0) { + scaled_dts = -gst_util_uint64_scale (-pad->last_dts, + atom_trak_get_timescale (pad->trak), GST_SECOND); + } else { + scaled_dts = gst_util_uint64_scale (pad->last_dts, + atom_trak_get_timescale (pad->trak), GST_SECOND); + } + scaled_duration = scaled_dts - last_dts; + last_dts = scaled_dts; + } else { + /* first convert intended timestamp (in GstClockTime resolution) to + * trak timescale, then derive delta; + * this ensures sums of (scale)delta add up to converted timestamp, + * which only deviates at most 1/scale from timestamp itself */ + scaled_duration = gst_util_uint64_scale (pad->last_dts + duration, + atom_trak_get_timescale (pad->trak), GST_SECOND) - last_dts; + pad->last_dts += duration; + } } - pad->last_dts += duration * nsamples; chunk_offset = qtmux->mdat_size; GST_LOG_OBJECT (qtmux, @@ -1020,14 +1037,14 @@ gst_qt_mux_add_buffer (GstQTMux * qtmux, GstQTPad * pad, GstBuffer * buf) * buffer timestamps in case of multiple segment, non-perfect streams * (and just perhaps maybe with some luck segment_to_running_time * or segment_to_media_time might get near to it) */ - if (qtmux->do_ctts && pad->is_out_of_order) { + if ((pad->have_dts || qtmux->guess_pts) && pad->is_out_of_order) { guint64 pts; pts = gst_util_uint64_scale (GST_BUFFER_TIMESTAMP (last_buf), atom_trak_get_timescale (pad->trak), GST_SECOND); pts_offset = (gint64) (pts - last_dts); do_pts = TRUE; - GST_LOG_OBJECT (qtmux, "Adding ctts entry for pad %s: %" G_GUINT64_FORMAT, + GST_ERROR_OBJECT (qtmux, "Adding ctts entry for pad %s: %" G_GINT64_FORMAT, GST_PAD_NAME (pad->collect.pad), pts_offset); } @@ -1178,6 +1195,7 @@ gst_qt_mux_audio_sink_set_caps (GstPad * pad, GstCaps * caps) codec_data = gst_value_get_buffer (value); qtpad->is_out_of_order = FALSE; + qtpad->have_dts = FALSE; /* set common properties */ entry.sample_rate = rate; @@ -1517,6 +1535,14 @@ gst_qt_mux_video_sink_set_caps (GstPad * pad, GstCaps * caps) gst_structure_get_fourcc (structure, "format", &fourcc); entry.fourcc = fourcc; qtpad->is_out_of_order = TRUE; + qtpad->have_dts = TRUE; + } else if (strcmp (mimetype, "video/x-mp4-part") == 0) { + guint32 fourcc; + + gst_structure_get_fourcc (structure, "format", &fourcc); + entry.fourcc = fourcc; + qtpad->is_out_of_order = TRUE; + qtpad->have_dts = TRUE; } if (!entry.fourcc) @@ -1661,7 +1687,7 @@ gst_qt_mux_get_property (GObject * object, g_value_set_uint (value, qtmux->timescale); break; case PROP_DO_CTTS: - g_value_set_boolean (value, qtmux->do_ctts); + g_value_set_boolean (value, qtmux->guess_pts); break; case PROP_FAST_START: g_value_set_boolean (value, qtmux->fast_start); @@ -1706,7 +1732,7 @@ gst_qt_mux_set_property (GObject * object, qtmux->timescale = g_value_get_uint (value); break; case PROP_DO_CTTS: - qtmux->do_ctts = g_value_get_boolean (value); + qtmux->guess_pts = g_value_get_boolean (value); break; case PROP_FAST_START: qtmux->fast_start = g_value_get_boolean (value); diff --git a/gst/quicktime/gstqtmux.h b/gst/quicktime/gstqtmux.h index 4459947..99d129e 100644 --- a/gst/quicktime/gstqtmux.h +++ b/gst/quicktime/gstqtmux.h @@ -48,6 +48,8 @@ typedef struct _GstQTPad guint32 fourcc; /* whether using format that have out of order buffers */ gboolean is_out_of_order; + /* whether upstream provides valid PTS data */ + gboolean have_dts; /* if not 0, track with constant sized samples, e.g. raw audio */ guint sample_size; /* make sync table entry */ @@ -102,7 +104,7 @@ struct _GstQTMux AtomsTreeFlavor flavor; gboolean fast_start; gboolean large_file; - gboolean do_ctts; + gboolean guess_pts; gchar *fast_start_file_path; /* for collect pads event handling function */