From 9117748cff55d649c076f5b9fba6bf3647448273 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Sun, 6 Sep 2015 19:10:53 +0200 Subject: [PATCH] avutil/opt: add AV_OPT_TYPE_BOOL --- libavutil/opt.c | 64 ++++++++++++++++++++++++++++++++++++++++++++- libavutil/opt.h | 1 + libavutil/version.h | 2 +- tests/ref/fate/opt | 22 ++++++++++++++-- 4 files changed, 85 insertions(+), 4 deletions(-) diff --git a/libavutil/opt.c b/libavutil/opt.c index 4030fa8ed5..7a0911b621 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,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 ", ""); break; + case AV_OPT_TYPE_BOOL: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + 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; diff --git a/libavutil/opt.h b/libavutil/opt.h index 9443bf3d6c..d6d8df36ff 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/libavutil/version.h b/libavutil/version.h index ccb571edc0..c34725ef07 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -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, \ diff --git a/tests/ref/fate/opt b/tests/ref/fate/opt index 3aa7423efd..307da374ea 100644 --- a/tests/ref/fate/opt +++ b/tests/ref/fate/opt @@ -40,6 +40,9 @@ TestContext AVOptions: -num64 E....... set num 64bit (from 0 to 100) (default 1) -flt E....... set float (from 0 to 100) (default 0.333333) -dbl E....... set double (from 0 to 100) (default 0.333333) + -bool1 E....... set boolean value (default auto) + -bool2 E....... set boolean value (default true) + -bool3 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 ''