mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
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
This commit is contained in:
parent
2274ca7d07
commit
12181efddc
2 changed files with 56 additions and 7 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue