mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 01:00:37 +00:00
qtmux: Fix ctts generation for streams that don't start at 0 timestamps
Subtract the first timestamp of a stream from all input buffers to get 0-based timestamps for creating a sane ctts table. Without this patch the ctts could have larger values than needed, causing the playback to have a delay at startup. As the first timestamp is only found after a few buffers are queued (due to possible reordered buffers), once we find the first timestamp we subtract it from all buffers on the queue, from that point on, all buffers have their timestamps subtract when they are collected. https://bugzilla.gnome.org/show_bug.cgi?id=658659
This commit is contained in:
parent
aea09188dc
commit
261d11a6d7
1 changed files with 65 additions and 14 deletions
|
@ -2029,6 +2029,39 @@ gst_qt_mux_push_ts (GstQTMux * qtmux, GstQTPad * pad, GstClockTime ts)
|
|||
pad->ts_n_entries++;
|
||||
}
|
||||
|
||||
static void
|
||||
check_and_subtract_ts (GstQTMux * qtmux, GstClockTime * ts_a, GstClockTime ts_b)
|
||||
{
|
||||
if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (*ts_a))) {
|
||||
if (G_LIKELY (*ts_a > ts_b)) {
|
||||
*ts_a -= ts_b;
|
||||
} else {
|
||||
*ts_a = 0;
|
||||
GST_WARNING_OBJECT (qtmux, "Subtraction would result in negative value, "
|
||||
"using 0 as result");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* subtract ts from all buffers enqueued on the pad */
|
||||
static void
|
||||
gst_qt_mux_subtract_ts (GstQTMux * qtmux, GstQTPad * pad, GstClockTime ts)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; (i < QTMUX_NO_OF_TS) && (i < pad->ts_n_entries); i++) {
|
||||
check_and_subtract_ts (qtmux, &pad->ts_entries[i], ts);
|
||||
}
|
||||
for (i = 0; i < G_N_ELEMENTS (pad->buf_entries); i++) {
|
||||
if (pad->buf_entries[i]) {
|
||||
check_and_subtract_ts (qtmux, &GST_BUFFER_TIMESTAMP (pad->buf_entries[i]),
|
||||
ts);
|
||||
check_and_subtract_ts (qtmux,
|
||||
&GST_BUFFER_OFFSET_END (pad->buf_entries[i]), ts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* takes ownership of @buf */
|
||||
static GstBuffer *
|
||||
gst_qt_mux_get_asc_buffer_ts (GstQTMux * qtmux, GstQTPad * pad, GstBuffer * buf)
|
||||
|
@ -2085,6 +2118,13 @@ gst_qt_mux_add_buffer (GstQTMux * qtmux, GstQTPad * pad, GstBuffer * buf)
|
|||
buf = pad->prepare_buf_func (pad, buf, qtmux);
|
||||
}
|
||||
|
||||
if (G_LIKELY (buf != NULL && GST_CLOCK_TIME_IS_VALID (pad->first_ts))) {
|
||||
buf = gst_buffer_make_metadata_writable (buf);
|
||||
check_and_subtract_ts (qtmux, &GST_BUFFER_TIMESTAMP (buf), pad->first_ts);
|
||||
}
|
||||
/* when we obtain the first_ts we subtract from all stored buffers we have,
|
||||
* after that we can subtract on input */
|
||||
|
||||
again:
|
||||
last_buf = pad->last_buf;
|
||||
if (qtmux->dts_method == DTS_METHOD_REORDER) {
|
||||
|
@ -2158,6 +2198,31 @@ again:
|
|||
goto no_order;
|
||||
}
|
||||
|
||||
/* if this is the first buffer, store the timestamp */
|
||||
if (G_UNLIKELY (pad->first_ts == GST_CLOCK_TIME_NONE) && last_buf) {
|
||||
if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (last_buf))) {
|
||||
pad->first_ts = GST_BUFFER_TIMESTAMP (last_buf);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (qtmux, "First buffer for pad %s has no timestamp, "
|
||||
"using 0 as first timestamp", GST_PAD_NAME (pad->collect.pad));
|
||||
pad->first_ts = 0;
|
||||
}
|
||||
GST_DEBUG_OBJECT (qtmux, "Stored first timestamp for pad %s %"
|
||||
GST_TIME_FORMAT, GST_PAD_NAME (pad->collect.pad),
|
||||
GST_TIME_ARGS (pad->first_ts));
|
||||
|
||||
gst_qt_mux_subtract_ts (qtmux, pad, pad->first_ts);
|
||||
|
||||
GST_BUFFER_TIMESTAMP (last_buf) = 0;
|
||||
check_and_subtract_ts (qtmux, &GST_BUFFER_OFFSET_END (last_buf),
|
||||
pad->first_ts);
|
||||
if (buf) {
|
||||
check_and_subtract_ts (qtmux, &GST_BUFFER_TIMESTAMP (buf), pad->first_ts);
|
||||
check_and_subtract_ts (qtmux, &GST_BUFFER_OFFSET_END (buf),
|
||||
pad->first_ts);
|
||||
}
|
||||
}
|
||||
|
||||
/* fall back to duration if last buffer or
|
||||
* out-of-order (determined previously), otherwise use input ts */
|
||||
if (buf == NULL ||
|
||||
|
@ -2317,20 +2382,6 @@ again:
|
|||
qtmux->longest_chunk = duration;
|
||||
}
|
||||
|
||||
/* if this is the first buffer, store the timestamp */
|
||||
if (G_UNLIKELY (pad->first_ts == GST_CLOCK_TIME_NONE) && last_buf) {
|
||||
if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (last_buf))) {
|
||||
pad->first_ts = GST_BUFFER_TIMESTAMP (last_buf);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (qtmux, "First buffer for pad %s has no timestamp, "
|
||||
"using 0 as first timestamp", GST_PAD_NAME (pad->collect.pad));
|
||||
pad->first_ts = 0;
|
||||
}
|
||||
GST_DEBUG_OBJECT (qtmux, "Stored first timestamp for pad %s %"
|
||||
GST_TIME_FORMAT, GST_PAD_NAME (pad->collect.pad),
|
||||
GST_TIME_ARGS (pad->first_ts));
|
||||
}
|
||||
|
||||
/* now we go and register this buffer/sample all over */
|
||||
/* note that a new chunk is started each time (not fancy but works) */
|
||||
if (qtmux->moov_recov_file) {
|
||||
|
|
Loading…
Reference in a new issue