summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido Cella <guido@guidocella.xyz>2025-01-24 10:19:27 +0100
committerDudemanguy <random342@airmail.cc>2025-01-27 19:32:52 +0000
commit24db17d10f0be1ccd3c03ba4d06c304bc2541561 (patch)
treee9f5e2395d60f360a0d5c635040a36fd5f762b76
parent130128762bde05f1bbb5c497d6f3444b52aba9fd (diff)
downloadmpv-24db17d10f0be1ccd3c03ba4d06c304bc2541561.tar.bz2
mpv-24db17d10f0be1ccd3c03ba4d06c304bc2541561.tar.xz
loadfile: discard prefetched files if demuxer options changed
When using --prefetch-playlist, if demuxer options are changed in the time window between the start of prefetching and the playback of the next file, the old values are used. This includes setting demuxer options in legacy extension auto profiles. Fix this by setting a flag when demuxer options change and not using the prefetched data when that flag is true. UPDATE_DEMUXER is not added to demux.c's options because those already support updates while playing.
-rw-r--r--demux/cache.c1
-rw-r--r--demux/demux_lavf.c1
-rw-r--r--demux/demux_libarchive.c1
-rw-r--r--demux/demux_mkv.c1
-rw-r--r--demux/demux_playlist.c1
-rw-r--r--demux/demux_raw.c1
-rw-r--r--options/m_option.h3
-rw-r--r--options/options.c2
-rw-r--r--player/command.c3
-rw-r--r--player/core.h1
-rw-r--r--player/loadfile.c22
11 files changed, 28 insertions, 9 deletions
diff --git a/demux/cache.c b/demux/cache.c
index 01d94323fc..d89685d82b 100644
--- a/demux/cache.c
+++ b/demux/cache.c
@@ -50,6 +50,7 @@ const struct m_sub_options demux_cache_conf = {
.defaults = &(const struct demux_cache_opts){
.unlink_files = 2,
},
+ .change_flags = UPDATE_DEMUXER,
};
struct demux_cache {
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index 747fa1922d..30d55ca9d9 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -121,6 +121,7 @@ const struct m_sub_options demux_lavf_conf = {
.linearize_ts = -1,
.propagate_opts = true,
},
+ .change_flags = UPDATE_DEMUXER,
};
struct format_hack {
diff --git a/demux/demux_libarchive.c b/demux/demux_libarchive.c
index a85e40ff89..f08bfba0f4 100644
--- a/demux/demux_libarchive.c
+++ b/demux/demux_libarchive.c
@@ -116,5 +116,6 @@ const struct demuxer_desc demuxer_desc_libarchive = {
{0}
},
.size = sizeof(OPT_BASE_STRUCT),
+ .change_flags = UPDATE_DEMUXER,
},
};
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index 4a834db5cb..adde357d79 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -257,6 +257,7 @@ const struct m_sub_options demux_mkv_conf = {
.subtitle_preroll_secs_index = 10.0,
.probe_start_time = true,
},
+ .change_flags = UPDATE_DEMUXER,
};
#define REALHEADER_SIZE 16
diff --git a/demux/demux_playlist.c b/demux/demux_playlist.c
index d4ce089632..2221e7e86f 100644
--- a/demux/demux_playlist.c
+++ b/demux/demux_playlist.c
@@ -77,6 +77,7 @@ struct m_sub_options demux_playlist_conf = {
"video", "audio", "image", "archive", "playlist", NULL
},
},
+ .change_flags = UPDATE_DEMUXER,
};
static bool check_mimetype(struct stream *s, const char *const *list)
diff --git a/demux/demux_raw.c b/demux/demux_raw.c
index acb0251847..8a2786ca8e 100644
--- a/demux/demux_raw.c
+++ b/demux/demux_raw.c
@@ -85,6 +85,7 @@ const struct m_sub_options demux_rawaudio_conf = {
.samplerate = 44100,
.aformat = PCM(1, 0, 16, 0), // s16le
},
+ .change_flags = UPDATE_DEMUXER,
};
#undef PCM
diff --git a/options/m_option.h b/options/m_option.h
index d3f542c4af..3eb28dde12 100644
--- a/options/m_option.h
+++ b/options/m_option.h
@@ -443,7 +443,8 @@ char *format_file_size(int64_t size);
#define UPDATE_VIDEO (1 << 15) // force redraw if needed
#define UPDATE_VO (1 << 16) // reinit the VO
#define UPDATE_CLIPBOARD (1 << 17) // reinit the clipboard
-#define UPDATE_OPT_LAST (1 << 17)
+#define UPDATE_DEMUXER (1 << 18) // invalidate --prefetch-playlist's data
+#define UPDATE_OPT_LAST (1 << 18)
// All bits between of UPDATE_ flags
#define UPDATE_OPTS_MASK ((UPDATE_OPT_LAST << 1) - 1)
diff --git a/options/options.c b/options/options.c
index f9159affd8..fdf7151685 100644
--- a/options/options.c
+++ b/options/options.c
@@ -627,7 +627,7 @@ static const m_option_t mp_opts[] = {
#endif
// demuxer.c - select audio/sub file/demuxer
- {"demuxer", OPT_STRING(demuxer_name), .help = demuxer_help},
+ {"demuxer", OPT_STRING(demuxer_name), .help = demuxer_help, .flags = UPDATE_DEMUXER},
{"audio-demuxer", OPT_STRING(audio_demuxer_name), .help = demuxer_help},
{"sub-demuxer", OPT_STRING(sub_demuxer_name), .help = demuxer_help},
{"demuxer-thread", OPT_BOOL(demuxer_thread)},
diff --git a/player/command.c b/player/command.c
index 4a3f10f7ce..6e0e1dc864 100644
--- a/player/command.c
+++ b/player/command.c
@@ -7741,6 +7741,9 @@ void mp_option_change_callback(void *ctx, struct m_config_option *co, int flags,
mpctx->stop_play = PT_CURRENT_ENTRY;
}
+ if (flags & UPDATE_DEMUXER)
+ mpctx->demuxer_changed = true;
+
if (opt_ptr == &opts->vo->android_surface_size) {
if (mpctx->video_out)
vo_control(mpctx->video_out, VOCTRL_EXTERNAL_RESIZE, NULL);
diff --git a/player/core.h b/player/core.h
index d1a1424e3b..560004c360 100644
--- a/player/core.h
+++ b/player/core.h
@@ -463,6 +463,7 @@ typedef struct MPContext {
char *open_format;
int open_url_flags;
bool open_for_prefetch;
+ bool demuxer_changed;
// --- All fields below are owned by open_thread, unless open_done was set
// to true.
struct demuxer *open_res_demuxer;
diff --git a/player/loadfile.c b/player/loadfile.c
index ea6fd5c558..253fdf889f 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -1180,6 +1180,7 @@ static void start_open(struct MPContext *mpctx, char *url, int url_flags,
mpctx->open_format = talloc_strdup(NULL, mpctx->opts->demuxer_name);
mpctx->open_url_flags = url_flags;
mpctx->open_for_prefetch = for_prefetch && mpctx->opts->demuxer_thread;
+ mpctx->demuxer_changed = false;
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
// Don't allow to open local paths or stdin during fuzzing
@@ -1210,16 +1211,23 @@ static void open_demux_reentrant(struct MPContext *mpctx)
bool failed = done && !mpctx->open_res_demuxer;
bool correct_url = strcmp(mpctx->open_url, url) == 0;
- if (correct_url && !failed) {
+ if (correct_url && !mpctx->demuxer_changed && !failed) {
MP_VERBOSE(mpctx, "Using prefetched/prefetching URL.\n");
- } else if (correct_url && failed) {
- MP_VERBOSE(mpctx, "Prefetched URL failed, retrying.\n");
- cancel_open(mpctx);
} else {
- if (done) {
- MP_VERBOSE(mpctx, "Dropping finished prefetch of wrong URL.\n");
+ if (correct_url && failed) {
+ MP_VERBOSE(mpctx, "Prefetched URL failed, retrying.\n");
+ } else if (mpctx->demuxer_changed) {
+ if (done) {
+ MP_VERBOSE(mpctx, "Dropping finished prefetch because demuxer options changed.\n");
+ } else {
+ MP_VERBOSE(mpctx, "Aborting ongoing prefetch because demuxer options changed.\n");
+ }
} else {
- MP_VERBOSE(mpctx, "Aborting ongoing prefetch of wrong URL.\n");
+ if (done) {
+ MP_VERBOSE(mpctx, "Dropping finished prefetch of wrong URL.\n");
+ } else {
+ MP_VERBOSE(mpctx, "Aborting ongoing prefetch of wrong URL.\n");
+ }
}
cancel_open(mpctx);
}