diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-07-21 16:00:08 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-07-21 17:00:37 +0200 |
commit | 265dadbe7de5e0f35faeedf0a76a823cbc71cd72 (patch) | |
tree | 915cd3cf780e2af85207fd039dcfaef82bcb5f57 | |
parent | 88efc013b10cbbb5c6b4281c88c4ad1f66d45af8 (diff) | |
download | ffmpeg-265dadbe7de5e0f35faeedf0a76a823cbc71cd72.tar.gz |
avutil/opt: Support general expressions involving AVOption constants in set_string_number()
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavutil/opt.c | 61 |
1 files changed, 36 insertions, 25 deletions
diff --git a/libavutil/opt.c b/libavutil/opt.c index 9ea4aa50ed..40c944dd7a 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -129,18 +129,6 @@ static int write_number(void *obj, const AVOption *o, void *dst, double num, int return 0; } -static const double const_values[] = { - M_PI, - M_E, - 0 -}; - -static const char * const const_names[] = { - "PI", - "E", - 0 -}; - static int hexchar2int(char c) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return c - 'a' + 10; @@ -220,21 +208,44 @@ static int set_string_number(void *obj, void *target_obj, const AVOption *o, con buf[i] = 0; { - const AVOption *o_named = av_opt_find(target_obj, buf, o->unit, 0, 0); - if (o_named && o_named->type == AV_OPT_TYPE_CONST) - d = DEFAULT_NUMVAL(o_named); - else if (!strcmp(buf, "default")) d = DEFAULT_NUMVAL(o); - else if (!strcmp(buf, "max" )) d = o->max; - else if (!strcmp(buf, "min" )) d = o->min; - else if (!strcmp(buf, "none" )) d = 0; - else if (!strcmp(buf, "all" )) d = ~0; - else { - int 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 AVOption *o_named; + 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; + } + 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; + } } if (o->type == AV_OPT_TYPE_FLAGS) { read_number(o, dst, NULL, NULL, &intnum); |