On date Tuesday 2014-11-11 08:31:23 +0100, Lukasz Marek encoded: > TODO: bump minor version, update doc/APIchanges > > New function allows to check if option is set to its default > > Signed-off-by: Lukasz Marek <lukasz.m.lu...@gmail.com> > --- > libavutil/opt.c | 127 > +++++++++++++++++++++++++++++++++++++++++++++++++++++ > libavutil/opt.h | 26 +++++++++++ > tests/ref/fate/opt | 40 +++++++++++++++++ > 3 files changed, 193 insertions(+) > > diff --git a/libavutil/opt.c b/libavutil/opt.c > index f55f1c5..85c9379 100644 > --- a/libavutil/opt.c > +++ b/libavutil/opt.c > @@ -1726,6 +1726,110 @@ 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); you should check the return value here as well for consistency. Alternatively you can place an assert(). > + 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); ditto > + return ((uint8_t *)dst)[0] == color[0] && ((uint8_t *)dst)[1] == > color[1] && > + ((uint8_t *)dst)[2] == color[2] && ((uint8_t *)dst)[3] == > color[3]; memcmp or maybe a cast to uint32_t, but that's subjective. > + } > + default: > + av_log(NULL, AV_LOG_WARNING, "Not supported option type: %d\n", > o->type); nit: also state name and value, so that's easier to debug > + break; > + } > + return AVERROR_PATCHWELCOME; unreachable code, probably an assert is better here > +} > + > +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 > @@ -1820,6 +1924,29 @@ int main(void) > printf("dbl=%.6f\n", test_ctx.dbl); > } > > + printf("\nTesting av_opt_is_set_to_default()\n"); > + { > + 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)) { > + if (av_opt_is_set_to_default_by_name(&test_ctx, o->name, 0) <= 0) > + printf("option not detected as set to default: '%s'\n", > o->name); > + else > + printf("option detected as set to default: '%s'\n", > o->name); probably less verbose for a test: ret = av_opt_is_set_to_default_by_name(&test_ctx, o->name, 0); printf("name:%s default:%s error:%s", o->name, !!ret, av_err2str(ret)); > + printf("option not detected as set to default: '%s'\n", > o->name); > + } > + av_opt_set_defaults(&test_ctx); > + while (o = av_opt_next(&test_ctx, o)) { > + if (av_opt_is_set_to_default_by_name(&test_ctx, o->name, 0) <= 0) > + printf("option not detected as set to default: '%s'\n", > o->name); > + else > + printf("option detected as set to default: '%s'\n", > o->name); > + } > + } > + > printf("\nTesting av_set_options_string()\n"); > { > TestContext test_ctx = { 0 }; > diff --git a/libavutil/opt.h b/libavutil/opt.h > index df5a62e..a3ad7cc 100644 > --- a/libavutil/opt.h > +++ b/libavutil/opt.h > @@ -844,6 +844,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. ... 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. drop capitalization and ending point for incomplete sentences > + * @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. > + * > + * @param obj AVClass object to check option on. > + * @param name Option name. > + * @param search_flags A combination of AV_OPT_SEARCH_*. ditto [...] -- FFmpeg = Frightening and Furious Murdering Ponderous Entertaining Gnome _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel