mirror of
https://github.com/mpv-player/mpv
synced 2024-11-03 03:19:24 +01:00
options: don't let watch_later etc. overwite command line options
There are certain cases where mpv will automatically set options, such as per-file configs, per protocol/VO/AO/extension profiles, and watch_later resume configs. All these were overwriting the user's options, even when they were specified on command line. Add something that explicitly preserves command line options. This means you can now actually use the command line to override any options that the playback resume functionality backups and restores. It still happily overrides options set at runtime (e.g. changed via properties while playing a file; then playing the next file might override them again), but maybe that's not a problem with typical use.
This commit is contained in:
parent
d8896f0dba
commit
ecc0705f83
@ -495,6 +495,9 @@ static int m_config_parse_option(struct m_config *config, struct bstr name,
|
||||
if ((flags & M_SETOPT_PRE_PARSE_ONLY) && !(co->opt->flags & M_OPT_PRE_PARSE))
|
||||
return 0;
|
||||
|
||||
if ((flags & M_SETOPT_PRESERVE_CMDLINE) && co->is_set_from_cmdline)
|
||||
set = false;
|
||||
|
||||
// Check if this option isn't forbidden in the current mode
|
||||
if ((flags & M_SETOPT_FROM_CONFIG_FILE) && (co->opt->flags & M_OPT_NOCFG)) {
|
||||
mp_tmsg(MSGT_CFGPARSER, MSGL_ERR,
|
||||
@ -530,7 +533,21 @@ static int m_config_parse_option(struct m_config *config, struct bstr name,
|
||||
return parse_subopts(config, (char *)co->name, prefix, param, flags);
|
||||
}
|
||||
|
||||
return m_option_parse(co->opt, name, param, set ? co->data : NULL);
|
||||
int r = m_option_parse(co->opt, name, param, set ? co->data : NULL);
|
||||
|
||||
if (r >= 0 && set && (flags & M_SETOPT_FROM_CMDLINE)) {
|
||||
co->is_set_from_cmdline = true;
|
||||
// Mark aliases too
|
||||
if (co->data) {
|
||||
for (int n = 0; n < config->num_opts; n++) {
|
||||
struct m_config_option *co2 = &config->opts[n];
|
||||
if (co2->data == co->data)
|
||||
co2->is_set_from_cmdline = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int parse_subopts(struct m_config *config, char *name, char *prefix,
|
||||
|
@ -36,14 +36,12 @@ struct m_obj_desc;
|
||||
|
||||
// Config option
|
||||
struct m_config_option {
|
||||
bool is_generated : 1;
|
||||
// Full name (ie option-subopt).
|
||||
const char *name;
|
||||
// Option description.
|
||||
const struct m_option *opt;
|
||||
// Raw value of the option.
|
||||
void *data;
|
||||
const void *default_data;
|
||||
bool is_generated : 1; // Automatically added ("no-" options)
|
||||
bool is_set_from_cmdline : 1; // Set by user from command line
|
||||
const char *name; // Full name (ie option-subopt)
|
||||
const struct m_option *opt; // Option description
|
||||
void *data; // Raw value of the option
|
||||
const void *default_data; // Raw default value
|
||||
};
|
||||
|
||||
// Config object
|
||||
@ -108,7 +106,9 @@ enum {
|
||||
M_SETOPT_PRE_PARSE_ONLY = 1, // Silently ignore non-M_OPT_PRE_PARSE opt.
|
||||
M_SETOPT_CHECK_ONLY = 2, // Don't set, just check name/value
|
||||
M_SETOPT_FROM_CONFIG_FILE = 4, // Reject M_OPT_NOCFG opt. (print error)
|
||||
M_SETOPT_BACKUP = 8, // Call m_config_backup_opt() before
|
||||
M_SETOPT_FROM_CMDLINE = 8, // Mark as set by command line
|
||||
M_SETOPT_BACKUP = 16, // Call m_config_backup_opt() before
|
||||
M_SETOPT_PRESERVE_CMDLINE = 32, // Don't set if already marked as FROM_CMDLINE
|
||||
};
|
||||
|
||||
// Set the named option to the given string.
|
||||
|
@ -669,6 +669,10 @@ static bool parse_cfgfiles(struct MPContext *mpctx, m_config_t *conf)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Set options file-local, and don't set them if the user set them via the
|
||||
// command line.
|
||||
#define FILE_LOCAL_FLAGS (M_SETOPT_BACKUP | M_SETOPT_PRESERVE_CMDLINE)
|
||||
|
||||
#define PROFILE_CFG_PROTOCOL "protocol."
|
||||
|
||||
static void load_per_protocol_config(m_config_t *conf, const char * const file)
|
||||
@ -690,7 +694,7 @@ static void load_per_protocol_config(m_config_t *conf, const char * const file)
|
||||
if (p) {
|
||||
mp_tmsg(MSGT_CPLAYER, MSGL_INFO,
|
||||
"Loading protocol-related profile '%s'\n", protocol);
|
||||
m_config_set_profile(conf, p, M_SETOPT_BACKUP);
|
||||
m_config_set_profile(conf, p, FILE_LOCAL_FLAGS);
|
||||
}
|
||||
}
|
||||
|
||||
@ -713,7 +717,7 @@ static void load_per_extension_config(m_config_t *conf, const char * const file)
|
||||
if (p) {
|
||||
mp_tmsg(MSGT_CPLAYER, MSGL_INFO,
|
||||
"Loading extension-related profile '%s'\n", extension);
|
||||
m_config_set_profile(conf, p, M_SETOPT_BACKUP);
|
||||
m_config_set_profile(conf, p, FILE_LOCAL_FLAGS);
|
||||
}
|
||||
}
|
||||
|
||||
@ -733,7 +737,7 @@ static void load_per_output_config(m_config_t *conf, char *cfg, char *out)
|
||||
if (p) {
|
||||
mp_tmsg(MSGT_CPLAYER, MSGL_INFO,
|
||||
"Loading extension-related profile '%s'\n", profile);
|
||||
m_config_set_profile(conf, p, M_SETOPT_BACKUP);
|
||||
m_config_set_profile(conf, p, FILE_LOCAL_FLAGS);
|
||||
}
|
||||
}
|
||||
|
||||
@ -741,12 +745,12 @@ static void load_per_output_config(m_config_t *conf, char *cfg, char *out)
|
||||
* Tries to load a config file (in file local mode)
|
||||
* @return 0 if file was not found, 1 otherwise
|
||||
*/
|
||||
static int try_load_config(m_config_t *conf, const char *file, bool local)
|
||||
static int try_load_config(m_config_t *conf, const char *file, int flags)
|
||||
{
|
||||
if (!mp_path_exists(file))
|
||||
return 0;
|
||||
mp_tmsg(MSGT_CPLAYER, MSGL_INFO, "Loading config '%s'\n", file);
|
||||
m_config_parse_config_file(conf, file, local ? M_SETOPT_BACKUP : 0);
|
||||
m_config_parse_config_file(conf, file, flags);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -769,14 +773,14 @@ static void load_per_file_config(m_config_t *conf, const char * const file,
|
||||
char dircfg[MP_PATH_MAX];
|
||||
strcpy(dircfg, cfg);
|
||||
strcpy(dircfg + (name - cfg), "mpv.conf");
|
||||
try_load_config(conf, dircfg, true);
|
||||
try_load_config(conf, dircfg, FILE_LOCAL_FLAGS);
|
||||
|
||||
if (try_load_config(conf, cfg, true))
|
||||
if (try_load_config(conf, cfg, FILE_LOCAL_FLAGS))
|
||||
return;
|
||||
}
|
||||
|
||||
if ((confpath = mp_find_user_config_file(name)) != NULL) {
|
||||
try_load_config(conf, confpath, true);
|
||||
try_load_config(conf, confpath, FILE_LOCAL_FLAGS);
|
||||
|
||||
talloc_free(confpath);
|
||||
}
|
||||
@ -922,7 +926,7 @@ static void load_playback_resume(m_config_t *conf, const char *file)
|
||||
m_config_backup_opt(conf, "start");
|
||||
mp_msg(MSGT_CPLAYER, MSGL_INFO, "Resuming playback. This behavior can "
|
||||
"be disabled with --no-resume-playback.\n");
|
||||
try_load_config(conf, fname, false);
|
||||
try_load_config(conf, fname, M_SETOPT_PRESERVE_CMDLINE);
|
||||
unlink(fname);
|
||||
}
|
||||
talloc_free(fname);
|
||||
|
@ -129,9 +129,10 @@ int m_config_parse_mp_command_line(m_config_t *config, struct playlist *files,
|
||||
struct parse_state p = {config, argc, argv};
|
||||
while (split_opt(&p)) {
|
||||
if (p.is_opt) {
|
||||
int flags = mode == LOCAL ? M_SETOPT_BACKUP | M_SETOPT_CHECK_ONLY : 0;
|
||||
int r;
|
||||
r = m_config_set_option_ext(config, p.arg, p.param, flags);
|
||||
int flags = M_SETOPT_FROM_CMDLINE;
|
||||
if (mode == LOCAL)
|
||||
flags |= M_SETOPT_BACKUP | M_SETOPT_CHECK_ONLY;
|
||||
int r = m_config_set_option_ext(config, p.arg, p.param, flags);
|
||||
if (r <= M_OPT_EXIT) {
|
||||
ret = r;
|
||||
goto err_out;
|
||||
@ -282,8 +283,8 @@ void m_config_preparse_command_line(m_config_t *config, int argc, char **argv)
|
||||
if (p.is_opt) {
|
||||
// Ignore non-pre-parse options. They will be set later.
|
||||
// Option parsing errors will be handled later as well.
|
||||
m_config_set_option_ext(config, p.arg, p.param,
|
||||
M_SETOPT_PRE_PARSE_ONLY);
|
||||
int flags = M_SETOPT_FROM_CMDLINE | M_SETOPT_PRE_PARSE_ONLY;
|
||||
m_config_set_option_ext(config, p.arg, p.param, flags);
|
||||
if (bstrcmp0(p.arg, "v") == 0)
|
||||
verbose++;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user