diff mbox series

[FFmpeg-devel,2/2] avutil/opt: add an unsigned option type

Message ID 20240227135947.503-2-jamrial@gmail.com
State New
Headers show
Series [FFmpeg-devel,1/2] avutil/tests/opt: test negative values for INT and INT64 types | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

James Almer Feb. 27, 2024, 1:59 p.m. UTC
Signed-off-by: James Almer <jamrial@gmail.com>
---
 libavutil/opt.c       | 20 ++++++++++++++++++++
 libavutil/opt.h       |  1 +
 libavutil/tests/opt.c |  9 +++++++++
 tests/ref/fate/opt    | 32 ++++++++++++++++++++++++++++++--
 4 files changed, 60 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/libavutil/opt.c b/libavutil/opt.c
index 0681b19896..45d6aa5849 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -72,6 +72,9 @@  static int read_number(const AVOption *o, const void *dst, double *num, int *den
     case AV_OPT_TYPE_INT:
         *intnum = *(int *)dst;
         return 0;
+    case AV_OPT_TYPE_UINT:
+        *intnum = *(unsigned *)dst;
+        return 0;
 #if FF_API_OLD_CHANNEL_LAYOUT
 FF_DISABLE_DEPRECATION_WARNINGS
     case AV_OPT_TYPE_CHANNEL_LAYOUT:
@@ -130,6 +133,9 @@  static int write_number(void *obj, const AVOption *o, void *dst, double num, int
     case AV_OPT_TYPE_INT:
         *(int *)dst = llrint(num / den) * intnum;
         break;
+    case AV_OPT_TYPE_UINT:
+        *(unsigned *)dst = llrint(num / den) * intnum;
+        break;
     case AV_OPT_TYPE_DURATION:
 #if FF_API_OLD_CHANNEL_LAYOUT
 FF_DISABLE_DEPRECATION_WARNINGS
@@ -231,6 +237,7 @@  static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **d
                               opt->type == AV_OPT_TYPE_UINT64 || \
                               opt->type == AV_OPT_TYPE_CONST || \
                               opt->type == AV_OPT_TYPE_FLAGS || \
+                              opt->type == AV_OPT_TYPE_UINT  || \
                               opt->type == AV_OPT_TYPE_INT)     \
                              ? opt->default_val.i64             \
                              : opt->default_val.dbl)
@@ -529,6 +536,7 @@  FF_ENABLE_DEPRECATION_WARNINGS
         return set_string_binary(obj, o, val, dst);
     case AV_OPT_TYPE_FLAGS:
     case AV_OPT_TYPE_INT:
+    case AV_OPT_TYPE_UINT:
     case AV_OPT_TYPE_INT64:
     case AV_OPT_TYPE_UINT64:
     case AV_OPT_TYPE_FLOAT:
@@ -871,6 +879,9 @@  int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
     case AV_OPT_TYPE_INT:
         ret = snprintf(buf, sizeof(buf), "%d", *(int *)dst);
         break;
+    case AV_OPT_TYPE_UINT:
+        ret = snprintf(buf, sizeof(buf), "%u", *(unsigned int *)dst);
+        break;
     case AV_OPT_TYPE_INT64:
         ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t *)dst);
         break;
@@ -1276,6 +1287,9 @@  static void opt_list(void *obj, void *av_log_obj, const char *unit,
             case AV_OPT_TYPE_INT:
                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int>");
                 break;
+            case AV_OPT_TYPE_UINT:
+                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<unsigned>");
+                break;
             case AV_OPT_TYPE_INT64:
                 av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int64>");
                 break;
@@ -1358,6 +1372,7 @@  FF_ENABLE_DEPRECATION_WARNINGS
         if (av_opt_query_ranges(&r, obj, opt->name, AV_OPT_SEARCH_FAKE_OBJ) >= 0) {
             switch (opt->type) {
             case AV_OPT_TYPE_INT:
+            case AV_OPT_TYPE_UINT:
             case AV_OPT_TYPE_INT64:
             case AV_OPT_TYPE_UINT64:
             case AV_OPT_TYPE_DOUBLE:
@@ -1405,6 +1420,7 @@  FF_ENABLE_DEPRECATION_WARNINGS
                 av_log(av_log_obj, AV_LOG_INFO, "%s", buf);
                 break;
             }
+            case AV_OPT_TYPE_UINT:
             case AV_OPT_TYPE_INT:
             case AV_OPT_TYPE_UINT64:
             case AV_OPT_TYPE_INT64: {
@@ -1490,6 +1506,7 @@  void av_opt_set_defaults2(void *s, int mask, int flags)
             case AV_OPT_TYPE_BOOL:
             case AV_OPT_TYPE_FLAGS:
             case AV_OPT_TYPE_INT:
+            case AV_OPT_TYPE_UINT:
             case AV_OPT_TYPE_INT64:
             case AV_OPT_TYPE_UINT64:
             case AV_OPT_TYPE_DURATION:
@@ -1858,6 +1875,7 @@  static int opt_size(enum AVOptionType type)
     switch(type) {
     case AV_OPT_TYPE_BOOL:
     case AV_OPT_TYPE_INT:
+    case AV_OPT_TYPE_UINT:
     case AV_OPT_TYPE_FLAGS:
         return sizeof(int);
     case AV_OPT_TYPE_DURATION:
@@ -1997,6 +2015,7 @@  int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const ch
     switch (field->type) {
     case AV_OPT_TYPE_BOOL:
     case AV_OPT_TYPE_INT:
+    case AV_OPT_TYPE_UINT:
     case AV_OPT_TYPE_INT64:
     case AV_OPT_TYPE_UINT64:
     case AV_OPT_TYPE_PIXEL_FMT:
@@ -2089,6 +2108,7 @@  int av_opt_is_set_to_default(void *obj, const AVOption *o)
     case AV_OPT_TYPE_PIXEL_FMT:
     case AV_OPT_TYPE_SAMPLE_FMT:
     case AV_OPT_TYPE_INT:
+    case AV_OPT_TYPE_UINT:
 #if FF_API_OLD_CHANNEL_LAYOUT
 FF_DISABLE_DEPRECATION_WARNINGS
     case AV_OPT_TYPE_CHANNEL_LAYOUT:
diff --git a/libavutil/opt.h b/libavutil/opt.h
index 461b5d3b6b..9fec1b0509 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -243,6 +243,7 @@  enum AVOptionType{
 #endif
     AV_OPT_TYPE_BOOL,
     AV_OPT_TYPE_CHLAYOUT,
+    AV_OPT_TYPE_UINT,
 };
 
 /**
diff --git a/libavutil/tests/opt.c b/libavutil/tests/opt.c
index a914d0359a..747042896f 100644
--- a/libavutil/tests/opt.c
+++ b/libavutil/tests/opt.c
@@ -31,6 +31,7 @@ 
 typedef struct TestContext {
     const AVClass *class;
     int num;
+    unsigned unum;
     int toggle;
     char *string;
     int flags;
@@ -67,6 +68,7 @@  typedef struct TestContext {
 
 static const AVOption test_options[]= {
     {"num",        "set num",            OFFSET(num),            AV_OPT_TYPE_INT,            { .i64 = 0 },                     -1,       100, 1 },
+    {"unum",       "set unum",           OFFSET(unum),           AV_OPT_TYPE_UINT,           { .i64 = 1 },                      0, INT_MAX + 1U, 1 },
     {"toggle",     "set toggle",         OFFSET(toggle),         AV_OPT_TYPE_INT,            { .i64 = 1 },                      0,         1, 1 },
     {"rational",   "set rational",       OFFSET(rational),       AV_OPT_TYPE_RATIONAL,       { .dbl = 1 },                      0,        10, 1 },
     {"string",     "set string",         OFFSET(string),         AV_OPT_TYPE_STRING,         { .str = "default" },       CHAR_MIN,  CHAR_MAX, 1 },
@@ -127,6 +129,7 @@  int main(void)
         av_opt_set_defaults(&test_ctx);
 
         printf("num=%d\n", test_ctx.num);
+        printf("unum=%u\n", test_ctx.unum);
         printf("toggle=%d\n", test_ctx.toggle);
         printf("string=%s\n", test_ctx.string);
         printf("escape=%s\n", test_ctx.escape);
@@ -291,6 +294,12 @@  int main(void)
             "num=-1",
             "num=-2",
             "num=101",
+            "unum=bogus",
+            "unum=44",
+            "unum=44.4",
+            "unum=-1",
+            "unum=2147483648",
+            "unum=2147483649",
             "num64=bogus",
             "num64=44",
             "num64=44.4",
diff --git a/tests/ref/fate/opt b/tests/ref/fate/opt
index 2da155aa2b..c753142992 100644
--- a/tests/ref/fate/opt
+++ b/tests/ref/fate/opt
@@ -1,5 +1,6 @@ 
 Testing default values
 num=0
+unum=1
 toggle=1
 string=default
 escape=\=,
@@ -19,6 +20,7 @@  flt=0.333333
 dbl=0.333333
 TestContext AVOptions:
   -num               <int>        E.......... set num (from -1 to 100) (default 0)
+  -unum              <unsigned>   E.......... set unum (from 0 to 2.14748e+09) (default 1)
   -toggle            <int>        E.......... set toggle (from 0 to 1) (default 1)
   -rational          <rational>   E.......... set rational (from 0 to 10) (default 1/1)
   -string            <string>     E.......... set string (default "default")
@@ -48,6 +50,7 @@  TestContext AVOptions:
 
 Testing av_opt_is_set_to_default()
 name:       num default:1 error:
+name:      unum default:0 error:
 name:    toggle default:0 error:
 name:  rational default:0 error:
 name:    string default:0 error:
@@ -75,6 +78,7 @@  name:     bool3 default:1 error:
 name:     dict1 default:1 error:
 name:     dict2 default:0 error:
 name:       num default:1 error:
+name:      unum default:1 error:
 name:    toggle default:1 error:
 name:  rational default:1 error:
 name:    string default:1 error:
@@ -104,6 +108,7 @@  name:     dict2 default:1 error:
 
 Testing av_opt_get/av_opt_set()
 name: num         get: 0                set: OK               get: 0                OK
+name: unum        get: 1                set: OK               get: 1                OK
 name: toggle      get: 1                set: OK               get: 1                OK
 name: rational    get: 1/1              set: OK               get: 1/1              OK
 name: string      get: default          set: OK               get: default          OK
@@ -129,8 +134,9 @@  name: dict1       get:                  set: OK               get:
 name: dict2       get: happy=\:-)       set: OK               get: happy=\:-)       OK
 
 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.001,color=0xffc0cbff,cl=hexagonal,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333,bool1=auto,bool2=true,bool3=false,dict1=,dict2=happy\=\\:-)
+num=0,unum=1,toggle=1,rational=1/1,string=default,escape=\\\=\,,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0.001,color=0xffc0cbff,cl=hexagonal,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333,bool1=auto,bool2=true,bool3=false,dict1=,dict2=happy\=\\:-)
 Setting entry with key 'num' to value '0'
+Setting entry with key 'unum' to value '1'
 Setting entry with key 'toggle' to value '1'
 Setting entry with key 'rational' to value '1/1'
 Setting entry with key 'string' to value 'default'
@@ -154,7 +160,7 @@  Setting entry with key 'bool2' to value 'true'
 Setting entry with key 'bool3' to value 'false'
 Setting entry with key 'dict1' to value ''
 Setting entry with key 'dict2' to value 'happy=\:-)'
-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.001,color=0xffc0cbff,cl=hexagonal,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333,bool1=auto,bool2=true,bool3=false,dict1=,dict2=happy\=\\:-)
+num=0,unum=1,toggle=1,rational=1/1,string=default,escape=\\\=\,,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0.001,color=0xffc0cbff,cl=hexagonal,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333,bool1=auto,bool2=true,bool3=false,dict1=,dict2=happy\=\\:-)
 
 Testing av_set_options_string()
 Setting options string ''
@@ -334,6 +340,28 @@  Setting options string 'num=101'
 Setting entry with key 'num' to value '101'
 Value 101.000000 for parameter 'num' out of range [-1 - 100]
 Error 'num=101'
+Setting options string 'unum=bogus'
+Setting entry with key 'unum' to value 'bogus'
+Undefined constant or missing '(' in 'bogus'
+Unable to parse option value "bogus"
+Error 'unum=bogus'
+Setting options string 'unum=44'
+Setting entry with key 'unum' to value '44'
+OK    'unum=44'
+Setting options string 'unum=44.4'
+Setting entry with key 'unum' to value '44.4'
+OK    'unum=44.4'
+Setting options string 'unum=-1'
+Setting entry with key 'unum' to value '-1'
+Value -1.000000 for parameter 'unum' out of range [0 - 2.14748e+09]
+Error 'unum=-1'
+Setting options string 'unum=2147483648'
+Setting entry with key 'unum' to value '2147483648'
+OK    'unum=2147483648'
+Setting options string 'unum=2147483649'
+Setting entry with key 'unum' to value '2147483649'
+Value 2147483649.000000 for parameter 'unum' out of range [0 - 2.14748e+09]
+Error 'unum=2147483649'
 Setting options string 'num64=bogus'
 Setting entry with key 'num64' to value 'bogus'
 Undefined constant or missing '(' in 'bogus'