diff options
author | Edward Hervey <edward@centricular.com> | 2021-07-22 15:14:26 +0200 |
---|---|---|
committer | Edward Hervey <bilboed@bilboed.com> | 2021-07-22 15:22:13 +0200 |
commit | a79a756b79aa1675e4ae14eced8b08cdd578d50a (patch) | |
tree | fd5525ddc3b8bfd0f169cb7cf8c1bca49ada4672 /gst | |
parent | 0c8d41b8b0aa94548287731760b69249777e988d (diff) | |
download | gstreamer-plugins-bad-a79a756b79aa1675e4ae14eced8b08cdd578d50a.tar.gz |
tsdemux: Handle PCR-less streams
Some programs specify a PCR PID but don't actually store any PCR values, or are
way too far apart.
In order to gracefully handle those situations, we will queue up to a certain
amount of pending buffers before deciding to give up on that PCR PID and not use
any (i.e. using DTS/PTS values as-is)
Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/issues/1629
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2422>
Diffstat (limited to 'gst')
-rw-r--r-- | gst/mpegtsdemux/tsdemux.c | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/gst/mpegtsdemux/tsdemux.c b/gst/mpegtsdemux/tsdemux.c index 2747f1447..0a2a76963 100644 --- a/gst/mpegtsdemux/tsdemux.c +++ b/gst/mpegtsdemux/tsdemux.c @@ -2261,6 +2261,7 @@ check_pending_buffers (GstTSDemux * demux) guint64 offset = 0; GList *tmp; gboolean have_only_sparse = TRUE; + gboolean exceeded_threshold = FALSE; /* 0. Do we only have sparse stream */ for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) { @@ -2282,12 +2283,38 @@ check_pending_buffers (GstTSDemux * demux) have_observation = TRUE; break; } + /* 1.2 Check if we exceeded the maximum threshold of pending data */ + if (tmpstream->pending && (tmpstream->raw_dts != -1 + || tmpstream->raw_pts != -1)) { + PendingBuffer *pend = tmpstream->pending->data; + guint64 lastval = + tmpstream->raw_dts != -1 ? tmpstream->raw_dts : tmpstream->raw_pts; + guint64 firstval = pend->dts != -1 ? pend->dts : pend->pts; + GstClockTime dur; + g_assert (firstval != -1); + dur = MPEGTIME_TO_GSTTIME (lastval - firstval); + GST_DEBUG_OBJECT (tmpstream->pad, + "Pending content duration: %" GST_TIME_FORMAT, GST_TIME_ARGS (dur)); + if (dur > 500 * GST_MSECOND) { + exceeded_threshold = TRUE; + break; + } + } } } - /* 2. If we don't have a valid value yet, break out */ - if (have_observation == FALSE) - return FALSE; + if (have_observation == FALSE) { + /* 2. If we don't have a valid value yet, break out */ + if (!exceeded_threshold) + return FALSE; + + /* Except if we've exceed the maximum amount of pending buffers, in which + * case we ignore PCR from now on */ + GST_DEBUG_OBJECT (demux, + "Saw more than 500ms of data without PCR. Ignoring PCR from now on"); + GST_MPEGTS_BASE (demux)->ignore_pcr = TRUE; + demux->program->pcr_pid = 0x1fff; + } /* 3. Go over all streams that have current/pending data */ for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) { |