avutil/opt: add AV_OPT_TYPE_BOOL
authorClément Bœsch <u@pkh.me>
Sun, 6 Sep 2015 17:10:53 +0000 (19:10 +0200)
committerClément Bœsch <u@pkh.me>
Tue, 8 Sep 2015 20:39:20 +0000 (22:39 +0200)
libavutil/opt.c
libavutil/opt.h
libavutil/version.h
tests/ref/fate/opt

index 4030fa8..7a0911b 100644 (file)
@@ -60,6 +60,7 @@ static int read_number(const AVOption *o, const void *dst, double *num, int *den
     case AV_OPT_TYPE_FLAGS:     *intnum = *(unsigned int*)dst;return 0;
     case AV_OPT_TYPE_PIXEL_FMT: *intnum = *(enum AVPixelFormat *)dst;return 0;
     case AV_OPT_TYPE_SAMPLE_FMT:*intnum = *(enum AVSampleFormat*)dst;return 0;
+    case AV_OPT_TYPE_BOOL:
     case AV_OPT_TYPE_INT:       *intnum = *(int         *)dst;return 0;
     case AV_OPT_TYPE_CHANNEL_LAYOUT:
     case AV_OPT_TYPE_DURATION:
@@ -96,6 +97,7 @@ static int write_number(void *obj, const AVOption *o, void *dst, double num, int
     switch (o->type) {
     case AV_OPT_TYPE_PIXEL_FMT: *(enum AVPixelFormat *)dst = llrint(num/den) * intnum; break;
     case AV_OPT_TYPE_SAMPLE_FMT:*(enum AVSampleFormat*)dst = llrint(num/den) * intnum; break;
+    case AV_OPT_TYPE_BOOL:
     case AV_OPT_TYPE_FLAGS:
     case AV_OPT_TYPE_INT:   *(int       *)dst= llrint(num/den)*intnum; break;
     case AV_OPT_TYPE_DURATION:
@@ -297,6 +299,44 @@ static int set_string_color(void *obj, const AVOption *o, const char *val, uint8
     return 0;
 }
 
+static const char *get_bool_name(int val)
+{
+    if (val < 0)
+        return "auto";
+    return val ? "true" : "false";
+}
+
+static int set_string_bool(void *obj, const AVOption *o, const char *val, int *dst)
+{
+    int n;
+
+    if (!val)
+        return 0;
+
+    if (!strcmp(val, "auto")) {
+        n = -1;
+    } else if (av_match_name(val, "true,y,yes,enable,enabled,on")) {
+        n = 1;
+    } else if (av_match_name(val, "false,n,no,disable,disabled,off")) {
+        n = 0;
+    } else {
+        char *end = NULL;
+        n = strtol(val, &end, 10);
+        if (val + strlen(val) != end)
+            goto fail;
+    }
+
+    if (n < o->min || n > o->max)
+        goto fail;
+
+    *dst = n;
+    return 0;
+
+fail:
+    av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as boolean\n", val);
+    return AVERROR(EINVAL);
+}
+
 static int set_string_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst,
                           int fmt_nb, int ((*get_fmt)(const char *)), const char *desc)
 {
@@ -360,7 +400,7 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
                  o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT &&
                  o->type != AV_OPT_TYPE_IMAGE_SIZE && o->type != AV_OPT_TYPE_VIDEO_RATE &&
                  o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR &&
-                 o->type != AV_OPT_TYPE_CHANNEL_LAYOUT))
+                 o->type != AV_OPT_TYPE_CHANNEL_LAYOUT && o->type != AV_OPT_TYPE_BOOL))
         return AVERROR(EINVAL);
 
     if (o->flags & AV_OPT_FLAG_READONLY)
@@ -368,6 +408,7 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
 
     dst = ((uint8_t*)target_obj) + o->offset;
     switch (o->type) {
+    case AV_OPT_TYPE_BOOL:     return set_string_bool(obj, o, val, dst);
     case AV_OPT_TYPE_STRING:   return set_string(obj, o, val, dst);
     case AV_OPT_TYPE_BINARY:   return set_string_binary(obj, o, val, dst);
     case AV_OPT_TYPE_FLAGS:
@@ -613,6 +654,9 @@ int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
 
     buf[0] = 0;
     switch (o->type) {
+    case AV_OPT_TYPE_BOOL:
+        ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(get_bool_name(*(int *)dst), "invalid"));
+        break;
     case AV_OPT_TYPE_FLAGS:     ret = snprintf(buf, sizeof(buf), "0x%08X",  *(int    *)dst);break;
     case AV_OPT_TYPE_INT:       ret = snprintf(buf, sizeof(buf), "%d" ,     *(int    *)dst);break;
     case AV_OPT_TYPE_INT64:     ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t*)dst);break;
@@ -950,6 +994,9 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
             case AV_OPT_TYPE_CHANNEL_LAYOUT:
                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<channel_layout>");
                 break;
+            case AV_OPT_TYPE_BOOL:
+                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<boolean>");
+                break;
             case AV_OPT_TYPE_CONST:
             default:
                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
@@ -995,6 +1042,9 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
                   !opt->default_val.str)) {
             av_log(av_log_obj, AV_LOG_INFO, " (default ");
             switch (opt->type) {
+            case AV_OPT_TYPE_BOOL:
+                av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(get_bool_name(opt->default_val.i64), "invalid"));
+                break;
             case AV_OPT_TYPE_FLAGS:
                 av_log(av_log_obj, AV_LOG_INFO, "%"PRIX64, opt->default_val.i64);
                 break;
@@ -1070,6 +1120,7 @@ void av_opt_set_defaults2(void *s, int mask, int flags)
             case AV_OPT_TYPE_CONST:
                 /* Nothing to be done here */
             break;
+            case AV_OPT_TYPE_BOOL:
             case AV_OPT_TYPE_FLAGS:
             case AV_OPT_TYPE_INT:
             case AV_OPT_TYPE_INT64:
@@ -1428,6 +1479,7 @@ void *av_opt_ptr(const AVClass *class, void *obj, const char *name)
 static int opt_size(enum AVOptionType type)
 {
     switch(type) {
+    case AV_OPT_TYPE_BOOL:
     case AV_OPT_TYPE_INT:
     case AV_OPT_TYPE_FLAGS:     return sizeof(int);
     case AV_OPT_TYPE_DURATION:
@@ -1545,6 +1597,7 @@ int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const ch
     range->value_max = field->max;
 
     switch (field->type) {
+    case AV_OPT_TYPE_BOOL:
     case AV_OPT_TYPE_INT:
     case AV_OPT_TYPE_INT64:
     case AV_OPT_TYPE_PIXEL_FMT:
@@ -1628,6 +1681,7 @@ int av_opt_is_set_to_default(void *obj, const AVOption *o)
     switch (o->type) {
     case AV_OPT_TYPE_CONST:
         return 1;
+    case AV_OPT_TYPE_BOOL:
     case AV_OPT_TYPE_FLAGS:
     case AV_OPT_TYPE_PIXEL_FMT:
     case AV_OPT_TYPE_SAMPLE_FMT:
@@ -1791,6 +1845,9 @@ typedef struct TestContext
     float flt;
     double dbl;
     char *escape;
+    int bool1;
+    int bool2;
+    int bool3;
 } TestContext;
 
 #define OFFSET(x) offsetof(TestContext, x)
@@ -1822,6 +1879,9 @@ static const AVOption test_options[]= {
 {"num64",    "set num 64bit",  OFFSET(num64),    AV_OPT_TYPE_INT64,    {.i64 = 1},        0,        100, 1 },
 {"flt",      "set float",      OFFSET(flt),      AV_OPT_TYPE_FLOAT,    {.dbl = 1.0/3},    0,        100, 1},
 {"dbl",      "set double",     OFFSET(dbl),      AV_OPT_TYPE_DOUBLE,   {.dbl = 1.0/3},    0,        100, 1 },
+{"bool1", "set boolean value",  OFFSET(bool1),   AV_OPT_TYPE_BOOL,     {.i64 = -1},      -1,        1, 1 },
+{"bool2", "set boolean value",  OFFSET(bool2),   AV_OPT_TYPE_BOOL,     {.i64 = 1},       -1,        1, 1 },
+{"bool3", "set boolean value",  OFFSET(bool3),   AV_OPT_TYPE_BOOL,     {.i64 = 0},        0,        1, 1 },
 {NULL},
 };
 
@@ -1987,6 +2047,8 @@ int main(void)
             "dbl=2.2",
             "dbl=-1",
             "dbl=101",
+            "bool1=true",
+            "bool2=auto",
         };
 
         test_ctx.class = &test_class;
index 9443bf3..d6d8df3 100644 (file)
@@ -236,6 +236,7 @@ enum AVOptionType{
     AV_OPT_TYPE_DURATION   = MKBETAG('D','U','R',' '),
     AV_OPT_TYPE_COLOR      = MKBETAG('C','O','L','R'),
     AV_OPT_TYPE_CHANNEL_LAYOUT = MKBETAG('C','H','L','A'),
+    AV_OPT_TYPE_BOOL           = MKBETAG('B','O','O','L'),
 };
 
 /**
index ccb571e..c34725e 100644 (file)
@@ -56,7 +56,7 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  55
-#define LIBAVUTIL_VERSION_MINOR   0
+#define LIBAVUTIL_VERSION_MINOR   1
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
index 3aa7423..307da37 100644 (file)
@@ -40,6 +40,9 @@ TestContext AVOptions:
   -num64             <int64>      E....... set num 64bit (from 0 to 100) (default 1)
   -flt               <float>      E....... set float (from 0 to 100) (default 0.333333)
   -dbl               <double>     E....... set double (from 0 to 100) (default 0.333333)
+  -bool1             <boolean>    E....... set boolean value (default auto)
+  -bool2             <boolean>    E....... set boolean value (default true)
+  -bool3             <boolean>    E....... set boolean value (default false)
 
 Testing av_opt_is_set_to_default()
 name:       num default:1 error:
@@ -64,6 +67,9 @@ name:      bin2 default:1 error:
 name:     num64 default:0 error:
 name:       flt default:0 error:
 name:       dbl default:0 error:
+name:     bool1 default:0 error:
+name:     bool2 default:0 error:
+name:     bool3 default:1 error:
 name:       num default:1 error:
 name:    toggle default:1 error:
 name:  rational default:1 error:
@@ -86,9 +92,12 @@ name:      bin2 default:1 error:
 name:     num64 default:1 error:
 name:       flt default:1 error:
 name:       dbl default:1 error:
+name:     bool1 default:1 error:
+name:     bool2 default:1 error:
+name:     bool3 default:1 error:
 
 Test av_opt_serialize()
-num=0,toggle=1,rational=1/1,string=default,escape=\\\=\,,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0:00:00.001000,color=0xffc0cbff,cl=0x137,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333
+num=0,toggle=1,rational=1/1,string=default,escape=\\\=\,,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0:00:00.001000,color=0xffc0cbff,cl=0x137,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333,bool1=auto,bool2=true,bool3=false
 Setting entry with key 'num' to value '0'
 Setting entry with key 'toggle' to value '1'
 Setting entry with key 'rational' to value '1/1'
@@ -108,7 +117,10 @@ Setting entry with key 'bin2' to value ''
 Setting entry with key 'num64' to value '1'
 Setting entry with key 'flt' to value '0.333333'
 Setting entry with key 'dbl' to value '0.333333'
-num=0,toggle=1,rational=1/1,string=default,escape=\\\=\,,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0:00:00.001000,color=0xffc0cbff,cl=0x137,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333
+Setting entry with key 'bool1' to value 'auto'
+Setting entry with key 'bool2' to value 'true'
+Setting entry with key 'bool3' to value 'false'
+num=0,toggle=1,rational=1/1,string=default,escape=\\\=\,,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0:00:00.001000,color=0xffc0cbff,cl=0x137,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333,bool1=auto,bool2=true,bool3=false
 
 Testing av_set_options_string()
 Setting options string ''
@@ -323,6 +335,12 @@ Setting options string 'dbl=101'
 Setting entry with key 'dbl' to value '101'
 Value 101.000000 for parameter 'dbl' out of range [0 - 100]
 Error 'dbl=101'
+Setting options string 'bool1=true'
+Setting entry with key 'bool1' to value 'true'
+OK    'bool1=true'
+Setting options string 'bool2=auto'
+Setting entry with key 'bool2' to value 'auto'
+OK    'bool2=auto'
 
 Testing av_opt_set_from_string()
 Setting options string ''