diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-04-11 11:09:44 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-04-11 11:09:51 +0200 |
commit | d7e8b3d83179b811764660f5613905f7eb726291 (patch) | |
tree | 96b36ca92dd9dc098387fe0457953dcf10c896c0 | |
parent | 44d4488301c69bc026908011a9b6f9df5add3353 (diff) | |
parent | b89ce54e740500715803c2731bf0008f6fd4bfa8 (diff) | |
download | ffmpeg-d7e8b3d83179b811764660f5613905f7eb726291.tar.gz |
Merge remote-tracking branch 'ubitux/lavfi-mixed-short-long'
* ubitux/lavfi-mixed-short-long:
lavfi: restore mixed short/long option support with the new system.
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | doc/filters.texi | 8 | ||||
-rw-r--r-- | libavfilter/avfilter.c | 86 |
2 files changed, 58 insertions, 36 deletions
diff --git a/doc/filters.texi b/doc/filters.texi index ffdc0db570..7fd1481161 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -137,7 +137,7 @@ The name of the filter class is optionally followed by a string "=@var{arguments}". @var{arguments} is a string which contains the parameters used to -initialize the filter instance. It may have one of the two allowed forms: +initialize the filter instance. It may have one of the following forms: @itemize @item @@ -151,6 +151,12 @@ declares three options in this order -- @option{type}, @option{start_frame} and @var{in} is assigned to the option @option{type}, @var{0} to @option{start_frame} and @var{30} to @option{nb_frames}. +@item +A ':'-separated list of mixed direct @var{value} and long @var{key=value} +pairs. The direct @var{value} must precede the @var{key=value} pairs, and +follow the same constraints order of the previous point. The following +@var{key=value} pairs can be set in any preferred order. + @end itemize If the option value itself is a list of items (e.g. the @code{format} filter diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 5dd4965671..e958923ff2 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -610,39 +610,64 @@ void avfilter_free(AVFilterContext *filter) av_free(filter); } -/* process a list of value1:value2:..., each value corresponding - * to subsequent AVOption, in the order they are declared */ -static int process_unnamed_options(AVFilterContext *ctx, AVDictionary **options, - const char *args) +static int process_options(AVFilterContext *ctx, AVDictionary **options, + const char *args) { const AVOption *o = NULL; - const char *p = args; - char *val; + int ret, count = 0; + char *av_uninit(parsed_key), *av_uninit(value); + const char *key; int offset= -1; - while (*p) { + if (!args) + return 0; + + while (*args) { + const char *shorthand = NULL; + o = av_opt_next(ctx->priv, o); - if (!o) { - av_log(ctx, AV_LOG_ERROR, "More options provided than " - "this filter supports.\n"); - return AVERROR(EINVAL); + if (o) { + if (o->type == AV_OPT_TYPE_CONST || o->offset == offset) + continue; + offset = o->offset; + shorthand = o->name; } - if (o->type == AV_OPT_TYPE_CONST || o->offset == offset) - continue; - offset = o->offset; - val = av_get_token(&p, ":"); - if (!val) - return AVERROR(ENOMEM); + ret = av_opt_get_key_value(&args, "=", ":", + shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0, + &parsed_key, &value); + if (ret < 0) { + if (ret == AVERROR(EINVAL)) + av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", args); + else + av_log(ctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", args, + av_err2str(ret)); + return ret; + } + if (*args) + args++; + if (parsed_key) { + key = parsed_key; + while ((o = av_opt_next(ctx->priv, o))); /* discard all remaining shorthand */ + } else { + key = shorthand; + } - av_dict_set(options, o->name, val, 0); + av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value); + av_dict_set(options, key, value, 0); + if ((ret = av_opt_set(ctx->priv, key, value, 0)) < 0) { + if (ret == AVERROR_OPTION_NOT_FOUND) + av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key); + av_free(value); + av_free(parsed_key); + return ret; + } - av_freep(&val); - if (*p) - p++; + av_free(value); + av_free(parsed_key); + count++; } - - return 0; + return count; } int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque) @@ -782,20 +807,11 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque ret = av_dict_parse_string(&options, p, "=", ":", 0); } if (ret >= 0) - ret = process_unnamed_options(filter, &options, copy); + ret = process_options(filter, &options, copy); av_freep(©); if (ret < 0) goto fail; - } else -#endif - - if (strchr(args, '=')) { - /* assume a list of key1=value1:key2=value2:... */ - ret = av_dict_parse_string(&options, args, "=", ":", 0); - if (ret < 0) - goto fail; -#if FF_API_OLD_FILTER_OPTS } else if (!strcmp(filter->filter->name, "format") || !strcmp(filter->filter->name, "noformat") || !strcmp(filter->filter->name, "frei0r") || @@ -835,14 +851,14 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque while ((p = strchr(p, ':'))) *p++ = '|'; - ret = process_unnamed_options(filter, &options, copy); + ret = process_options(filter, &options, copy); av_freep(©); if (ret < 0) goto fail; #endif } else { - ret = process_unnamed_options(filter, &options, args); + ret = process_options(filter, &options, args); if (ret < 0) goto fail; } |