lavu/opt: introduce av_opt_is_set_to_default()
authorLukasz Marek <lukasz.m.luki2@gmail.com>
Mon, 10 Nov 2014 21:25:30 +0000 (22:25 +0100)
committerLukasz Marek <lukasz.m.luki2@gmail.com>
Sun, 16 Nov 2014 00:13:38 +0000 (01:13 +0100)
New function allows to check if option is set to its default value

Signed-off-by: Lukasz Marek <lukasz.m.luki2@gmail.com>
doc/APIchanges
libavutil/opt.c
libavutil/opt.h
libavutil/version.h
tests/ref/fate/opt

index 7c5ab9b..079bfb5 100644 (file)
@@ -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.
 
index 4e286ff..72e4caf 100644 (file)
@@ -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 };
index 39365ac..1b458e1 100644 (file)
@@ -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 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);
+
+/**
  * @}
  */
 
index a682c80..a48ea8d 100644 (file)
@@ -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, \
index 6523390..7953ce8 100644 (file)
@@ -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 ':'