]> git.sesse.net Git - ffmpeg/blobdiff - libavutil/opt.c
Merge commit '1ef9e8376466bb1e2c147e47554b94cab9c8b04a'
[ffmpeg] / libavutil / opt.c
index 40c944dd7af89644ccd49aec03db224675e0b6c1..2a06eb6f39fbed10c53434a15cb28fb017ec5fce 100644 (file)
@@ -191,60 +191,62 @@ static int set_string_number(void *obj, void *target_obj, const AVOption *o, con
     }
 
     for (;;) {
-        int i, den = 1;
+        int i = 0;
         char buf[256];
         int cmd = 0;
-        double d, num = 1;
+        double d;
         int64_t intnum = 1;
 
-        i = 0;
-        if (*val == '+' || *val == '-') {
-            if (o->type == AV_OPT_TYPE_FLAGS)
+        if (o->type == AV_OPT_TYPE_FLAGS) {
+            if (*val == '+' || *val == '-')
                 cmd = *(val++);
+            for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
+                buf[i] = val[i];
+            buf[i] = 0;
         }
 
-        for (; i < sizeof(buf) - 1 && val[i] && (o->type != AV_OPT_TYPE_FLAGS || val[i] != '+' && val[i] != '-'); i++)
-            buf[i] = val[i];
-        buf[i] = 0;
-
         {
-            const AVOption *o_named;
+            const AVOption *o_named = av_opt_find(target_obj, i ? buf : val, o->unit, 0, 0);
             int res;
             int ci = 0;
             double const_values[64];
             const char * const_names[64];
-
-            if (o->unit) {
-                for (o_named = NULL; o_named = av_opt_next(target_obj, o_named); ) {
-                    if (o_named->type == AV_OPT_TYPE_CONST &&
-                        o_named->unit &&
-                        !strcmp(o_named->unit, o->unit)) {
-                        if (ci + 6 >= FF_ARRAY_ELEMS(const_values)) {
-                            av_log(obj, AV_LOG_ERROR, "const_values array too small for %s\n", o->unit);
-                            return AVERROR_PATCHWELCOME;
+            if (o_named && o_named->type == AV_OPT_TYPE_CONST)
+                d = DEFAULT_NUMVAL(o_named);
+            else {
+                if (o->unit) {
+                    for (o_named = NULL; o_named = av_opt_next(target_obj, o_named); ) {
+                        if (o_named->type == AV_OPT_TYPE_CONST &&
+                            o_named->unit &&
+                            !strcmp(o_named->unit, o->unit)) {
+                            if (ci + 6 >= FF_ARRAY_ELEMS(const_values)) {
+                                av_log(obj, AV_LOG_ERROR, "const_values array too small for %s\n", o->unit);
+                                return AVERROR_PATCHWELCOME;
+                            }
+                            const_names [ci  ] = o_named->name;
+                            const_values[ci++] = DEFAULT_NUMVAL(o_named);
                         }
-                        const_names [ci  ] = o_named->name;
-                        const_values[ci++] = DEFAULT_NUMVAL(o_named);
                     }
                 }
-            }
-            const_names [ci  ] = "default";
-            const_values[ci++] = DEFAULT_NUMVAL(o);
-            const_names [ci  ] = "max";
-            const_values[ci++] = o->max;
-            const_names [ci  ] = "min";
-            const_values[ci++] = o->min;
-            const_names [ci  ] = "none";
-            const_values[ci++] = 0;
-            const_names [ci  ] = "all";
-            const_values[ci++] = ~0;
-            const_names [ci] = NULL;
-            const_values[ci] = 0;
-
-            res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
-            if (res < 0) {
-                av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);
-                return res;
+                const_names [ci  ] = "default";
+                const_values[ci++] = DEFAULT_NUMVAL(o);
+                const_names [ci  ] = "max";
+                const_values[ci++] = o->max;
+                const_names [ci  ] = "min";
+                const_values[ci++] = o->min;
+                const_names [ci  ] = "none";
+                const_values[ci++] = 0;
+                const_names [ci  ] = "all";
+                const_values[ci++] = ~0;
+                const_names [ci] = NULL;
+                const_values[ci] = 0;
+
+                res = av_expr_parse_and_eval(&d, i ? buf : val, const_names,
+                                            const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
+                if (res < 0) {
+                    av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);
+                    return res;
+                }
             }
         }
         if (o->type == AV_OPT_TYPE_FLAGS) {
@@ -256,7 +258,7 @@ static int set_string_number(void *obj, void *target_obj, const AVOption *o, con
         if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0)
             return ret;
         val += i;
-        if (!*val)
+        if (!i || !*val)
             return 0;
     }