[FFmpeg-devel] [PATCH 1/9] lavu/opt: introduce av_opt_is_set_to_default()

Lukasz Marek lukasz.m.luki2 at gmail.com
Tue Nov 11 08:31:23 CET 2014


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.luki2 at 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);
+        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 ((uint8_t *)dst)[0] == color[0] && ((uint8_t *)dst)[1] == color[1] &&
+               ((uint8_t *)dst)[2] == color[2] && ((uint8_t *)dst)[3] == color[3];
+    }
+    default:
+        av_log(NULL, AV_LOG_WARNING, "Not supported option type: %d\n", o->type);
+        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
@@ -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);
+        }
+        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.
+ *
+ * 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.
+ *
+ * @param obj          AVClass object to check option on.
+ * @param name         Option name.
+ * @param search_flags A 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/tests/ref/fate/opt b/tests/ref/fate/opt
index a14c558..21008bc 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()
+option     detected as set to default: 'num'
+option not detected as set to default: 'toggle'
+option not detected as set to default: 'rational'
+option not detected as set to default: 'string'
+option not detected as set to default: 'flags'
+option not detected as set to default: 'cool'
+option not detected as set to default: 'lame'
+option not detected as set to default: 'mu'
+option not detected as set to default: 'size'
+option not detected as set to default: 'pix_fmt'
+option not detected as set to default: 'sample_fmt'
+option not detected as set to default: 'video_rate'
+option not detected as set to default: 'duration'
+option not detected as set to default: 'color'
+option not detected as set to default: 'cl'
+option not detected as set to default: 'bin'
+option not detected as set to default: 'num64'
+option not detected as set to default: 'flt'
+option not detected as set to default: 'dbl'
+option     detected as set to default: 'num'
+option     detected as set to default: 'toggle'
+option     detected as set to default: 'rational'
+option     detected as set to default: 'string'
+option     detected as set to default: 'flags'
+option not detected as set to default: 'cool'
+option not detected as set to default: 'lame'
+option not detected as set to default: 'mu'
+option     detected as set to default: 'size'
+option     detected as set to default: 'pix_fmt'
+option     detected as set to default: 'sample_fmt'
+option     detected as set to default: 'video_rate'
+option     detected as set to default: 'duration'
+option     detected as set to default: 'color'
+option     detected as set to default: 'cl'
+option     detected as set to default: 'bin'
+option     detected as set to default: 'num64'
+option     detected as set to default: 'flt'
+option     detected as set to default: 'dbl'
+
 Testing av_set_options_string()
 OK    setting options string: ''
 Error setting options string: ':'
-- 
1.9.1



More information about the ffmpeg-devel mailing list