summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-03-25 17:07:40 +0100
committerwm4 <wm4@nowhere>2017-03-25 17:07:40 +0100
commit7d424b4ce45534ade52f38df68308498decc0171 (patch)
treef5ed0a3c98cab67ce50e76a0223031cb73eb39b8
parent29f9e44723104aac8ce91d0347a91fb206afba8d (diff)
downloadmpv-7d424b4ce45534ade52f38df68308498decc0171.tar.bz2
mpv-7d424b4ce45534ade52f38df68308498decc0171.tar.xz
command: add better runtime filter toggling method
Basically, see the example in input.rst. This is better than the "old" vf-toggle method, because it doesn't require the user to duplicate the filter string in mpv.conf and input.conf. Some aspects of this changes are untested, so enjoy your alpha testing.
-rw-r--r--DOCS/man/af.rst27
-rw-r--r--DOCS/man/input.rst13
-rw-r--r--DOCS/man/vf.rst32
-rw-r--r--audio/filter/af.c3
-rw-r--r--options/m_option.c45
-rw-r--r--options/m_option.h4
-rw-r--r--player/command.c5
-rw-r--r--video/filter/vf.c3
8 files changed, 100 insertions, 32 deletions
diff --git a/DOCS/man/af.rst b/DOCS/man/af.rst
index 040b44cd64..9dff18ebbe 100644
--- a/DOCS/man/af.rst
+++ b/DOCS/man/af.rst
@@ -4,8 +4,8 @@ AUDIO FILTERS
Audio filters allow you to modify the audio stream and its properties. The
syntax is:
-``--af=<filter1[=parameter1:parameter2:...],filter2,...>``
- Setup a chain of audio filters.
+``--af=...``
+ Setup a chain of audio filters. See ``--vf`` for the syntax.
.. note::
@@ -15,27 +15,8 @@ syntax is:
wrapper, which gives you access to most of libavfilter's filters. This
includes all filters that have been ported from MPlayer to libavfilter.
-You can also set defaults for each filter. The defaults are applied before the
-normal filter parameters.
-
-``--af-defaults=<filter1[=parameter1:parameter2:...],filter2,...>``
- Set defaults for each filter.
-
-Audio filters are managed in lists. There are a few commands to manage the
-filter list:
-
-``--af-add=<filter1[,filter2,...]>``
- Appends the filters given as arguments to the filter list.
-
-``--af-pre=<filter1[,filter2,...]>``
- Prepends the filters given as arguments to the filter list.
-
-``--af-del=<index1[,index2,...]>``
- Deletes the filters at the given indexes. Index numbers start at 0,
- negative numbers address the end of the list (-1 is the last).
-
-``--af-clr``
- Completely empties the filter list.
+See ``--vf`` group of options for info on how ``--af-defaults``, ``--af-add``,
+``--af-pre``, ``--af-del``, ``--af-clr``, and possibly others work.
Available filters are:
diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst
index 9e578867cf..d252bb93a1 100644
--- a/DOCS/man/input.rst
+++ b/DOCS/man/input.rst
@@ -452,6 +452,9 @@ Input Commands that are Possibly Subject to Change
(If several filters are passed to the command, this is done for
each filter.)
+ A special variant is combining this with labels, and using ``@name:!``
+ as filter entry. This toggles the enable/disable flag.
+
del
Remove the given filters from the video chain. Unlike in the other
cases, the second parameter is a comma separated list of filter names
@@ -487,6 +490,16 @@ Input Commands that are Possibly Subject to Change
- ``b vf set ""`` remove all video filters on ``b``
- ``c vf toggle lavfi=gradfun`` toggle debanding on ``c``
+ .. admonition:: Example how to toggle disabled filters at runtime
+
+ - Add something ``vf-add=@deband:!lavfi=[gradfun]`` to ``mpv.conf``. The
+ ``@deband:`` is the label, and ``deband`` is an arbitrary, user-given
+ name for this filter entry. The ``!`` before the filter name disables
+ the filter by default. Everything after this is the normal filter name
+ and the filter parameters.
+ - Add ``a vf toggle @deband:!`` to ``input.conf``. This toggles the
+ "disabled" flag for the filter identified with ``deband``.
+
``cycle-values ["!reverse"] <property> "<value1>" "<value2>" ...``
Cycle through a list of values. Each invocation of the command will set the
given property to the next value in the list. The command maintains an
diff --git a/DOCS/man/vf.rst b/DOCS/man/vf.rst
index 9da20942f6..a3f7ee6dab 100644
--- a/DOCS/man/vf.rst
+++ b/DOCS/man/vf.rst
@@ -5,7 +5,37 @@ Video filters allow you to modify the video stream and its properties. The
syntax is:
``--vf=<filter1[=parameter1:parameter2:...],filter2,...>``
- Setup a chain of video filters.
+ Setup a chain of video filters. This consists on the filter name, and an
+ option list of parameters after ``=``. The parameters are separated by
+ ``:`` (not ``,``, as that starts a new filter entry).
+
+ Before the filter name, a label can be specified with ``@name:``, where
+ name is an arbitrary user-given name, which identifies the filter. This
+ is only needed if you want to toggle the filter at runtime.
+
+ A ``!`` before the filter name means the filter is enabled by default. It
+ will be skipped on filter creation. This is also useful for runtime filter
+ toggling.
+
+ See the ``vf`` command (and ``toggle`` sub-command) for further explanations
+ and examples.
+
+ The general filter entry syntax is:
+
+ ``["@"<label-name>":"] ["!"] <filter-name> [ "=" <filter-parameter-list> ]``
+
+ and the ``filter-parameter-list``:
+
+ ``<filter-parameter> | <filter-parameter> "," <filter-parameter-list>``
+
+ and ``filter-parameter``:
+
+ ``( <param-name> "=" <param-value> ) | <param-value>``
+
+ ``param-value`` can further be quoted in ``[`` / ``]`` in case the value
+ contains characters like ``,`` or ``=``. This is used in particular with
+ the ``lavfi`` filter, which uses a very similar syntax as mpv (MPlayer
+ historically) to specify filters and their parameters.
You can also set defaults for each filter. The defaults are applied before the
normal filter parameters.
diff --git a/audio/filter/af.c b/audio/filter/af.c
index 31f4e45614..84ee377136 100644
--- a/audio/filter/af.c
+++ b/audio/filter/af.c
@@ -78,6 +78,7 @@ static bool get_desc(struct m_obj_desc *dst, int index)
const struct m_obj_list af_obj_list = {
.get_desc = get_desc,
.description = "audio filters",
+ .allow_disable_entries = true,
.aliases = {
{"force", "format"},
{0}
@@ -545,6 +546,8 @@ int af_init(struct af_stream *s)
// Add all filters in the list (if there are any)
struct m_obj_settings *list = s->opts->af_settings;
for (int i = 0; list && list[i].name; i++) {
+ if (!list[i].enabled)
+ continue;
struct af_instance *af =
af_prepend(s, s->last, list[i].name, list[i].attribs);
if (!af) {
diff --git a/options/m_option.c b/options/m_option.c
index 7f30b73a9a..29bbcb17db 100644
--- a/options/m_option.c
+++ b/options/m_option.c
@@ -2590,6 +2590,7 @@ static void copy_obj_settings_list(const m_option_t *opt, void *dst,
for (n = 0; s[n].name; n++) {
d[n].name = talloc_strdup(NULL, s[n].name);
d[n].label = talloc_strdup(NULL, s[n].label);
+ d[n].enabled = s[n].enabled;
d[n].attribs = NULL;
copy_str_list(NULL, &(d[n].attribs), &(s[n].attribs));
}
@@ -2754,7 +2755,7 @@ exit:
#define NAMECH "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-"
// Parse one item, e.g. -vf a=b:c:d,e=f:g => parse a=b:c:d into "a" and "b:c:d"
-static int parse_obj_settings(struct mp_log *log, struct bstr opt,
+static int parse_obj_settings(struct mp_log *log, struct bstr opt, int op,
struct bstr *pstr, const struct m_obj_list *list,
m_obj_settings_t **_ret)
{
@@ -2763,6 +2764,7 @@ static int parse_obj_settings(struct mp_log *log, struct bstr opt,
struct m_obj_desc desc;
bstr label = {0};
bool nopos = list->disallow_positional_parameters;
+ bool enabled = true;
if (bstr_eatstart0(pstr, "@")) {
if (!bstr_split_tok(*pstr, ":", &label, pstr)) {
@@ -2771,9 +2773,14 @@ static int parse_obj_settings(struct mp_log *log, struct bstr opt,
}
}
+ if (list->allow_disable_entries && bstr_eatstart0(pstr, "!"))
+ enabled = false;
+
bool has_param = false;
int idx = bstrspn(*pstr, NAMECH);
bstr str = bstr_splice(*pstr, 0, idx);
+ if (str.len == 0 && !enabled && label.len && op == OP_TOGGLE)
+ goto done; // "@labelname:!" is the special enable/disable toggle syntax
*pstr = bstr_cut(*pstr, idx);
// video filters use "=", VOs use ":"
if (bstr_eatstart0(pstr, "=") || bstr_eatstart0(pstr, ":"))
@@ -2817,9 +2824,11 @@ static int parse_obj_settings(struct mp_log *log, struct bstr opt,
if (!_ret)
return 1;
+done: ;
m_obj_settings_t item = {
.name = bstrto0(NULL, str),
.label = bstrdup0(NULL, label),
+ .enabled = enabled,
.attribs = plist,
};
obj_settings_list_insert_at(_ret, -1, &item);
@@ -2964,7 +2973,7 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
if (op == OP_DEL)
r = parse_obj_settings_del(log, name, &param, dst, mark_del);
if (r == 0) {
- r = parse_obj_settings(log, name, &param, ol, dst ? &res : NULL);
+ r = parse_obj_settings(log, name, op, &param, ol, dst ? &res : NULL);
}
if (r < 0)
return r;
@@ -3017,12 +3026,25 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
talloc_free(res);
} else if (op == OP_TOGGLE) {
for (int n = 0; res && res[n].name; n++) {
- int found = obj_settings_find_by_content(list, &res[n]);
- if (found < 0) {
- obj_settings_list_insert_at(&list, -1, &res[n]);
- } else {
- obj_settings_list_del_at(&list, found);
+ if (!res[n].enabled && !res[n].name[0]) {
+ // Toggle enable/disable special case.
+ int found =
+ obj_settings_list_find_by_label0(list, res[n].label);
+ if (found < 0) {
+ mp_warn(log, "Option %.*s: Label %s not found\n",
+ BSTR_P(name), res[n].label);
+ } else {
+ list[found].enabled = !list[found].enabled;
+ }
obj_setting_free(&res[n]);
+ } else {
+ int found = obj_settings_find_by_content(list, &res[n]);
+ if (found < 0) {
+ obj_settings_list_insert_at(&list, -1, &res[n]);
+ } else {
+ obj_settings_list_del_at(&list, found);
+ obj_setting_free(&res[n]);
+ }
}
}
talloc_free(res);
@@ -3073,6 +3095,8 @@ static char *print_obj_settings_list(const m_option_t *opt, const void *val)
// Assume labels and names don't need escaping
if (entry->label && entry->label[0])
res = talloc_asprintf_append(res, "@%s:", entry->label);
+ if (!entry->enabled)
+ res = talloc_strdup_append(res, "!");
res = talloc_strdup_append(res, entry->name);
if (entry->attribs && entry->attribs[0]) {
res = talloc_strdup_append(res, "=");
@@ -3111,6 +3135,10 @@ static int set_obj_settings_list(const m_option_t *opt, void *dst,
if (val->format != MPV_FORMAT_STRING)
goto error;
entry->label = talloc_strdup(NULL, val->u.string);
+ } else if (strcmp(key, "enabled") == 0) {
+ if (val->format != MPV_FORMAT_FLAG)
+ goto error;
+ entry->enabled = val->u.flag;
} else if (strcmp(key, "params") == 0) {
if (val->format != MPV_FORMAT_NODE_MAP)
goto error;
@@ -3176,6 +3204,9 @@ static int get_obj_settings_list(const m_option_t *opt, void *ta_parent,
add_map_string(nentry, "name", entry->name);
if (entry->label && entry->label[0])
add_map_string(nentry, "label", entry->label);
+ struct mpv_node *enabled = add_map_entry(nentry, "enabled");
+ enabled->format = MPV_FORMAT_FLAG;
+ enabled->u.flag = entry->enabled;
struct mpv_node *params = add_map_entry(nentry, "params");
params->format = MPV_FORMAT_NODE_MAP;
params->u.list = talloc_zero(ta_parent, struct mpv_node_list);
diff --git a/options/m_option.h b/options/m_option.h
index 8709d20bb2..f3a4e7bc1e 100644
--- a/options/m_option.h
+++ b/options/m_option.h
@@ -146,6 +146,8 @@ struct m_obj_list {
// Allow unknown entries, for which a dummy entry is inserted, and whose
// options are skipped and ignored.
bool allow_unknown_entries;
+ // Allow syntax for disabling entries.
+ bool allow_disable_entries;
// This helps with confusing error messages if unknown flag options are used.
bool disallow_positional_parameters;
// Each sub-item is backed by global options (for AOs and VOs).
@@ -162,6 +164,8 @@ typedef struct m_obj_settings {
char *name;
// Optional user-defined name.
char *label;
+ // User enable flag.
+ bool enabled;
// NULL terminated array of parameter/value pairs.
char **attribs;
} m_obj_settings_t;
diff --git a/player/command.c b/player/command.c
index 9050812fb3..28d331c97e 100644
--- a/player/command.c
+++ b/player/command.c
@@ -3449,7 +3449,10 @@ static char *print_obj_osd_list(struct m_obj_settings *list)
list[n].attribs[i],
list[n].attribs[i + 1]);
}
- res = talloc_asprintf_append(res, "]\n");
+ res = talloc_asprintf_append(res, "]");
+ if (!list[n].enabled)
+ res = talloc_strdup_append(res, " (disabled)");
+ res = talloc_strdup_append(res, "\n");
}
if (!res)
res = talloc_strdup(NULL, "(empty)");
diff --git a/video/filter/vf.c b/video/filter/vf.c
index 94e6760603..5208c7f824 100644
--- a/video/filter/vf.c
+++ b/video/filter/vf.c
@@ -128,6 +128,7 @@ static bool get_desc(struct m_obj_desc *dst, int index)
const struct m_obj_list vf_obj_list = {
.get_desc = get_desc,
.description = "video filters",
+ .allow_disable_entries = true,
};
// Try the cmd on each filter (starting with the first), and stop at the first
@@ -322,6 +323,8 @@ struct vf_instance *vf_append_filter(struct vf_chain *c, const char *name,
int vf_append_filter_list(struct vf_chain *c, struct m_obj_settings *list)
{
for (int n = 0; list && list[n].name; n++) {
+ if (!list[n].enabled)
+ continue;
struct vf_instance *vf =
vf_append_filter(c, list[n].name, list[n].attribs);
if (vf) {