mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +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->sample_size = 0;
|
||||||
qtpad->sync = FALSE;
|
qtpad->sync = FALSE;
|
||||||
qtpad->last_dts = 0;
|
qtpad->last_dts = 0;
|
||||||
|
qtpad->dts_adjustment = GST_CLOCK_TIME_NONE;
|
||||||
qtpad->first_ts = GST_CLOCK_TIME_NONE;
|
qtpad->first_ts = GST_CLOCK_TIME_NONE;
|
||||||
qtpad->prepare_buf_func = NULL;
|
qtpad->prepare_buf_func = NULL;
|
||||||
qtpad->create_empty_buffer = 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 (buf) = GST_BUFFER_DTS (last_buf) + last_buf_duration;
|
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)) {
|
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
|
static GstFlowReturn
|
||||||
gst_qt_mux_handle_buffer (GstCollectPads * pads, GstCollectData * cdata,
|
gst_qt_mux_handle_buffer (GstCollectPads * pads, GstCollectData * cdata,
|
||||||
GstBuffer * buf, gpointer user_data)
|
GstBuffer * buf, gpointer user_data)
|
||||||
|
@ -3255,7 +3304,6 @@ gst_qt_mux_handle_buffer (GstCollectPads * pads, GstCollectData * cdata,
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
GstQTMux *qtmux = GST_QT_MUX_CAST (user_data);
|
GstQTMux *qtmux = GST_QT_MUX_CAST (user_data);
|
||||||
GstQTPad *best_pad = NULL;
|
GstQTPad *best_pad = NULL;
|
||||||
GstClockTime best_time = GST_CLOCK_TIME_NONE;
|
|
||||||
|
|
||||||
if (G_UNLIKELY (qtmux->state == GST_QT_MUX_STATE_STARTED)) {
|
if (G_UNLIKELY (qtmux->state == GST_QT_MUX_STATE_STARTED)) {
|
||||||
if ((ret = gst_qt_mux_start_file (qtmux)) != GST_FLOW_OK)
|
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 */
|
/* clipping already converted to running time */
|
||||||
if (best_pad != NULL) {
|
if (best_pad != NULL) {
|
||||||
g_assert (buf);
|
g_assert (buf);
|
||||||
best_time = GST_BUFFER_PTS (buf);
|
gst_qt_pad_adjust_buffer_dts (qtmux, best_pad, cdata, &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));
|
|
||||||
ret = gst_qt_mux_add_buffer (qtmux, best_pad, buf);
|
ret = gst_qt_mux_add_buffer (qtmux, best_pad, buf);
|
||||||
} else {
|
} else {
|
||||||
qtmux->state = GST_QT_MUX_STATE_EOS;
|
qtmux->state = GST_QT_MUX_STATE_EOS;
|
||||||
|
|
|
@ -109,6 +109,9 @@ struct _GstQTPad
|
||||||
/* dts of last_buf */
|
/* dts of last_buf */
|
||||||
GstClockTime last_dts;
|
GstClockTime last_dts;
|
||||||
|
|
||||||
|
/* This is compensate for CTTS */
|
||||||
|
GstClockTime dts_adjustment;
|
||||||
|
|
||||||
/* store the first timestamp for comparing with other streams and
|
/* store the first timestamp for comparing with other streams and
|
||||||
* know if there are late streams */
|
* know if there are late streams */
|
||||||
GstClockTime first_ts;
|
GstClockTime first_ts;
|
||||||
|
|
Loading…
Reference in a new issue