hlsdemux2: Mark locations where partial segments need handling

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
This commit is contained in:
Jan Schmidt 2022-07-30 00:47:18 +10:00 committed by GStreamer Marge Bot
parent cfc62a69f7
commit 92e849070f
5 changed files with 33 additions and 5 deletions

View file

@ -974,6 +974,7 @@ out:
GST_STIME_ARGS (current_segment->stream_time + GST_STIME_ARGS (current_segment->stream_time +
current_segment->duration)); current_segment->duration));
/* FIXME: Could seek to an INDEPENDENT partial segment in LL-HLS */
candidate_segment = candidate_segment =
gst_hls_media_playlist_seek (hls_stream->playlist, TRUE, gst_hls_media_playlist_seek (hls_stream->playlist, TRUE,
GST_SEEK_FLAG_SNAP_NEAREST, low_stream_time); GST_SEEK_FLAG_SNAP_NEAREST, low_stream_time);

View file

@ -514,6 +514,7 @@ gst_hls_demux_stream_seek (GstAdaptiveDemux2Stream * stream, gboolean forward,
} }
} }
/* FIXME: Allow jumping to partial segments in LL-HLS? */
new_position = new_position =
gst_hls_media_playlist_seek (hls_stream->playlist, forward, flags, ts); gst_hls_media_playlist_seek (hls_stream->playlist, forward, flags, ts);
if (new_position) { if (new_position) {
@ -1350,6 +1351,7 @@ gst_hlsdemux_handle_internal_time (GstHLSDemux * demux,
GST_DEBUG_OBJECT (hls_stream, GST_DEBUG_OBJECT (hls_stream,
"Trying to seek to the correct segment for %" GST_STIME_FORMAT, "Trying to seek to the correct segment for %" GST_STIME_FORMAT,
GST_STIME_ARGS (current_stream_time)); GST_STIME_ARGS (current_stream_time));
/* FIXME: Allow jumping to partial segments in LL-HLS */
actual_segment = actual_segment =
gst_hls_media_playlist_seek (hls_stream->playlist, TRUE, gst_hls_media_playlist_seek (hls_stream->playlist, TRUE,
GST_SEEK_FLAG_SNAP_NEAREST, current_stream_time); GST_SEEK_FLAG_SNAP_NEAREST, current_stream_time);
@ -1823,9 +1825,10 @@ gst_hls_demux_stream_advance_fragment (GstAdaptiveDemux2Stream * stream)
GST_STIME_ARGS (hlsdemux_stream->current_segment->stream_time), GST_STIME_ARGS (hlsdemux_stream->current_segment->stream_time),
GST_STR_NULL (hlsdemux_stream->current_segment->uri)); GST_STR_NULL (hlsdemux_stream->current_segment->uri));
/* FIXME: In LL-HLS, handle advancing into the partial-only segment */
new_segment = new_segment =
gst_hls_media_playlist_advance_fragment (hlsdemux_stream->playlist, gst_hls_media_playlist_advance_fragment (hlsdemux_stream->playlist,
hlsdemux_stream->current_segment, stream->demux->segment.rate > 0); hlsdemux_stream->current_segment, stream->demux->segment.rate > 0, FALSE);
if (new_segment) { if (new_segment) {
hlsdemux_stream->reset_pts = FALSE; hlsdemux_stream->reset_pts = FALSE;
if (new_segment->discont_sequence != if (new_segment->discont_sequence !=
@ -2224,6 +2227,11 @@ gst_hls_demux_stream_update_media_playlist (GstHLSDemux * demux,
new_segment = new_segment =
gst_hls_media_playlist_sync_to_segment (new_playlist, gst_hls_media_playlist_sync_to_segment (new_playlist,
stream->current_segment); stream->current_segment);
/* FIXME: Handle LL-HLS partial segment sync */
if (new_segment && new_segment->partial_only)
new_segment = NULL;
if (new_segment) { if (new_segment) {
if (new_segment->discont_sequence != if (new_segment->discont_sequence !=
stream->current_segment->discont_sequence) stream->current_segment->discont_sequence)
@ -2385,6 +2393,7 @@ gst_hls_demux_stream_update_fragment_info (GstAdaptiveDemux2Stream * stream)
GST_DEBUG_OBJECT (stream, GST_DEBUG_OBJECT (stream,
"Looking up segment for position %" GST_TIME_FORMAT, "Looking up segment for position %" GST_TIME_FORMAT,
GST_TIME_ARGS (stream->current_position)); GST_TIME_ARGS (stream->current_position));
/* FIXME: Look up partial segments in LL-HLS */
hlsdemux_stream->current_segment = hlsdemux_stream->current_segment =
gst_hls_media_playlist_seek (hlsdemux_stream->playlist, TRUE, gst_hls_media_playlist_seek (hlsdemux_stream->playlist, TRUE,
GST_SEEK_FLAG_SNAP_NEAREST, stream->current_position); GST_SEEK_FLAG_SNAP_NEAREST, stream->current_position);

View file

@ -1218,6 +1218,11 @@ gst_hls_media_playlist_seek (GstHLSMediaPlaylist * playlist, gboolean forward,
for (idx = 0; idx < playlist->segments->len; idx++) { for (idx = 0; idx < playlist->segments->len; idx++) {
GstM3U8MediaSegment *cand = g_ptr_array_index (playlist->segments, idx); GstM3U8MediaSegment *cand = g_ptr_array_index (playlist->segments, idx);
/* If only full segments was request, skip any segment that
* only has EXT-X-PARTs attached */
if (cand->partial_only && !(flags & GST_HLS_M3U8_SEEK_FLAG_ALLOW_PARTIAL))
continue;
if ((forward & snap_after) || snap_nearest) { if ((forward & snap_after) || snap_nearest) {
if (cand->stream_time >= ts || if (cand->stream_time >= ts ||
(snap_nearest && (ts - cand->stream_time < cand->duration / 2))) { (snap_nearest && (ts - cand->stream_time < cand->duration / 2))) {
@ -1736,7 +1741,8 @@ gst_hls_media_playlist_has_next_fragment (GstHLSMediaPlaylist * m3u8,
GstM3U8MediaSegment * GstM3U8MediaSegment *
gst_hls_media_playlist_advance_fragment (GstHLSMediaPlaylist * m3u8, gst_hls_media_playlist_advance_fragment (GstHLSMediaPlaylist * m3u8,
GstM3U8MediaSegment * current, gboolean forward) GstM3U8MediaSegment * current, gboolean forward,
gboolean allow_partial_only_segment)
{ {
GstM3U8MediaSegment *file = NULL; GstM3U8MediaSegment *file = NULL;
guint idx; guint idx;
@ -1768,6 +1774,12 @@ gst_hls_media_playlist_advance_fragment (GstHLSMediaPlaylist * m3u8,
idx - 1)); idx - 1));
} }
if (file && file->partial_only && !allow_partial_only_segment) {
GST_LOG
("Ignoring segment with only partials as full segment was requested");
file = NULL;
}
if (file) if (file)
GST_DEBUG ("Advanced to segment sn:%" G_GINT64_FORMAT " dsn:%" GST_DEBUG ("Advanced to segment sn:%" G_GINT64_FORMAT " dsn:%"
G_GINT64_FORMAT, file->sequence, file->discont_sequence); G_GINT64_FORMAT, file->sequence, file->discont_sequence);

View file

@ -65,6 +65,11 @@ typedef enum {
GST_HLS_PLAYLIST_TYPE_VOD, GST_HLS_PLAYLIST_TYPE_VOD,
} GstHLSPlaylistType; } GstHLSPlaylistType;
/* Extra seek flag extensions for partial segment handling
* Values are chosen to avoid collision with the core GST_SEEK_FLAG_*
* flags */
#define GST_HLS_M3U8_SEEK_FLAG_ALLOW_PARTIAL (1 << 16) /* Allow seeking to a partial segment */
/** /**
* GstHLSMediaPlaylist: * GstHLSMediaPlaylist:
* *
@ -271,7 +276,8 @@ gst_hls_media_playlist_has_next_fragment (GstHLSMediaPlaylist * m3u8,
GstM3U8MediaSegment * GstM3U8MediaSegment *
gst_hls_media_playlist_advance_fragment (GstHLSMediaPlaylist * m3u8, gst_hls_media_playlist_advance_fragment (GstHLSMediaPlaylist * m3u8,
GstM3U8MediaSegment * current, GstM3U8MediaSegment * current,
gboolean forward); gboolean forward,
gboolean allow_partial_only_segment);
GstM3U8MediaSegment * GstM3U8MediaSegment *
gst_hls_media_playlist_get_starting_segment (GstHLSMediaPlaylist *self); gst_hls_media_playlist_get_starting_segment (GstHLSMediaPlaylist *self);

View file

@ -690,7 +690,7 @@ GST_START_TEST (test_advance_fragment)
gst_m3u8_media_segment_unref (mf); gst_m3u8_media_segment_unref (mf);
/* Check next media segments */ /* Check next media segments */
mf = gst_hls_media_playlist_advance_fragment (pl, mf, TRUE); mf = gst_hls_media_playlist_advance_fragment (pl, mf, TRUE, FALSE);
fail_unless (mf != NULL); fail_unless (mf != NULL);
assert_equals_int (mf->discont, FALSE); assert_equals_int (mf->discont, FALSE);
assert_equals_string (mf->uri, "http://media.example.com/all.ts"); assert_equals_string (mf->uri, "http://media.example.com/all.ts");
@ -701,7 +701,7 @@ GST_START_TEST (test_advance_fragment)
gst_m3u8_media_segment_unref (mf); gst_m3u8_media_segment_unref (mf);
/* Check next media segments */ /* Check next media segments */
mf = gst_hls_media_playlist_advance_fragment (pl, mf, TRUE); mf = gst_hls_media_playlist_advance_fragment (pl, mf, TRUE, FALSE);
assert_equals_int (mf->discont, FALSE); assert_equals_int (mf->discont, FALSE);
assert_equals_string (mf->uri, "http://media.example.com/all.ts"); assert_equals_string (mf->uri, "http://media.example.com/all.ts");
assert_equals_uint64 (mf->stream_time, 20 * GST_SECOND); assert_equals_uint64 (mf->stream_time, 20 * GST_SECOND);