[FFmpeg-devel] [PATCH 1/8] avutil/opt: add AV_OPT_TYPE_BOOL

Hendrik Leppkes h.leppkes at gmail.com
Mon Sep 7 10:48:34 CEST 2015


On Sun, Sep 6, 2015 at 7:43 PM, Clément Bœsch <u at pkh.me> wrote:
> TODO: bump lavu minor
> ---
>  libavutil/opt.c    | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  libavutil/opt.h    |  1 +
>  tests/ref/fate/opt | 22 +++++++++++++++--
>  3 files changed, 89 insertions(+), 3 deletions(-)
>
> diff --git a/libavutil/opt.c b/libavutil/opt.c
> index 4030fa8..9912d9e 100644
> --- a/libavutil/opt.c
> +++ b/libavutil/opt.c
> @@ -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,49 @@ 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 parse_bool(void *log_ctx, const char *val, int *dst)
> +{
> +    int i;
> +    static const char * const str_y[] = {"1", "true",  "y", "yes", "enable",  "enabled"};
> +    static const char * const str_n[] = {"0", "false", "n", "no",  "disable", "disabled"};

While we're adding fancy aliases, on/off? :)

> +
> +    if (!strcmp(val, "auto")) {
> +        *dst = -1;
> +        return 0;
> +    }
> +
> +    for (i = 0; i < FF_ARRAY_ELEMS(str_y); i++) {
> +        if (!strcmp(val, str_y[i])) {
> +            *dst = 1;
> +            return 0;
> +        }
> +    }
> +
> +    for (i = 0; i < FF_ARRAY_ELEMS(str_n); i++) {
> +        if (!strcmp(val, str_n[i])) {
> +            *dst = 0;
> +            return 0;
> +        }
> +    }
> +
> +    av_log(log_ctx, AV_LOG_ERROR, "Unable to parse option value \"%s\" as boolean\n", val);
> +    return AVERROR(EINVAL);
> +}
> +
> +static int set_string_bool(void *obj, const AVOption *o, const char *val, int *dst)
> +{
> +    if (!val)
> +        return 0;
> +    return parse_bool(obj, val, dst);
> +}
> +
>  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 +405,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 +413,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 +659,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 +999,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 +1047,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 +1125,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 +1484,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 +1602,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 +1686,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 +1850,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 +1884,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 +2052,8 @@ int main(void)
>              "dbl=2.2",
>              "dbl=-1",
>              "dbl=101",
> +            "bool1=true",
> +            "bool2=auto",
>          };
>
>          test_ctx.class = &test_class;
> diff --git a/libavutil/opt.h b/libavutil/opt.h
> index 9443bf3..d6d8df3 100644
> --- a/libavutil/opt.h
> +++ b/libavutil/opt.h
> @@ -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'),
>  };
>
>  /**
> diff --git a/tests/ref/fate/opt b/tests/ref/fate/opt
> index 3aa7423..307da37 100644
> --- a/tests/ref/fate/opt
> +++ b/tests/ref/fate/opt
> @@ -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 ''
> --
> 2.5.1
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


More information about the ffmpeg-devel mailing list