aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-04-11 11:09:44 +0200
committerMichael Niedermayer <michaelni@gmx.at>2013-04-11 11:09:51 +0200
commitd7e8b3d83179b811764660f5613905f7eb726291 (patch)
tree96b36ca92dd9dc098387fe0457953dcf10c896c0
parent44d4488301c69bc026908011a9b6f9df5add3353 (diff)
parentb89ce54e740500715803c2731bf0008f6fd4bfa8 (diff)
downloadffmpeg-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.texi8
-rw-r--r--libavfilter/avfilter.c86
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(&copy);
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(&copy);
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;
}