summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Dufresne <nicolas.dufresne@collabora.com>2015-04-03 20:34:42 -0400
committerNicolas Dufresne <nicolas.dufresne@collabora.com>2015-06-12 17:18:24 -0400
commit12181efddcd33dc9832fb36f8cad0399e3f032d3 (patch)
treed77cbac34d464c90e1f94e1f1570b7d6f17a81d2
parent2274ca7d07670516f02d21683d6966d67ac658f1 (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.c60
-rw-r--r--gst/isomp4/gstqtmux.h3
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;