hlsdemuxdemux2: Consider the hold-back when calculating seek range

When calculating the seek range for a live stream, use the same hold-back logic
as when choosing a starting segment, including low-latency segments if
enabled. Permits seeking closer to the live edge when re-synching or catching
up.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
This commit is contained in:
Jan Schmidt 2022-12-28 00:45:15 +11:00 committed by GStreamer Marge Bot
parent 083538df9e
commit 9ae3978c72
4 changed files with 30 additions and 15 deletions

View file

@ -1268,10 +1268,11 @@ gst_hls_demux_get_live_seek_range (GstAdaptiveDemux * demux, gint64 * start,
GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
gboolean ret = FALSE;
if (hlsdemux->main_stream && hlsdemux->main_stream->playlist)
if (hlsdemux->main_stream && hlsdemux->main_stream->playlist) {
ret =
gst_hls_media_playlist_get_seek_range (hlsdemux->main_stream->playlist,
start, stop);
hlsdemux->main_stream->llhls_enabled, start, stop);
}
return ret;
}

View file

@ -2487,10 +2487,9 @@ gst_hls_media_playlist_has_lost_sync (GstHLSMediaPlaylist * m3u8,
gboolean
gst_hls_media_playlist_get_seek_range (GstHLSMediaPlaylist * m3u8,
gint64 * start, gint64 * stop)
gboolean low_latency, gint64 * start, gint64 * stop)
{
GstM3U8MediaSegment *first, *last;
guint min_distance = 1;
g_return_val_if_fail (m3u8 != NULL, FALSE);
@ -2500,17 +2499,31 @@ gst_hls_media_playlist_get_seek_range (GstHLSMediaPlaylist * m3u8,
first = g_ptr_array_index (m3u8->segments, 0);
*start = first->stream_time;
if (GST_HLS_MEDIA_PLAYLIST_IS_LIVE (m3u8) && m3u8->segments->len > 1) {
/* min_distance is used to make sure the seek range is never closer than
GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE fragments from the end of a live
playlist - see 6.3.3. "Playing the Playlist file" of the HLS draft */
min_distance =
MIN (GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE, m3u8->segments->len - 1);
}
last = g_ptr_array_index (m3u8->segments, m3u8->segments->len - min_distance);
/* Default is the end of the playlist */
last = g_ptr_array_index (m3u8->segments, m3u8->segments->len - 1);
*stop = last->stream_time + last->duration;
/* For live playlists, take the minimum hold back into account
* for the end of the seek range */
if (GST_HLS_MEDIA_PLAYLIST_IS_LIVE (m3u8)) {
GstM3U8SeekResult seek_result;
if (gst_hls_media_playlist_get_starting_segment (m3u8, low_latency,
&seek_result)) {
if (seek_result.found_partial_segment) {
GstM3U8PartialSegment *part =
g_ptr_array_index (seek_result.segment->partial_segments,
seek_result.part_idx);
*stop = part->stream_time + part->duration;
} else {
*stop =
seek_result.segment->stream_time + seek_result.segment->duration;
}
gst_m3u8_media_segment_unref (seek_result.segment);
}
}
return TRUE;
}

View file

@ -335,7 +335,7 @@ gboolean
gst_hls_media_playlist_is_live (GstHLSMediaPlaylist * m3u8);
gboolean
gst_hls_media_playlist_get_seek_range (GstHLSMediaPlaylist * m3u8,
gst_hls_media_playlist_get_seek_range (GstHLSMediaPlaylist * m3u8, gboolean low_latency,
gint64 * start,
gint64 * stop);

View file

@ -524,7 +524,8 @@ GST_START_TEST (test_playlist_with_doubles_duration)
assert_equals_float (file->duration / (double) GST_SECOND, 10.2344);
file = GST_M3U8_MEDIA_SEGMENT (g_ptr_array_index (pl->segments, 3));
assert_equals_float (file->duration / (double) GST_SECOND, 9.92);
fail_unless (gst_hls_media_playlist_get_seek_range (pl, &start, &stop));
fail_unless (gst_hls_media_playlist_get_seek_range (pl, FALSE, &start,
&stop));
assert_equals_int64 (start, 0);
assert_equals_float (stop / (double) GST_SECOND,
10.321 + 9.6789 + 10.2344 + 9.92);