mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-30 12:49:40 +00:00
asfdemux: Fix prerolling files with "empty" streams
This is a regression that was introduced by
commit 1803b3c185
" asfdemux: Add support for dvr-ms"
The problem is that some files/streams might contain stream definition
but there is no actual packets for those streams.
This was used to "define" streams with different bitrates for example.
The first_ts calculation resulted in never ever finding a valid first_ts
since some streams were empty, and therefore never "activating" itself.
Instead of that we first check if we are prerolled. And if we are we
unconditionally get the "first_ts"
The preroll check has been adapted to check whether streams of
each defined type (i.e. audio/video/sub) has been prerolled. This solves
the problem of having different streams of a particular type where only
one stream actually has data.
This commit is contained in:
parent
2d9867b120
commit
f86751d9f7
1 changed files with 22 additions and 11 deletions
|
@ -1304,6 +1304,7 @@ all_streams_prerolled (GstASFDemux * demux)
|
|||
{
|
||||
GstClockTime preroll_time;
|
||||
guint i, num_no_data = 0;
|
||||
AsfStreamType prerolled_types = 0, all_types = 0;
|
||||
|
||||
/* Allow at least 500ms of preroll_time */
|
||||
preroll_time = MAX (demux->preroll, 500 * GST_MSECOND);
|
||||
|
@ -1317,12 +1318,17 @@ all_streams_prerolled (GstASFDemux * demux)
|
|||
gint last_idx;
|
||||
|
||||
stream = &demux->stream[i];
|
||||
|
||||
all_types |= stream->type;
|
||||
|
||||
if (G_UNLIKELY (stream->payloads->len == 0)) {
|
||||
++num_no_data;
|
||||
GST_LOG_OBJECT (stream->pad, "no data queued");
|
||||
continue;
|
||||
}
|
||||
|
||||
prerolled_types |= stream->type;
|
||||
|
||||
/* find last payload with timestamp */
|
||||
for (last_idx = stream->payloads->len - 1;
|
||||
last_idx >= 0 && (last_payload == NULL
|
||||
|
@ -1340,6 +1346,13 @@ all_streams_prerolled (GstASFDemux * demux)
|
|||
}
|
||||
}
|
||||
|
||||
GST_LOG_OBJECT (demux, "all_types:%d prerolled_types:%d",
|
||||
all_types, prerolled_types);
|
||||
|
||||
/* If streams of each present type have prerolled, we are good to go */
|
||||
if (all_types != 0 && prerolled_types == all_types)
|
||||
return TRUE;
|
||||
|
||||
if (G_UNLIKELY (num_no_data > 0))
|
||||
return FALSE;
|
||||
|
||||
|
@ -1403,7 +1416,7 @@ gst_asf_demux_check_segment_ts (GstASFDemux * demux, GstClockTime payload_ts)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_asf_demux_check_first_ts (GstASFDemux * demux, gboolean force)
|
||||
gst_asf_demux_get_first_ts (GstASFDemux * demux)
|
||||
{
|
||||
if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (demux->first_ts))) {
|
||||
GstClockTime first_ts = GST_CLOCK_TIME_NONE;
|
||||
|
@ -1438,22 +1451,20 @@ gst_asf_demux_check_first_ts (GstASFDemux * demux, gboolean force)
|
|||
from it. I havent found a better way to distinguish between these two, except to set an arbitrary boundary
|
||||
and disregard the first 0 timestamp if the second timestamp is bigger than the boundary) */
|
||||
|
||||
if (stream_min_ts == 0 && stream_min_ts2 == GST_CLOCK_TIME_NONE && !force) /* still waiting for the second timestamp */
|
||||
return FALSE;
|
||||
GST_DEBUG_OBJECT (demux,
|
||||
"stream #%u stream_min_ts %" GST_TIME_FORMAT " stream_min_ts2 %"
|
||||
GST_TIME_FORMAT, stream->id, GST_TIME_ARGS (stream_min_ts),
|
||||
GST_TIME_ARGS (stream_min_ts2));
|
||||
|
||||
if (stream_min_ts == 0 && stream_min_ts2 > GST_SECOND) /* first timestamp is 0 and second is significantly larger, disregard the 0 */
|
||||
stream_min_ts = stream_min_ts2;
|
||||
|
||||
/* if we don't have timestamp for this stream, wait for more data */
|
||||
if (!GST_CLOCK_TIME_IS_VALID (stream_min_ts) && !force)
|
||||
return FALSE;
|
||||
|
||||
if (GST_CLOCK_TIME_IS_VALID (stream_min_ts) &&
|
||||
(!GST_CLOCK_TIME_IS_VALID (first_ts) || first_ts > stream_min_ts))
|
||||
first_ts = stream_min_ts;
|
||||
}
|
||||
|
||||
if (!GST_CLOCK_TIME_IS_VALID (first_ts)) /* can happen with force = TRUE */
|
||||
if (!GST_CLOCK_TIME_IS_VALID (first_ts)) /* can happen */
|
||||
first_ts = 0;
|
||||
|
||||
demux->first_ts = first_ts;
|
||||
|
@ -1547,14 +1558,14 @@ gst_asf_demux_check_activate_streams (GstASFDemux * demux, gboolean force)
|
|||
if (demux->activated_streams)
|
||||
return TRUE;
|
||||
|
||||
if (G_UNLIKELY (!gst_asf_demux_check_first_ts (demux, force)))
|
||||
return FALSE;
|
||||
|
||||
if (!all_streams_prerolled (demux) && !force) {
|
||||
GST_DEBUG_OBJECT (demux, "not all streams with data beyond preroll yet");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (!gst_asf_demux_get_first_ts (demux)))
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < demux->num_streams; ++i) {
|
||||
AsfStream *stream = &demux->stream[i];
|
||||
|
||||
|
|
Loading…
Reference in a new issue