From 31611fc46b29e0704004e21f1e25de2f9608e109 Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 3 Apr 2017 18:04:18 +0200 Subject: video: support positional arguments for automatic lavfi option bridge Now e.g. --vf=pad=1000:1000 works. All in all pretty ugly and hacky. Just look away. --- common/av_common.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'common') diff --git a/common/av_common.c b/common/av_common.c index 5c58f3fea8..d7ad8e172c 100644 --- a/common/av_common.c +++ b/common/av_common.c @@ -302,6 +302,35 @@ void mp_avdict_print_unset(struct mp_log *log, int msgl, AVDictionary *dict) mp_msg(log, msgl, "Could not set AVOption %s='%s'\n", t->key, t->value); } +// If the name starts with "@", try to interpret it as a number, and set *name +// to the name of the n-th parameter. +static void resolve_positional_arg(void *avobj, char **name) +{ + if (!*name || (*name)[0] != '@') + return; + + char *end = NULL; + int pos = strtol(*name + 1, &end, 10); + if (!end || *end) + return; + + const AVOption *opt = NULL; + int offset = -1; + while (1) { + opt = av_opt_next(avobj, opt); + if (!opt) + return; + // This is what libavfilter's parser does to skip aliases. + if (opt->offset != offset && opt->type != AV_OPT_TYPE_CONST) + pos--; + if (pos < 0) { + *name = (char *)opt->name; + return; + } + offset = opt->offset; + } +} + // kv is in the format as by OPT_KEYVALUELIST(): kv[0]=key0, kv[1]=val0, ... // Set these options on given avobj (using av_opt_set..., meaning avobj must // point to a struct that has AVClass as first member). @@ -313,6 +342,7 @@ int mp_set_avopts(struct mp_log *log, void *avobj, char **kv) for (int n = 0; kv && kv[n * 2]; n++) { char *k = kv[n * 2 + 0]; char *v = kv[n * 2 + 1]; + resolve_positional_arg(avobj, &k); int r = av_opt_set(avobj, k, v, AV_OPT_SEARCH_CHILDREN); if (r == AVERROR_OPTION_NOT_FOUND) { mp_err(log, "AVOption '%s' not found.\n", k); -- cgit v1.2.3