diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux-stream.c b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux-stream.c index 2c4e6eb4b8..cbfdc032ab 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux-stream.c +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux-stream.c @@ -1675,6 +1675,58 @@ lost_sync: } } +GstClockTime +gst_hls_demux_stream_get_playlist_reload_interval (GstHLSDemuxStream * stream) +{ + GstHLSMediaPlaylist *playlist = stream->playlist; + + if (playlist == NULL) + return GST_CLOCK_TIME_NONE; /* No playlist yet */ + + if (!gst_hls_media_playlist_is_live (playlist)) + return GST_CLOCK_TIME_NONE; /* Not live playback */ + + /* Use the most recent segment (or part segment) duration, as per + * https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis-11#section-6.3.4 + */ + GstClockTime target_duration = GST_CLOCK_TIME_NONE; + GstClockTime min_reload_interval = playlist->targetduration / 2; + + if (playlist->segments->len) { + GstM3U8MediaSegment *last_seg = + g_ptr_array_index (playlist->segments, playlist->segments->len - 1); + + target_duration = last_seg->duration; + + if (stream->llhls_enabled && last_seg->partial_segments) { + GstM3U8PartialSegment *last_part = + g_ptr_array_index (last_seg->partial_segments, + last_seg->partial_segments->len - 1); + + target_duration = last_part->duration; + if (GST_CLOCK_TIME_IS_VALID (playlist->partial_targetduration)) { + min_reload_interval = playlist->partial_targetduration / 2; + } else { + min_reload_interval = target_duration / 2; + } + } + } else if (stream->llhls_enabled + && GST_CLOCK_TIME_IS_VALID (playlist->partial_targetduration)) { + target_duration = playlist->partial_targetduration; + min_reload_interval = target_duration / 2; + } else if (playlist->version > 5) { + target_duration = playlist->targetduration; + } + + if (playlist->reloaded && target_duration > min_reload_interval) { + GST_DEBUG_OBJECT (stream, + "Playlist didn't change previously, returning lower update interval"); + target_duration = min_reload_interval; + } + + return target_duration; +} + static GstFlowReturn gst_hls_demux_stream_update_rendition_playlist (GstHLSDemux * demux, GstHLSDemuxStream * stream) diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux-stream.h b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux-stream.h index 0df4fdd01e..3ca4a44860 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux-stream.h +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux-stream.h @@ -165,6 +165,9 @@ gst_hls_demux_stream_seek (GstAdaptiveDemux2Stream * stream, gboolean forward, GstFlowReturn gst_hls_demux_stream_update_media_playlist (GstHLSDemuxStream * stream, gchar ** uri, GError ** err); +GstClockTime +gst_hls_demux_stream_get_playlist_reload_interval (GstHLSDemuxStream * stream); + void gst_hls_demux_stream_clear_pending_data (GstHLSDemuxStream * hls_stream, gboolean force); diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux.c b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux.c index f5c453d2ad..c400e409fc 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux.c +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux.c @@ -745,7 +745,7 @@ gst_hls_demux_is_live (GstAdaptiveDemux * demux) GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux); gboolean is_live = FALSE; - if (hlsdemux->main_stream) + if (hlsdemux->main_stream && hlsdemux->main_stream->playlist) is_live = gst_hls_media_playlist_is_live (hlsdemux->main_stream->playlist); return is_live; @@ -1258,22 +1258,11 @@ gst_hls_demux_get_manifest_update_interval (GstAdaptiveDemux * demux) { GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux); GstClockTime target_duration = 5 * GST_SECOND; + GstHLSDemuxStream *main_stream = hlsdemux->main_stream; - if (hlsdemux->main_stream && hlsdemux->main_stream->playlist) { - GstHLSMediaPlaylist *playlist = hlsdemux->main_stream->playlist; - - if (playlist->version > 5) { - target_duration = hlsdemux->main_stream->playlist->targetduration; - } else if (playlist->segments->len) { - GstM3U8MediaSegment *last_seg = - g_ptr_array_index (playlist->segments, playlist->segments->len - 1); - target_duration = last_seg->duration; - } - if (playlist->reloaded && target_duration > (playlist->targetduration / 2)) { - GST_DEBUG_OBJECT (demux, - "Playlist didn't change previously, returning lower update interval"); - target_duration /= 2; - } + if (main_stream) { + target_duration = + gst_hls_demux_stream_get_playlist_reload_interval (main_stream); } GST_DEBUG_OBJECT (demux, "Returning update interval of %" GST_TIME_FORMAT,