PR #25386 opened by danog
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25386
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25386.patch

A playlist whose streams all get discarded is only closed when that happens 
before the first packet, and even then the data read while probing stays 
buffered. If it's discarded later, e.g. when a player switches to another audio 
rendition:
- the playlist keeps being read until the end of its current segment;
- packets of the discarded streams are still returned;
- when the streams are enabled again, it resumes with stale data and skips a 
segment;
- an fMP4 playlist doesn't resume at all.

This closes the playlist and drops its buffered data, as `hls_read_seek()` 
does, whenever it is no longer needed.

It was tested with an API program that discards a rendition at 6 s and 
re-enables it at 12 s, on MPEG-TS, fMP4, live, muxed audio+video variants and 
WebVTT. No discarded packets are returned, playback resumes at the right 
segment, and output before the first packet is unchanged. The CLI can't toggle 
discard mid-stream, so there's no FATE test.

Kodi carries this as a patch in https://github.com/xbmc/xbmc/pull/30047, where 
VideoPlayer discards the audio renditions it doesn't play; its maintainers 
asked for FFmpeg changes to go upstream.



>From d91c9e9eb781af8ebecf832e1d45d5c757ac4e0b Mon Sep 17 00:00:00 2001
From: Daniil Gentili <[email protected]>
Date: Fri, 23 Oct 2026 11:55:46 +0200
Subject: [PATCH] avformat/hls: stop playlists discarded during playback

A playlist whose streams all get discarded is only closed when that
happens before the first packet, and even then the data read while
probing stays buffered. Discarded later, e.g. when a player switches to
another audio rendition, the playlist keeps being read until the end of
its current segment and packets of the discarded streams are still
returned. When the streams are enabled again, it resumes with the stale
data and skips a segment, and an fMP4 playlist does not resume at all.

Close the playlist and drop its buffered data, as when seeking, whenever
it is no longer needed.

Signed-off-by: Daniil Gentili <[email protected]>
---
 libavformat/hls.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/libavformat/hls.c b/libavformat/hls.c
index c68b5e88cf5..3f64c402507 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -2800,7 +2800,7 @@ static int hls_read_header(AVFormatContext *s)
     return 0;
 }
 
-static int recheck_discard_flags(AVFormatContext *s, int first)
+static int recheck_discard_flags(AVFormatContext *s)
 {
     HLSContext *c = s->priv_data;
     int i, changed = 0;
@@ -2829,11 +2829,21 @@ static int recheck_discard_flags(AVFormatContext *s, 
int first)
                 pls->seek_stream_index = -1;
             }
             av_log(s, AV_LOG_INFO, "Now receiving playlist %d, segment 
%"PRId64"\n", i, pls->cur_seq_no);
-        } else if (first && !cur_needed && pls->needed) {
+        } else if (!cur_needed && pls->needed) {
+            AVIOContext *const pb = &pls->pb.pub;
+
             ff_format_io_close(pls->parent, &pls->input);
             pls->input_read_done = 0;
             ff_format_io_close(pls->parent, &pls->input_next);
             pls->input_next_requested = 0;
+            /* Drop buffered data as hls_read_seek() does; if needed again,
+             * the playlist restarts at another segment. */
+            av_packet_unref(pls->pkt);
+            pb->buf_end = pb->buf_ptr = pb->buffer;
+            pb->pos = 0;
+            if (pls->ctx)
+                ff_read_frame_flush(pls->ctx);
+            pls->cur_init_section = NULL;
             if (pls->is_subtitle)
                 avformat_close_input(&pls->ctx);
             pls->needed = 0;
@@ -2914,7 +2924,7 @@ static int hls_read_packet(AVFormatContext *s, AVPacket 
*pkt)
     HLSContext *c = s->priv_data;
     int ret, i, minplaylist = -1;
 
-    recheck_discard_flags(s, c->first_packet);
+    recheck_discard_flags(s);
     c->first_packet = 0;
 
     for (i = 0; i < c->n_playlists; i++) {
-- 
2.54.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to