diff options
author | Nicolas Dufresne <nicolas.dufresne@collabora.com> | 2015-04-03 20:34:42 -0400 |
---|---|---|
committer | Nicolas Dufresne <nicolas.dufresne@collabora.com> | 2015-06-12 17:18:24 -0400 |
commit | 12181efddcd33dc9832fb36f8cad0399e3f032d3 (patch) | |
tree | d77cbac34d464c90e1f94e1f1570b7d6f17a81d2 | |
parent | 2274ca7d07670516f02d21683d6966d67ac658f1 (diff) |
qtmux: Handle DTS with negative running time
As QT works with duration, simply bring back first DTS to 0 and shift
forward the PTS of the same amount.
https://bugzilla.gnome.org/show_bug.cgi?id=740575
-rw-r--r-- | gst/isomp4/gstqtmux.c | 60 | ||||
-rw-r--r-- | gst/isomp4/gstqtmux.h | 3 |
2 files changed, 56 insertions, 7 deletions
diff --git a/gst/isomp4/gstqtmux.c b/gst/isomp4/gstqtmux.c index 9690eb5fd..331010d94 100644 --- a/gst/isomp4/gstqtmux.c +++ b/gst/isomp4/gstqtmux.c @@ -493,6 +493,7 @@ gst_qt_mux_pad_reset (GstQTPad * qtpad) qtpad->sample_size = 0; qtpad->sync = FALSE; qtpad->last_dts = 0; + qtpad->dts_adjustment = GST_CLOCK_TIME_NONE; qtpad->first_ts = GST_CLOCK_TIME_NONE; qtpad->prepare_buf_func = NULL; qtpad->create_empty_buffer = NULL; @@ -2996,9 +2997,6 @@ gst_qt_mux_add_buffer (GstQTMux * qtmux, GstQTPad * pad, GstBuffer * buf) GST_BUFFER_DTS (buf)) { GST_BUFFER_DTS (buf) = GST_BUFFER_DTS (last_buf) + last_buf_duration; } - - if (GST_BUFFER_PTS_IS_VALID (buf)) - GST_BUFFER_DTS (buf) = MIN (GST_BUFFER_DTS (buf), GST_BUFFER_PTS (buf)); } if (last_buf && !buf && !GST_BUFFER_DURATION_IS_VALID (last_buf)) { @@ -3248,6 +3246,57 @@ not_negotiated: } } +/* + * DTS running time can be negative. There is no way to represent that in + * MP4 however, thus we need to offset DTS so that it starts from 0. + */ +static void +gst_qt_pad_adjust_buffer_dts (GstQTMux * qtmux, GstQTPad * pad, + GstCollectData * cdata, GstBuffer ** buf) +{ + GstClockTime pts; + gint64 dts; + + pts = GST_BUFFER_PTS (*buf); + dts = GST_COLLECT_PADS_DTS (cdata); + + GST_LOG_OBJECT (qtmux, "selected pad %s with PTS %" GST_TIME_FORMAT + " and DTS %" GST_STIME_FORMAT, GST_PAD_NAME (cdata->pad), + GST_TIME_ARGS (pts), GST_STIME_ARGS (dts)); + + if (!GST_CLOCK_TIME_IS_VALID (pad->dts_adjustment)) { + if (GST_CLOCK_STIME_IS_VALID (dts) && dts < 0) + pad->dts_adjustment = -dts; + else + pad->dts_adjustment = 0; + } + + if (pad->dts_adjustment > 0) { + *buf = gst_buffer_make_writable (*buf); + + dts += pad->dts_adjustment; + + if (GST_CLOCK_TIME_IS_VALID (pts)) + pts += pad->dts_adjustment; + + if (GST_CLOCK_STIME_IS_VALID (dts) && dts < 0) { + GST_WARNING_OBJECT (pad, "Decreasing DTS."); + dts = 0; + } + + if (pts < dts) { + GST_WARNING_OBJECT (pad, "DTS is bigger then PTS"); + pts = dts; + } + + GST_BUFFER_PTS (*buf) = pts; + GST_BUFFER_DTS (*buf) = dts; + + GST_LOG_OBJECT (qtmux, "time adjusted to PTS %" GST_TIME_FORMAT + " and DTS %" GST_TIME_FORMAT, GST_TIME_ARGS (pts), GST_TIME_ARGS (dts)); + } +} + static GstFlowReturn gst_qt_mux_handle_buffer (GstCollectPads * pads, GstCollectData * cdata, GstBuffer * buf, gpointer user_data) @@ -3255,7 +3304,6 @@ gst_qt_mux_handle_buffer (GstCollectPads * pads, GstCollectData * cdata, GstFlowReturn ret = GST_FLOW_OK; GstQTMux *qtmux = GST_QT_MUX_CAST (user_data); GstQTPad *best_pad = NULL; - GstClockTime best_time = GST_CLOCK_TIME_NONE; if (G_UNLIKELY (qtmux->state == GST_QT_MUX_STATE_STARTED)) { if ((ret = gst_qt_mux_start_file (qtmux)) != GST_FLOW_OK) @@ -3272,9 +3320,7 @@ gst_qt_mux_handle_buffer (GstCollectPads * pads, GstCollectData * cdata, /* clipping already converted to running time */ if (best_pad != NULL) { g_assert (buf); - best_time = GST_BUFFER_PTS (buf); - GST_LOG_OBJECT (qtmux, "selected pad %s with time %" GST_TIME_FORMAT, - GST_PAD_NAME (best_pad->collect.pad), GST_TIME_ARGS (best_time)); + gst_qt_pad_adjust_buffer_dts (qtmux, best_pad, cdata, &buf); ret = gst_qt_mux_add_buffer (qtmux, best_pad, buf); } else { qtmux->state = GST_QT_MUX_STATE_EOS; diff --git a/gst/isomp4/gstqtmux.h b/gst/isomp4/gstqtmux.h index b3b0261fb..bf9317947 100644 --- a/gst/isomp4/gstqtmux.h +++ b/gst/isomp4/gstqtmux.h @@ -109,6 +109,9 @@ struct _GstQTPad /* dts of last_buf */ GstClockTime last_dts; + /* This is compensate for CTTS */ + GstClockTime dts_adjustment; + /* store the first timestamp for comparing with other streams and * know if there are late streams */ GstClockTime first_ts; |