diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux-util.c b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux-util.c index 704786a039..89a949df88 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux-util.c +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux-util.c @@ -974,6 +974,7 @@ out: GST_STIME_ARGS (current_segment->stream_time + current_segment->duration)); + /* FIXME: Could seek to an INDEPENDENT partial segment in LL-HLS */ candidate_segment = gst_hls_media_playlist_seek (hls_stream->playlist, TRUE, GST_SEEK_FLAG_SNAP_NEAREST, low_stream_time); diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux.c b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux.c index b81675c0fc..09f9ead911 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux.c +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux.c @@ -514,6 +514,7 @@ gst_hls_demux_stream_seek (GstAdaptiveDemux2Stream * stream, gboolean forward, } } + /* FIXME: Allow jumping to partial segments in LL-HLS? */ new_position = gst_hls_media_playlist_seek (hls_stream->playlist, forward, flags, ts); if (new_position) { @@ -1350,6 +1351,7 @@ gst_hlsdemux_handle_internal_time (GstHLSDemux * demux, GST_DEBUG_OBJECT (hls_stream, "Trying to seek to the correct segment for %" GST_STIME_FORMAT, GST_STIME_ARGS (current_stream_time)); + /* FIXME: Allow jumping to partial segments in LL-HLS */ actual_segment = gst_hls_media_playlist_seek (hls_stream->playlist, TRUE, 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_STR_NULL (hlsdemux_stream->current_segment->uri)); + /* FIXME: In LL-HLS, handle advancing into the partial-only segment */ new_segment = 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) { hlsdemux_stream->reset_pts = FALSE; if (new_segment->discont_sequence != @@ -2224,6 +2227,11 @@ gst_hls_demux_stream_update_media_playlist (GstHLSDemux * demux, new_segment = gst_hls_media_playlist_sync_to_segment (new_playlist, 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->discont_sequence != stream->current_segment->discont_sequence) @@ -2385,6 +2393,7 @@ gst_hls_demux_stream_update_fragment_info (GstAdaptiveDemux2Stream * stream) GST_DEBUG_OBJECT (stream, "Looking up segment for position %" GST_TIME_FORMAT, GST_TIME_ARGS (stream->current_position)); + /* FIXME: Look up partial segments in LL-HLS */ hlsdemux_stream->current_segment = gst_hls_media_playlist_seek (hlsdemux_stream->playlist, TRUE, GST_SEEK_FLAG_SNAP_NEAREST, stream->current_position); diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.c b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.c index 84113bc550..614dd64552 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.c +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.c @@ -1218,6 +1218,11 @@ gst_hls_media_playlist_seek (GstHLSMediaPlaylist * playlist, gboolean forward, for (idx = 0; idx < playlist->segments->len; 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 (cand->stream_time >= ts || (snap_nearest && (ts - cand->stream_time < cand->duration / 2))) { @@ -1736,7 +1741,8 @@ gst_hls_media_playlist_has_next_fragment (GstHLSMediaPlaylist * m3u8, GstM3U8MediaSegment * gst_hls_media_playlist_advance_fragment (GstHLSMediaPlaylist * m3u8, - GstM3U8MediaSegment * current, gboolean forward) + GstM3U8MediaSegment * current, gboolean forward, + gboolean allow_partial_only_segment) { GstM3U8MediaSegment *file = NULL; guint idx; @@ -1768,6 +1774,12 @@ gst_hls_media_playlist_advance_fragment (GstHLSMediaPlaylist * m3u8, 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) GST_DEBUG ("Advanced to segment sn:%" G_GINT64_FORMAT " dsn:%" G_GINT64_FORMAT, file->sequence, file->discont_sequence); diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.h b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.h index e6339ae0bf..dc497ac2d0 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.h +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.h @@ -65,6 +65,11 @@ typedef enum { GST_HLS_PLAYLIST_TYPE_VOD, } 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: * @@ -271,7 +276,8 @@ gst_hls_media_playlist_has_next_fragment (GstHLSMediaPlaylist * m3u8, GstM3U8MediaSegment * gst_hls_media_playlist_advance_fragment (GstHLSMediaPlaylist * m3u8, GstM3U8MediaSegment * current, - gboolean forward); + gboolean forward, + gboolean allow_partial_only_segment); GstM3U8MediaSegment * gst_hls_media_playlist_get_starting_segment (GstHLSMediaPlaylist *self); diff --git a/subprojects/gst-plugins-good/tests/check/elements/hlsdemux_m3u8.c b/subprojects/gst-plugins-good/tests/check/elements/hlsdemux_m3u8.c index f21231a03c..73e0cf8dab 100644 --- a/subprojects/gst-plugins-good/tests/check/elements/hlsdemux_m3u8.c +++ b/subprojects/gst-plugins-good/tests/check/elements/hlsdemux_m3u8.c @@ -690,7 +690,7 @@ GST_START_TEST (test_advance_fragment) gst_m3u8_media_segment_unref (mf); /* 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); assert_equals_int (mf->discont, FALSE); 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); /* 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_string (mf->uri, "http://media.example.com/all.ts"); assert_equals_uint64 (mf->stream_time, 20 * GST_SECOND);