Skip to content

Commit

Permalink
options: don't make options set during playback file local (e.g. --vf)
Browse files Browse the repository at this point in the history
Refactor file local options handling: instead of making all options
implicitly file local between loading a file and terminating playback,
explicitly make options file local which are required to be file local.

Or in other words, introduce a M_SETOPT_BACKUP flag, which forces file
local-ness when setting an option, and use this for file local command
line options, per-file config files, and per-protocol/extension/vo/ao
profiles.

In particular, this changes the "vf" input command such that video
filters stay permanent even when going to the next file in the playlist.
The underlying reason for this is that the "vf" command uses the option
setting command. This influences the "af" command as well.
  • Loading branch information
wm4 committed Aug 2, 2013
1 parent 878a94d commit d1c563c
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 81 deletions.
61 changes: 24 additions & 37 deletions core/m_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,21 @@ struct m_opt_backup {
void *backup;
};

static int parse_include(struct m_config *config, struct bstr param, bool set)
static int parse_include(struct m_config *config, struct bstr param, bool set,
int flags)
{
if (param.len == 0)
return M_OPT_MISSING_PARAM;
if (!set)
return 1;
char *filename = bstrdup0(NULL, param);
config->includefunc(config, filename);
config->includefunc(config, filename, flags);
talloc_free(filename);
return 1;
}

static int parse_profile(struct m_config *config, const struct m_option *opt,
struct bstr name, struct bstr param, bool set)
struct bstr name, struct bstr param, bool set, int flags)
{
if (!bstrcmp0(param, "help")) {
struct m_profile *p;
Expand Down Expand Up @@ -97,7 +98,7 @@ static int parse_profile(struct m_config *config, const struct m_option *opt,
list[i]);
r = M_OPT_INVALID;
} else if (set)
m_config_set_profile(config, p);
m_config_set_profile(config, p, flags);
}
m_option_free(opt, &list);
return r;
Expand Down Expand Up @@ -182,8 +183,7 @@ static void add_options(struct m_config *config,
static int config_destroy(void *p)
{
struct m_config *config = p;
if (config->file_local_mode)
m_config_leave_file_local(config);
m_config_restore_backups(config);
for (struct m_config_option *copt = config->opts; copt; copt = copt->next)
m_option_free(copt->opt, copt->data);
return 0;
Expand Down Expand Up @@ -257,8 +257,6 @@ int m_config_initialize_obj(struct m_config *config, struct m_obj_desc *desc,

static void ensure_backup(struct m_config *config, struct m_config_option *co)
{
if (!config->file_local_mode)
return;
if (co->opt->type->flags & M_OPT_TYPE_HAS_CHILD)
return;
if (co->opt->flags & M_OPT_GLOBAL)
Expand All @@ -279,20 +277,8 @@ static void ensure_backup(struct m_config *config, struct m_config_option *co)
config->backup_opts = bc;
}

void m_config_enter_file_local(struct m_config *config)
{
assert(!config->file_local_mode);
config->file_local_mode = true;
for (struct m_config_option *co = config->opts; co; co = co->next) {
if (co->opt->flags & M_OPT_LOCAL)
ensure_backup(config, co);
}
}

void m_config_leave_file_local(struct m_config *config)
void m_config_restore_backups(struct m_config *config)
{
assert(config->file_local_mode);
config->file_local_mode = false;
while (config->backup_opts) {
struct m_opt_backup *bc = config->backup_opts;
config->backup_opts = bc->next;
Expand All @@ -303,7 +289,7 @@ void m_config_leave_file_local(struct m_config *config)
}
}

void m_config_mark_file_local(struct m_config *config, const char *opt)
void m_config_backup_opt(struct m_config *config, const char *opt)
{
struct m_config_option *co = m_config_get_co(config, bstr0(opt));
if (co) {
Expand All @@ -313,7 +299,7 @@ void m_config_mark_file_local(struct m_config *config, const char *opt)
}
}

void m_config_mark_all_file_local(struct m_config *config)
void m_config_backup_all_opts(struct m_config *config)
{
for (struct m_config_option *co = config->opts; co; co = co->next)
ensure_backup(config, co);
Expand Down Expand Up @@ -346,8 +332,7 @@ static void add_negation_option(struct m_config *config,
*no_opt = (struct m_option) {
.name = talloc_asprintf(no_opt, "no-%s", opt->name),
.type = CONF_TYPE_STORE,
.flags = opt->flags & (M_OPT_NOCFG | M_OPT_GLOBAL | M_OPT_LOCAL |
M_OPT_PRE_PARSE),
.flags = opt->flags & (M_OPT_NOCFG | M_OPT_GLOBAL | M_OPT_PRE_PARSE),
.new = opt->new,
.p = opt->p,
.offset = opt->offset,
Expand Down Expand Up @@ -527,17 +512,21 @@ static int m_config_parse_option(struct m_config *config, struct bstr name,
BSTR_P(name));
return M_OPT_INVALID;
}
if (config->file_local_mode && (co->opt->flags & M_OPT_GLOBAL)) {
mp_tmsg(MSGT_CFGPARSER, MSGL_ERR,
"The %.*s option is global and can't be set per-file.\n",
BSTR_P(name));
return M_OPT_INVALID;
if (flags & M_SETOPT_BACKUP) {
if (co->opt->flags & M_OPT_GLOBAL) {
mp_tmsg(MSGT_CFGPARSER, MSGL_ERR,
"The %.*s option is global and can't be set per-file.\n",
BSTR_P(name));
return M_OPT_INVALID;
}
if (set)
ensure_backup(config, co);
}

if (config->includefunc && bstr_equals0(name, "include"))
return parse_include(config, param, set);
return parse_include(config, param, set, flags);
if (config->use_profiles && bstr_equals0(name, "profile"))
return parse_profile(config, co->opt, name, param, set);
return parse_profile(config, co->opt, name, param, set, flags);
if (config->use_profiles && bstr_equals0(name, "show-profile"))
return show_profile(config, param);
if (bstr_equals0(name, "list-options"))
Expand All @@ -551,9 +540,6 @@ static int m_config_parse_option(struct m_config *config, struct bstr name,
return parse_subopts(config, co->name, prefix, param, flags);
}

if (set)
ensure_backup(config, co);

return m_option_parse(co->opt, name, param, set ? co->data : NULL);
}

Expand Down Expand Up @@ -763,7 +749,8 @@ int m_config_set_profile_option(struct m_config *config, struct m_profile *p,
return 1;
}

void m_config_set_profile(struct m_config *config, struct m_profile *p)
void m_config_set_profile(struct m_config *config, struct m_profile *p,
int flags)
{
if (config->profile_depth > MAX_PROFILE_DEPTH) {
mp_tmsg(MSGT_CFGPARSER, MSGL_WARN,
Expand All @@ -775,7 +762,7 @@ void m_config_set_profile(struct m_config *config, struct m_profile *p)
m_config_set_option_ext(config,
bstr0(p->opts[2 * i]),
bstr0(p->opts[2 * i + 1]),
M_SETOPT_FROM_CONFIG_FILE);
flags | M_SETOPT_FROM_CONFIG_FILE);
}
config->profile_depth--;
}
Expand Down
26 changes: 15 additions & 11 deletions core/m_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,6 @@ typedef struct m_config {
// Registered options.
struct m_config_option *opts; // all options, even suboptions

// When options are set (via m_config_set_option or m_config_set_profile),
// back up the old value (unless it's already backed up). Used for restoring
// global options when per-file options are set.
bool file_local_mode;

// List of defined profiles.
struct m_profile *profiles;
// Depth when recursively including profiles.
Expand All @@ -67,7 +62,7 @@ typedef struct m_config {
struct m_opt_backup *backup_opts;

bool use_profiles;
int (*includefunc)(struct m_config *conf, char *filename);
int (*includefunc)(struct m_config *conf, char *filename, int flags);

const void *optstruct_defaults;
size_t optstruct_size;
Expand Down Expand Up @@ -101,15 +96,22 @@ int m_config_set_obj_params(struct m_config *conf, char **args);
int m_config_initialize_obj(struct m_config *config, struct m_obj_desc *desc,
void **ppriv, char ***pargs);

void m_config_enter_file_local(struct m_config *config);
void m_config_leave_file_local(struct m_config *config);
void m_config_mark_file_local(struct m_config *config, const char *opt);
void m_config_mark_all_file_local(struct m_config *config);
// Make sure the option is backed up. If it's already backed up, do nothing.
// All backed up options can be restored with m_config_restore_backups().
void m_config_backup_opt(struct m_config *config, const char *opt);

// Call m_config_backup_opt() on all options.
void m_config_backup_all_opts(struct m_config *config);

// Restore all options backed up with m_config_backup_opt(), and delete the
// backups afterwards.
void m_config_restore_backups(struct m_config *config);

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
};

// Set the named option to the given string.
Expand Down Expand Up @@ -204,8 +206,10 @@ int m_config_set_profile_option(struct m_config *config, struct m_profile *p,
*
* \param config The config object.
* \param p The profile object.
* \param flags M_SETOPT_* bits
*/
void m_config_set_profile(struct m_config *config, struct m_profile *p);
void m_config_set_profile(struct m_config *config, struct m_profile *p,
int flags);

void *m_config_alloc_struct(void *talloc_parent,
const struct m_sub_options *subopts);
Expand Down
5 changes: 0 additions & 5 deletions core/m_option.h
Original file line number Diff line number Diff line change
Expand Up @@ -337,11 +337,6 @@ struct m_option {
// This option can't be set per-file when used with struct m_config.
#define M_OPT_GLOBAL (1 << 4)

// This option is always considered per-file when used with struct m_config.
// When playback of a file ends, the option value will be restored to the value
// from before playback begin.
#define M_OPT_LOCAL (1 << 5)

// The option should be set during command line pre-parsing
#define M_OPT_PRE_PARSE (1 << 6)

Expand Down
32 changes: 16 additions & 16 deletions core/mplayer.c
Original file line number Diff line number Diff line change
Expand Up @@ -634,9 +634,9 @@ static void mk_config_dir(char *subdir)
talloc_free(tmp);
}

static int cfg_include(struct m_config *conf, char *filename)
static int cfg_include(struct m_config *conf, char *filename, int flags)
{
return m_config_parse_config_file(conf, filename);
return m_config_parse_config_file(conf, filename, flags);
}

#define DEF_CONFIG "# Write your default config options here!\n\n\n"
Expand All @@ -648,7 +648,7 @@ static bool parse_cfgfiles(struct MPContext *mpctx, m_config_t *conf)
int conffile_fd;
if (!opts->load_config)
return true;
if (!m_config_parse_config_file(conf, MPLAYER_CONFDIR "/mpv.conf") < 0)
if (!m_config_parse_config_file(conf, MPLAYER_CONFDIR "/mpv.conf", 0) < 0)
return false;
mk_config_dir(NULL);
if ((conffile = mp_find_user_config_file("config")) == NULL)
Expand All @@ -662,7 +662,7 @@ static bool parse_cfgfiles(struct MPContext *mpctx, m_config_t *conf)
write(conffile_fd, DEF_CONFIG, sizeof(DEF_CONFIG) - 1);
close(conffile_fd);
}
if (m_config_parse_config_file(conf, conffile) < 0)
if (m_config_parse_config_file(conf, conffile, 0) < 0)
return false;
talloc_free(conffile);
}
Expand All @@ -688,7 +688,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_config_set_profile(conf, p, M_SETOPT_BACKUP);
}
}

Expand All @@ -711,7 +711,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_config_set_profile(conf, p, M_SETOPT_BACKUP);
}
}

Expand All @@ -731,20 +731,20 @@ 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_config_set_profile(conf, p, M_SETOPT_BACKUP);
}
}

/**
* Tries to load a config file
* 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)
{
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);
m_config_parse_config_file(conf, file, M_SETOPT_BACKUP);
return 1;
}

Expand Down Expand Up @@ -899,8 +899,10 @@ static void load_per_file_options(m_config_t *conf,
struct playlist_param *params,
int params_count)
{
for (int n = 0; n < params_count; n++)
m_config_set_option(conf, params[n].name, params[n].value);
for (int n = 0; n < params_count; n++) {
m_config_set_option_ext(conf, params[n].name, params[n].value,
M_SETOPT_BACKUP);
}
}

/* When demux performs a blocking operation (network connection or
Expand Down Expand Up @@ -4147,8 +4149,6 @@ static void play_current_file(struct MPContext *mpctx)

mpctx->add_osd_seek_info &= OSD_SEEK_INFO_EDITION;

m_config_enter_file_local(mpctx->mconfig);

load_per_protocol_config(mpctx->mconfig, mpctx->filename);
load_per_extension_config(mpctx->mconfig, mpctx->filename);
load_per_file_config(mpctx->mconfig, mpctx->filename, opts->use_filedir_conf);
Expand All @@ -4170,9 +4170,9 @@ static void play_current_file(struct MPContext *mpctx)
for (int n = 0; opts->reset_options[n]; n++) {
const char *opt = opts->reset_options[n];
if (strcmp(opt, "all") == 0) {
m_config_mark_all_file_local(mpctx->mconfig);
m_config_backup_all_opts(mpctx->mconfig);
} else {
m_config_mark_file_local(mpctx->mconfig, opt);
m_config_backup_opt(mpctx->mconfig, opt);
}
}
}
Expand Down Expand Up @@ -4445,7 +4445,7 @@ goto_reopen_demuxer: ;
uninit_player(mpctx, uninitialize_parts);

// xxx handle this as INITIALIZED_CONFIG?
m_config_leave_file_local(mpctx->mconfig);
m_config_restore_backups(mpctx->mconfig);

mpctx->filename = NULL;
talloc_free(mpctx->resolve_result);
Expand Down
9 changes: 6 additions & 3 deletions core/parser-cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ static int recursion_depth = 0;
/// Setup the \ref Config from a config file.
/** \param config The config object.
* \param conffile Path to the config file.
* \param flags M_SETOPT_* bits
* \return 1 on sucess, -1 on error, 0 if file not accessible.
*/
int m_config_parse_config_file(m_config_t *config, const char *conffile)
int m_config_parse_config_file(m_config_t *config, const char *conffile,
int flags)
{
#define PRINT_LINENUM mp_msg(MSGT_CFGPARSER, MSGL_ERR, "%s:%d: ", conffile, line_num)
#define MAX_LINE_LEN 10000
Expand All @@ -63,6 +65,8 @@ int m_config_parse_config_file(m_config_t *config, const char *conffile)
int errors = 0;
m_profile_t *profile = NULL;

flags = flags | M_SETOPT_FROM_CONFIG_FILE;

mp_msg(MSGT_CFGPARSER, MSGL_V, "Reading config file %s", conffile);

if (recursion_depth > MAX_RECURSION_DEPTH) {
Expand Down Expand Up @@ -219,8 +223,7 @@ int m_config_parse_config_file(m_config_t *config, const char *conffile)
if (profile) {
tmp = m_config_set_profile_option(config, profile, bopt, bparam);
} else {
tmp = m_config_set_option_ext(config, bopt, bparam,
M_SETOPT_FROM_CONFIG_FILE);
tmp = m_config_set_option_ext(config, bopt, bparam, flags);
}
if (tmp < 0) {
PRINT_LINENUM;
Expand Down
3 changes: 2 additions & 1 deletion core/parser-cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include "m_config.h"

int m_config_parse_config_file(m_config_t* config, const char *conffile);
int m_config_parse_config_file(m_config_t* config, const char *conffile,
int flags);

#endif /* MPLAYER_PARSER_CFG_H */
Loading

0 comments on commit d1c563c

Please sign in to comment.