Skip to content

Commit

Permalink
loadfile: discard prefetched files if demuxer options changed
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
guidocella committed Dec 8, 2024
1 parent 8d20b72 commit ab8137f
Show file tree
Hide file tree
Showing 11 changed files with 22 additions and 7 deletions.
1 change: 1 addition & 0 deletions demux/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions demux/demux_lavf.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ const struct m_sub_options demux_lavf_conf = {
.linearize_ts = -1,
.propagate_opts = true,
},
.change_flags = UPDATE_DEMUXER,
};

struct format_hack {
Expand Down
1 change: 1 addition & 0 deletions demux/demux_libarchive.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,6 @@ const struct demuxer_desc demuxer_desc_libarchive = {
{0}
},
.size = sizeof(OPT_BASE_STRUCT),
.change_flags = UPDATE_DEMUXER,
},
};
1 change: 1 addition & 0 deletions demux/demux_mkv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions demux/demux_playlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ struct m_sub_options demux_playlist_conf = {
"video", "audio", "image", NULL
},
},
.change_flags = UPDATE_DEMUXER,
};

static bool check_mimetype(struct stream *s, const char *const *list)
Expand Down
1 change: 1 addition & 0 deletions demux/demux_raw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion options/m_option.h
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,8 @@ char *format_file_size(int64_t size);
#define UPDATE_VIDEO (1 << 24) // force redraw if needed
#define UPDATE_VO (1 << 25) // reinit the VO
#define UPDATE_CLIPBOARD (1 << 26) // reinit the clipboard
#define UPDATE_OPT_LAST (1 << 26)
#define UPDATE_DEMUXER (1 << 27) // invalidate prefetched files
#define UPDATE_OPT_LAST (1 << 27)

// All bits between _FIRST and _LAST (inclusive)
#define UPDATE_OPTS_MASK \
Expand Down
2 changes: 1 addition & 1 deletion options/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,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)},
Expand Down
3 changes: 3 additions & 0 deletions player/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -7808,6 +7808,9 @@ void mp_option_change_callback(void *ctx, struct m_config_option *co, int flags,
&& mpctx->vo_chain->is_sparse && !mpctx->ao_chain
&& mpctx->video_status == STATUS_DRAINING)
mpctx->time_frame = opts->image_display_duration;

if (flags & UPDATE_DEMUXER)
mpctx->demuxer_changed = true;
}

void mp_notify_property(struct MPContext *mpctx, const char *property)
Expand Down
1 change: 1 addition & 0 deletions player/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
14 changes: 9 additions & 5 deletions player/loadfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -1178,6 +1178,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
Expand Down Expand Up @@ -1208,13 +1209,16 @@ 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) {
if (correct_url && !mpctx->demuxer_changed && failed) {
MP_VERBOSE(mpctx, "Prefetched URL failed, retrying.\n");
} else if (mpctx->demuxer_changed && done) {
MP_VERBOSE(mpctx, "Dropping finished prefetch because demuxer options changed.\n");
} else if (mpctx->demuxer_changed) {
MP_VERBOSE(mpctx, "Aborting ongoing prefetch because demuxer options changed.\n");
} else if (done) {
MP_VERBOSE(mpctx, "Dropping finished prefetch of wrong URL.\n");
} else {
MP_VERBOSE(mpctx, "Aborting ongoing prefetch of wrong URL.\n");
Expand Down

0 comments on commit ab8137f

Please sign in to comment.