From 795cd15438639e7aa1dc1b2519d5584a098f10b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Tue, 25 Aug 2026 16:37:12 +0200 Subject: [PATCH] demux: let a demuxer mark a stream as absent Media can stop providing a stream mid-playback, for example a disc program that does not carry the Dolby Vision enhancement layer the previous one had. Since mpv always try to keep at least 1 packet buffered in all tracks, it can keep reading it till EOF. --- demux/demux.c | 19 ++++++++++++++++++- demux/demux.h | 2 ++ demux/stheader.h | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/demux/demux.c b/demux/demux.c index 48c9da4f2c..78c6b7e448 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -900,7 +900,7 @@ static void update_stream_eager_state(struct demux_internal *in) struct demux_stream *s = in->streams[n]->ds; s->still_image = s->sh->still_image; - s->eager = s->selected && !s->sh->attached_picture; + s->eager = s->selected && !s->sh->absent && !s->sh->attached_picture; if (s->eager && !s->still_image) any_av_streams |= s->type != STREAM_SUB; any_streams |= s->selected; @@ -933,6 +933,23 @@ void demux_set_stream_still_image(demuxer_t *demuxer, struct sh_stream *sh, mp_mutex_unlock(&in->lock); } +// Set whether the media provides data for this stream at all. +void demux_set_stream_absent(demuxer_t *demuxer, struct sh_stream *sh, + bool absent) +{ + struct demux_internal *in = demuxer->in; + mp_assert(demuxer == in->d_thread); + + mp_mutex_lock(&in->lock); + if (sh->absent != absent) { + MP_VERBOSE(in, "stream %d is %s\n", sh->index, + absent ? "absent" : "present"); + sh->absent = absent; + update_stream_eager_state(in); + } + mp_mutex_unlock(&in->lock); +} + static void update_stream_selection_state(struct demux_internal *in, struct demux_stream *ds) { diff --git a/demux/demux.h b/demux/demux.h index efe2be43a8..9ee332a256 100644 --- a/demux/demux.h +++ b/demux/demux.h @@ -331,6 +331,8 @@ void demux_drive_nav(struct demuxer *demuxer); void demux_nav_refresh(struct demuxer *demuxer); void demux_set_stream_still_image(struct demuxer *demuxer, struct sh_stream *sh, bool still_image); +void demux_set_stream_absent(struct demuxer *demuxer, struct sh_stream *sh, + bool absent); bool demux_cancel_test(struct demuxer *demuxer); bool demux_read_interrupted(struct demuxer *demuxer); diff --git a/demux/stheader.h b/demux/stheader.h index 01754746b2..fb50654249 100644 --- a/demux/stheader.h +++ b/demux/stheader.h @@ -68,6 +68,7 @@ struct sh_stream { bool commentary_track; // container flag bool image; // video stream is an image bool still_image; // video consists of multiple sparse still images + bool absent; // the media provides no data for this stream int hls_bitrate; int *program_ids; int num_program_ids;