[FFmpeg-cvslog] lavfi: restore mixed short/long option support with the new system.

Clément Bœsch git at videolan.org
Thu Apr 11 11:17:23 CEST 2013


ffmpeg | branch: master | Clément Bœsch <ubitux at gmail.com> | Thu Apr 11 10:38:05 2013 +0200| [b89ce54e740500715803c2731bf0008f6fd4bfa8] | committer: Clément Bœsch

lavfi: restore mixed short/long option support with the new system.

process_unnamed_options() is renamed to process_options() and its code
is heavily based on av_opt_set_from_string().

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=b89ce54e740500715803c2731bf0008f6fd4bfa8
---

 doc/filters.texi       |    8 ++++-
 libavfilter/avfilter.c |   86 ++++++++++++++++++++++++++++--------------------
 2 files changed, 58 insertions(+), 36 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index ffdc0db..7fd1481 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}.
 
+ at 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
+ at 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 e96c8f2..1ef27af 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -615,39 +615,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)
@@ -787,20 +812,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")     ||
@@ -840,14 +856,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;
         }



More information about the ffmpeg-cvslog mailing list