mirror of
https://github.com/mpv-player/mpv
synced 2024-09-28 17:52:52 +02:00
options: pre-check filter names when using vf/af libavfilter bridge
Until now, using a filter not in mpv's builtin filter list would assume it's a libavfilter filter. If it wasn't, the option value was still accepted, but creating the filter simply failed. But since this happens after option parsing, so the result is confusing. Improve this slightly by checking filter names. This will reject truly unknown filters at option parsing time. Unfortunately, this still does not check filter arguments. This would be much more complex, because you'd have to create a dummy filter graph and allocate the filter. Maybe another time.
This commit is contained in:
parent
13afc2150b
commit
37ac43847e
@ -941,6 +941,12 @@ static bool is_usable(const AVFilter *filter, int media_type)
|
|||||||
is_single_media_only(filter->outputs, media_type);
|
is_single_media_only(filter->outputs, media_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool mp_lavfi_is_usable(const char *name, int media_type)
|
||||||
|
{
|
||||||
|
const AVFilter *f = avfilter_get_by_name(name);
|
||||||
|
return f && is_usable(f, media_type);
|
||||||
|
}
|
||||||
|
|
||||||
static void dump_list(struct mp_log *log, int media_type)
|
static void dump_list(struct mp_log *log, int media_type)
|
||||||
{
|
{
|
||||||
mp_info(log, "Available libavfilter filters:\n");
|
mp_info(log, "Available libavfilter filters:\n");
|
||||||
|
@ -34,3 +34,6 @@ void print_lavfi_help_list(struct mp_log *log, int media_type);
|
|||||||
|
|
||||||
// Print libavfilter help for the given filter
|
// Print libavfilter help for the given filter
|
||||||
void print_lavfi_help(struct mp_log *log, const char *name, int media_type);
|
void print_lavfi_help(struct mp_log *log, const char *name, int media_type);
|
||||||
|
|
||||||
|
// Return whether the given filter exists and has the required media_type in/outs.
|
||||||
|
bool mp_lavfi_is_usable(const char *name, int media_type);
|
||||||
|
@ -48,11 +48,17 @@ static void print_af_lavfi_help(struct mp_log *log, const char *name)
|
|||||||
print_lavfi_help(log, name, AVMEDIA_TYPE_AUDIO);
|
print_lavfi_help(log, name, AVMEDIA_TYPE_AUDIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool check_af_lavfi(const char *name)
|
||||||
|
{
|
||||||
|
return mp_lavfi_is_usable(name, AVMEDIA_TYPE_AUDIO);
|
||||||
|
}
|
||||||
|
|
||||||
const struct m_obj_list af_obj_list = {
|
const struct m_obj_list af_obj_list = {
|
||||||
.get_desc = get_af_desc,
|
.get_desc = get_af_desc,
|
||||||
.description = "audio filters",
|
.description = "audio filters",
|
||||||
.allow_disable_entries = true,
|
.allow_disable_entries = true,
|
||||||
.allow_unknown_entries = true,
|
.allow_unknown_entries = true,
|
||||||
|
.check_unknown_entry = check_af_lavfi,
|
||||||
.print_help_list = print_af_help_list,
|
.print_help_list = print_af_help_list,
|
||||||
.print_unknown_entry_help = print_af_lavfi_help,
|
.print_unknown_entry_help = print_af_lavfi_help,
|
||||||
};
|
};
|
||||||
@ -96,11 +102,17 @@ static void print_vf_lavfi_help(struct mp_log *log, const char *name)
|
|||||||
print_lavfi_help(log, name, AVMEDIA_TYPE_VIDEO);
|
print_lavfi_help(log, name, AVMEDIA_TYPE_VIDEO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool check_vf_lavfi(const char *name)
|
||||||
|
{
|
||||||
|
return mp_lavfi_is_usable(name, AVMEDIA_TYPE_VIDEO);
|
||||||
|
}
|
||||||
|
|
||||||
const struct m_obj_list vf_obj_list = {
|
const struct m_obj_list vf_obj_list = {
|
||||||
.get_desc = get_vf_desc,
|
.get_desc = get_vf_desc,
|
||||||
.description = "video filters",
|
.description = "video filters",
|
||||||
.allow_disable_entries = true,
|
.allow_disable_entries = true,
|
||||||
.allow_unknown_entries = true,
|
.allow_unknown_entries = true,
|
||||||
|
.check_unknown_entry = check_vf_lavfi,
|
||||||
.print_help_list = print_vf_help_list,
|
.print_help_list = print_vf_help_list,
|
||||||
.print_unknown_entry_help = print_vf_lavfi_help,
|
.print_unknown_entry_help = print_vf_lavfi_help,
|
||||||
};
|
};
|
||||||
|
@ -3021,7 +3021,11 @@ static int parse_obj_settings(struct mp_log *log, struct bstr opt, int op,
|
|||||||
mp_warn(log, "Driver '%s' has been replaced with '%s'!\n",
|
mp_warn(log, "Driver '%s' has been replaced with '%s'!\n",
|
||||||
desc.replaced_name, desc.name);
|
desc.replaced_name, desc.name);
|
||||||
} else {
|
} else {
|
||||||
if (!list->allow_unknown_entries) {
|
char name[80];
|
||||||
|
snprintf(name, sizeof(name), "%.*s", BSTR_P(str));
|
||||||
|
if (!list->allow_unknown_entries ||
|
||||||
|
(list->check_unknown_entry && !list->check_unknown_entry(name)))
|
||||||
|
{
|
||||||
mp_err(log, "Option %.*s: %.*s doesn't exist.\n",
|
mp_err(log, "Option %.*s: %.*s doesn't exist.\n",
|
||||||
BSTR_P(opt), BSTR_P(str));
|
BSTR_P(opt), BSTR_P(str));
|
||||||
return M_OPT_INVALID;
|
return M_OPT_INVALID;
|
||||||
|
@ -149,6 +149,9 @@ struct m_obj_list {
|
|||||||
// Allow unknown entries, for which a dummy entry is inserted, and whose
|
// Allow unknown entries, for which a dummy entry is inserted, and whose
|
||||||
// options are skipped and ignored.
|
// options are skipped and ignored.
|
||||||
bool allow_unknown_entries;
|
bool allow_unknown_entries;
|
||||||
|
// Callback to test whether an unknown entry should be allowed. (This can
|
||||||
|
// be useful if adding them as explicit entries is too much work.)
|
||||||
|
bool (*check_unknown_entry)(const char *name);
|
||||||
// Allow syntax for disabling entries.
|
// Allow syntax for disabling entries.
|
||||||
bool allow_disable_entries;
|
bool allow_disable_entries;
|
||||||
// This helps with confusing error messages if unknown flag options are used.
|
// This helps with confusing error messages if unknown flag options are used.
|
||||||
|
Loading…
Reference in New Issue
Block a user