From eec693328a09f0dc6cbe398c199d093405ba7cf9 Mon Sep 17 00:00:00 2001 From: Lukasz Marek Date: Mon, 10 Nov 2014 22:25:30 +0100 Subject: lavu/opt: introduce av_opt_is_set_to_default() New function allows to check if option is set to its default value Signed-off-by: Lukasz Marek --- doc/APIchanges | 3 ++ libavutil/opt.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++ libavutil/opt.h | 26 +++++++++++ libavutil/version.h | 2 +- tests/ref/fate/opt | 40 +++++++++++++++++ 5 files changed, 194 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index 7c5ab9b870..079bfb5db2 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2014-08-09 API changes, most recent first: +2014-11-16 - xxxxxxx - lavu 54.12.0 - opt.h + Add av_opt_is_set_to_default(). + 2014-11-xx - xxxxxxx - lavc 56.6.0 - vorbis_parser.h Add a public API for parsing vorbis packets. diff --git a/libavutil/opt.c b/libavutil/opt.c index 4e286ff06f..72e4caf633 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -1732,6 +1732,109 @@ void av_opt_freep_ranges(AVOptionRanges **rangesp) av_freep(rangesp); } +int av_opt_is_set_to_default(void *obj, const AVOption *o) +{ + int64_t i64; + double d, d2; + float f; + AVRational q; + int ret, w, h; + char *str; + void *dst; + + if (!o || !obj) + return AVERROR(EINVAL); + + dst = ((uint8_t*)obj) + o->offset; + + switch (o->type) { + case AV_OPT_TYPE_CONST: + return 1; + case AV_OPT_TYPE_FLAGS: + case AV_OPT_TYPE_PIXEL_FMT: + case AV_OPT_TYPE_SAMPLE_FMT: + case AV_OPT_TYPE_INT: + case AV_OPT_TYPE_CHANNEL_LAYOUT: + case AV_OPT_TYPE_DURATION: + case AV_OPT_TYPE_INT64: + read_number(o, dst, NULL, NULL, &i64); + return o->default_val.i64 == i64; + case AV_OPT_TYPE_STRING: + str = *(char **)dst; + if (str == o->default_val.str) //2 NULLs + return 1; + if (!str || !o->default_val.str) //1 NULL + return 0; + return !strcmp(str, o->default_val.str); + case AV_OPT_TYPE_DOUBLE: + read_number(o, dst, &d, NULL, NULL); + return o->default_val.dbl == d; + case AV_OPT_TYPE_FLOAT: + read_number(o, dst, &d, NULL, NULL); + f = o->default_val.dbl; + d2 = f; + return d2 == d; + case AV_OPT_TYPE_RATIONAL: + q = av_d2q(o->default_val.dbl, INT_MAX); + return !av_cmp_q(*(AVRational*)dst, q); + case AV_OPT_TYPE_BINARY: { + struct { + uint8_t *data; + int size; + } tmp = {0}; + int opt_size = *(int *)((void **)dst + 1); + void *opt_ptr = *(void **)dst; + if (!opt_ptr && (!o->default_val.str || !strlen(o->default_val.str))) + return 1; + if (opt_ptr && o->default_val.str && !strlen(o->default_val.str)) + return 0; + if (opt_size != strlen(o->default_val.str) / 2) + return 0; + ret = set_string_binary(NULL, NULL, o->default_val.str, &tmp.data); + if (!ret) + ret = !memcmp(opt_ptr, tmp.data, tmp.size); + av_free(tmp.data); + return ret; + } + case AV_OPT_TYPE_DICT: + /* Binary and dict have not default support yet. Any pointer is not default. */ + return !!(*(void **)dst); + case AV_OPT_TYPE_IMAGE_SIZE: + if (!o->default_val.str || !strcmp(o->default_val.str, "none")) + w = h = 0; + else if ((ret = av_parse_video_size(&w, &h, o->default_val.str)) < 0) + return ret; + return (w == *(int *)dst) && (h == *((int *)dst+1)); + case AV_OPT_TYPE_VIDEO_RATE: + q = (AVRational){0, 0}; + if (o->default_val.str) + av_parse_video_rate(&q, o->default_val.str); + return !av_cmp_q(*(AVRational*)dst, q); + case AV_OPT_TYPE_COLOR: { + uint8_t color[4] = {0, 0, 0, 0}; + if (o->default_val.str) + av_parse_color(color, o->default_val.str, -1, NULL); + return !memcmp(color, dst, sizeof(color)); + } + default: + av_log(obj, AV_LOG_WARNING, "Not supported option type: %d, option name: %s\n", o->type, o->name); + break; + } + return AVERROR_PATCHWELCOME; +} + +int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags) +{ + const AVOption *o; + void *target; + if (!obj) + return AVERROR(EINVAL); + o = av_opt_find2(obj, name, NULL, 0, search_flags, &target); + if (!o) + return AVERROR_OPTION_NOT_FOUND; + return av_opt_is_set_to_default(target, o); +} + #ifdef TEST typedef struct TestContext @@ -1827,6 +1930,27 @@ int main(void) av_opt_free(&test_ctx); } + printf("\nTesting av_opt_is_set_to_default()\n"); + { + int ret; + TestContext test_ctx = { 0 }; + const AVOption *o = NULL; + test_ctx.class = &test_class; + + av_log_set_level(AV_LOG_QUIET); + + while (o = av_opt_next(&test_ctx, o)) { + ret = av_opt_is_set_to_default_by_name(&test_ctx, o->name, 0); + printf("name:%10s default:%d error:%s\n", o->name, !!ret, ret < 0 ? av_err2str(ret) : ""); + } + av_opt_set_defaults(&test_ctx); + while (o = av_opt_next(&test_ctx, o)) { + ret = av_opt_is_set_to_default_by_name(&test_ctx, o->name, 0); + printf("name:%10s default:%d error:%s\n", o->name, !!ret, ret < 0 ? av_err2str(ret) : ""); + } + av_opt_free(&test_ctx); + } + printf("\nTesting av_set_options_string()\n"); { TestContext test_ctx = { 0 }; diff --git a/libavutil/opt.h b/libavutil/opt.h index 39365ac957..1b458e1860 100644 --- a/libavutil/opt.h +++ b/libavutil/opt.h @@ -843,6 +843,32 @@ int av_opt_copy(void *dest, void *src); */ int av_opt_query_ranges_default(AVOptionRanges **, void *obj, const char *key, int flags); +/** + * Check if given option is set to its default value. + * + * Options o must belong to the obj. This function must not be called to check child's options state. + * @see av_opt_is_set_to_default_by_name(). + * + * @param obj AVClass object to check option on + * @param o option to be checked + * @return >0 when option is set to its default, + * 0 when option is not set its default, + * <0 on error + */ +int av_opt_is_set_to_default(void *obj, const AVOption *o); + +/** + * Check if given option is set to its default value. + * + * @param obj AVClass object to check option on + * @param name option name + * @param search_flags combination of AV_OPT_SEARCH_* + * @return >0 when option is set to its default, + * 0 when option is not set its default, + * <0 on error + */ +int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags); + /** * @} */ diff --git a/libavutil/version.h b/libavutil/version.h index a682c806ca..a48ea8d73d 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -56,7 +56,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 54 -#define LIBAVUTIL_VERSION_MINOR 11 +#define LIBAVUTIL_VERSION_MINOR 12 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ diff --git a/tests/ref/fate/opt b/tests/ref/fate/opt index 6523390dde..7953ce8eca 100644 --- a/tests/ref/fate/opt +++ b/tests/ref/fate/opt @@ -17,6 +17,46 @@ num64=1 flt=0.333333 dbl=0.333333 +Testing av_opt_is_set_to_default() +name: num default:1 error: +name: toggle default:0 error: +name: rational default:0 error: +name: string default:0 error: +name: flags default:0 error: +name: cool default:1 error:Option not found +name: lame default:1 error:Option not found +name: mu default:1 error:Option not found +name: size default:0 error: +name: pix_fmt default:0 error: +name:sample_fmt default:0 error: +name:video_rate default:0 error: +name: duration default:0 error: +name: color default:0 error: +name: cl default:0 error: +name: bin default:0 error: +name: num64 default:0 error: +name: flt default:0 error: +name: dbl default:0 error: +name: num default:1 error: +name: toggle default:1 error: +name: rational default:1 error: +name: string default:1 error: +name: flags default:1 error: +name: cool default:1 error:Option not found +name: lame default:1 error:Option not found +name: mu default:1 error:Option not found +name: size default:1 error: +name: pix_fmt default:1 error: +name:sample_fmt default:1 error: +name:video_rate default:1 error: +name: duration default:1 error: +name: color default:1 error: +name: cl default:1 error: +name: bin default:1 error: +name: num64 default:1 error: +name: flt default:1 error: +name: dbl default:1 error: + Testing av_set_options_string() OK '' Error ':' -- cgit v1.2.3