mirror of
https://github.com/mpv-player/mpv
synced 2024-12-26 09:02:38 +00:00
options: add some features to video filter parser
This is in preparation of making VOs and AOs use the parser which originally was for video filters only. The --vo and --ao options have several very annoying features, which are added here: - They can skip unknown video outputs (might be useful if a config file is supposed to work on several systems, where not all VOs/AOs are available everywhere) - The trailing "," in "-vo a,b," was significant, and meant that if "a" and "b" don't work, try the normal autoprobe order as fallback - There were deprecated VO names (like "gl3" and "gl"), which have to be handled with the option parser - Separating VO/VF names and options is different ("-vf foo=opts" vs. "-vo foo:opts") - vo_opengl.c provides opengl-hq as opengl + preset options
This commit is contained in:
parent
f2e3a49810
commit
999dad454f
@ -1790,6 +1790,27 @@ bool m_obj_list_find(struct m_obj_desc *dst, const struct m_obj_list *l,
|
||||
if (bstr_equals0(name, dst->name))
|
||||
return true;
|
||||
}
|
||||
if (l->aliases) {
|
||||
for (int i = 0; l->aliases[i][0]; i++) {
|
||||
const char *aname = l->aliases[i][0];
|
||||
const char *alias = l->aliases[i][1];
|
||||
const char *opts = l->aliases[i][2];
|
||||
if (bstr_equals0(name, aname) &&
|
||||
m_obj_list_find(dst, l, bstr0(alias)))
|
||||
{
|
||||
if (opts) {
|
||||
dst->init_options = opts;
|
||||
} else {
|
||||
// Assume it's deprecated in this case.
|
||||
// Also, it's used by the VO code only, so whatever.
|
||||
mp_msg(MSGT_CFGPARSER, MSGL_WARN,
|
||||
"VO driver '%s' has been replaced with '%s'!\n",
|
||||
aname, alias);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1947,6 +1968,9 @@ static int get_obj_param(bstr opt_name, bstr obj_name, struct m_config *config,
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!config)
|
||||
return 0; // skip
|
||||
|
||||
// va.start != NULL => of the form name=val (not positional)
|
||||
// If it's just "name", and the associated option exists and is a flag,
|
||||
// don't accept it as positional argument.
|
||||
@ -2010,6 +2034,12 @@ static int get_obj_params(struct bstr opt_name, struct bstr name,
|
||||
int num_args = 0;
|
||||
int r = 1;
|
||||
|
||||
if (ret) {
|
||||
args = *ret;
|
||||
while (args && args[num_args])
|
||||
num_args++;
|
||||
}
|
||||
|
||||
struct m_config *config = m_config_from_obj_desc(NULL, desc);
|
||||
|
||||
while (pstr->len > 0) {
|
||||
@ -2048,7 +2078,12 @@ static int get_obj_params(struct bstr opt_name, struct bstr name,
|
||||
goto exit;
|
||||
|
||||
print_help: ;
|
||||
m_config_print_option_list(config);
|
||||
if (config) {
|
||||
m_config_print_option_list(config);
|
||||
} else {
|
||||
mp_msg(MSGT_CFGPARSER, MSGL_WARN, "Option %.*s doesn't exist.\n",
|
||||
BSTR_P(opt_name));
|
||||
}
|
||||
r = M_OPT_EXIT - 1;
|
||||
|
||||
exit:
|
||||
@ -2082,13 +2117,26 @@ static int parse_obj_settings(struct bstr opt, struct bstr *pstr,
|
||||
int idx = bstrspn(*pstr, NAMECH);
|
||||
bstr str = bstr_splice(*pstr, 0, idx);
|
||||
*pstr = bstr_cut(*pstr, idx);
|
||||
if (bstr_eatstart0(pstr, "="))
|
||||
// video filters use "=", VOs use ":"
|
||||
if (bstr_eatstart0(pstr, "=") || bstr_eatstart0(pstr, ":"))
|
||||
has_param = true;
|
||||
|
||||
if (!m_obj_list_find(&desc, list, str)) {
|
||||
mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %.*s: %.*s doesn't exist.\n",
|
||||
BSTR_P(opt), BSTR_P(str));
|
||||
return M_OPT_INVALID;
|
||||
if (!list->allow_unknown_entries) {
|
||||
mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %.*s: %.*s doesn't exist.\n",
|
||||
BSTR_P(opt), BSTR_P(str));
|
||||
return M_OPT_INVALID;
|
||||
}
|
||||
desc = (struct m_obj_desc){0};
|
||||
}
|
||||
|
||||
if (desc.init_options && desc.options && _ret) {
|
||||
bstr s = bstr0(desc.init_options);
|
||||
r = get_obj_params(opt, str, &s, &desc, &plist);
|
||||
if (r < 0 || s.len > 0) {
|
||||
mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Internal error: preset broken\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_param) {
|
||||
@ -2099,7 +2147,7 @@ static int parse_obj_settings(struct bstr opt, struct bstr *pstr,
|
||||
bstr param = bstr_splice(*pstr, 0, next);
|
||||
*pstr = bstr_cut(*pstr, next);
|
||||
if (!bstrcmp0(param, "help")) {
|
||||
mp_msg(MSGT_CFGPARSER, MSGL_INFO,
|
||||
mp_msg(MSGT_CFGPARSER, MSGL_WARN,
|
||||
"Option %.*s: %.*s has no option description.\n",
|
||||
BSTR_P(opt), BSTR_P(str));
|
||||
return M_OPT_EXIT - 1;
|
||||
@ -2262,9 +2310,21 @@ static int parse_obj_settings_list(const m_option_t *opt, struct bstr name,
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
const char sep[2] = {OPTION_LIST_SEPARATOR, 0};
|
||||
if (param.len > 0 && !bstr_eatstart0(¶m, sep))
|
||||
return M_OPT_INVALID;
|
||||
if (param.len > 0) {
|
||||
const char sep[2] = {OPTION_LIST_SEPARATOR, 0};
|
||||
if (!bstr_eatstart0(¶m, sep))
|
||||
return M_OPT_INVALID;
|
||||
if (param.len == 0) {
|
||||
if (!ol->allow_trailer)
|
||||
return M_OPT_INVALID;
|
||||
if (dst) {
|
||||
m_obj_settings_t item = {
|
||||
.name = talloc_strdup(NULL, ""),
|
||||
};
|
||||
obj_settings_list_insert_at(&res, -1, &item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dst) {
|
||||
|
@ -106,12 +106,23 @@ struct m_obj_desc {
|
||||
const struct m_option *options;
|
||||
// For free use by the implementer of m_obj_list.get_desc
|
||||
const void *p;
|
||||
// If not NULL, options which should be set before applying other options.
|
||||
// This member is usually set my m_obj_list_find() only.
|
||||
// Only works if options is not NULL.
|
||||
const char *init_options;
|
||||
};
|
||||
|
||||
// Extra definition needed for \ref m_option_type_obj_settings_list options.
|
||||
struct m_obj_list {
|
||||
bool (*get_desc)(struct m_obj_desc *dst, int index);
|
||||
const char *description;
|
||||
// Can be set to a NULL terminated array of aliases
|
||||
const char *aliases[4][5];
|
||||
// Allow a trailing ",", which adds an entry with name=""
|
||||
bool allow_trailer;
|
||||
// Allow unknown entries, for which a dummy entry is inserted, and whose
|
||||
// options are skipped and ignored.
|
||||
bool allow_unknown_entries;
|
||||
};
|
||||
|
||||
// Find entry by name
|
||||
|
Loading…
Reference in New Issue
Block a user