mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 06:58:56 +00:00
dashdemux: Try harder to not run into a loop over the same fragment over and over
While still making sure to not jump ahead one fragment further than needed.
This commit is contained in:
parent
ef8f194855
commit
6a037a78de
1 changed files with 67 additions and 12 deletions
|
@ -1589,6 +1589,10 @@ gst_dash_demux_stream_advance_sync_sample (GstAdaptiveDemuxStream * stream,
|
||||||
(target_time -
|
(target_time -
|
||||||
dashstream->current_fragment_timestamp) /
|
dashstream->current_fragment_timestamp) /
|
||||||
dashstream->current_fragment_keyframe_distance;
|
dashstream->current_fragment_keyframe_distance;
|
||||||
|
|
||||||
|
/* Prevent getting stuck in a loop due to rounding errors */
|
||||||
|
if (idx == dashstream->current_sync_sample)
|
||||||
|
idx++;
|
||||||
} else {
|
} else {
|
||||||
GstClockTime end_time =
|
GstClockTime end_time =
|
||||||
dashstream->current_fragment_timestamp +
|
dashstream->current_fragment_timestamp +
|
||||||
|
@ -1607,6 +1611,17 @@ gst_dash_demux_stream_advance_sync_sample (GstAdaptiveDemuxStream * stream,
|
||||||
}
|
}
|
||||||
idx = dashstream->moof_sync_samples->len - 1 - idx;
|
idx = dashstream->moof_sync_samples->len - 1 - idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Prevent getting stuck in a loop due to rounding errors */
|
||||||
|
if (idx == dashstream->current_sync_sample) {
|
||||||
|
if (idx == 0) {
|
||||||
|
dashstream->current_sync_sample = -1;
|
||||||
|
fragment_finished = TRUE;
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
|
|
||||||
|
idx--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1839,6 +1854,7 @@ gst_dash_demux_stream_advance_fragment (GstAdaptiveDemuxStream * stream)
|
||||||
GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (stream->demux);
|
GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (stream->demux);
|
||||||
GstClockTime target_time = GST_CLOCK_TIME_NONE;
|
GstClockTime target_time = GST_CLOCK_TIME_NONE;
|
||||||
GstClockTime actual_ts;
|
GstClockTime actual_ts;
|
||||||
|
GstClockTime previous_position;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (stream->pad, "Advance fragment");
|
GST_DEBUG_OBJECT (stream->pad, "Advance fragment");
|
||||||
|
@ -1872,6 +1888,8 @@ gst_dash_demux_stream_advance_fragment (GstAdaptiveDemuxStream * stream)
|
||||||
GST_TIME_ARGS (dashstream->average_download_time));
|
GST_TIME_ARGS (dashstream->average_download_time));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
previous_position = dashstream->actual_position;
|
||||||
|
|
||||||
/* Update internal position */
|
/* Update internal position */
|
||||||
if (GST_CLOCK_TIME_IS_VALID (dashstream->actual_position)) {
|
if (GST_CLOCK_TIME_IS_VALID (dashstream->actual_position)) {
|
||||||
GstClockTime dur;
|
GstClockTime dur;
|
||||||
|
@ -1948,19 +1966,56 @@ gst_dash_demux_stream_advance_fragment (GstAdaptiveDemuxStream * stream)
|
||||||
if (GST_CLOCK_TIME_IS_VALID (target_time)
|
if (GST_CLOCK_TIME_IS_VALID (target_time)
|
||||||
&& GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (stream->demux) &&
|
&& GST_ADAPTIVE_DEMUX_IN_TRICKMODE_KEY_UNITS (stream->demux) &&
|
||||||
dashstream->active_stream->mimeType == GST_STREAM_VIDEO) {
|
dashstream->active_stream->mimeType == GST_STREAM_VIDEO) {
|
||||||
/* Key-unit trick mode, seek to fragment containing target time */
|
GstClockTime actual_ts;
|
||||||
if (stream->segment.rate > 0)
|
GstSeekFlags flags = 0;
|
||||||
ret = gst_dash_demux_stream_seek (stream, TRUE, GST_SEEK_FLAG_SNAP_AFTER,
|
|
||||||
|
/* Key-unit trick mode, seek to fragment containing target time
|
||||||
|
*
|
||||||
|
* We first try seeking without snapping. As above code to skip keyframes
|
||||||
|
* in the current fragment was not successful, we should go at least one
|
||||||
|
* fragment ahead. Due to rounding errors we could end up at the same
|
||||||
|
* fragment again here, in which case we retry seeking with the SNAP_AFTER
|
||||||
|
* flag.
|
||||||
|
*
|
||||||
|
* We don't always set that flag as we would then end up one further
|
||||||
|
* fragment in the future in all good cases.
|
||||||
|
*/
|
||||||
|
while (TRUE) {
|
||||||
|
ret =
|
||||||
|
gst_dash_demux_stream_seek (stream, (stream->segment.rate > 0), flags,
|
||||||
target_time, &actual_ts);
|
target_time, &actual_ts);
|
||||||
else
|
|
||||||
ret = gst_dash_demux_stream_seek (stream, FALSE, GST_SEEK_FLAG_SNAP_AFTER,
|
if (ret != GST_FLOW_OK) {
|
||||||
target_time, &actual_ts);
|
GST_WARNING_OBJECT (stream->pad, "Failed to seek to %" GST_TIME_FORMAT,
|
||||||
if (ret == GST_FLOW_OK)
|
GST_TIME_ARGS (target_time));
|
||||||
GST_DEBUG_OBJECT (stream->pad, "Emergency seek to %" GST_TIME_FORMAT,
|
/* Give up */
|
||||||
GST_TIME_ARGS (actual_ts));
|
if (flags != 0)
|
||||||
else
|
break;
|
||||||
GST_WARNING_OBJECT (stream->pad, "Failed to seek to %" GST_TIME_FORMAT,
|
|
||||||
GST_TIME_ARGS (target_time));
|
/* Retry with skipping ahead */
|
||||||
|
flags |= GST_SEEK_FLAG_SNAP_AFTER;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (stream->pad,
|
||||||
|
"Skipped to %" GST_TIME_FORMAT " (wanted %" GST_TIME_FORMAT ")",
|
||||||
|
GST_TIME_ARGS (actual_ts), GST_TIME_ARGS (target_time));
|
||||||
|
|
||||||
|
if ((stream->segment.rate > 0 && actual_ts < previous_position) ||
|
||||||
|
(stream->segment.rate < 0 && actual_ts > previous_position)) {
|
||||||
|
/* Give up */
|
||||||
|
if (flags != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Retry with forcing skipping ahead */
|
||||||
|
flags |= GST_SEEK_FLAG_SNAP_AFTER;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All good */
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Normal mode, advance to the next fragment */
|
/* Normal mode, advance to the next fragment */
|
||||||
ret = gst_mpd_client_advance_segment (dashdemux->client,
|
ret = gst_mpd_client_advance_segment (dashdemux->client,
|
||||||
|
|
Loading…
Reference in a new issue