From f7813a5324be39d13ab536c245d15dfc602a7849 Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Sun, 29 Dec 2013 12:19:38 +0000 Subject: basic type mechanism working --- ffmpeg/libavutil/opt.c | 356 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 277 insertions(+), 79 deletions(-) (limited to 'ffmpeg/libavutil/opt.c') diff --git a/ffmpeg/libavutil/opt.c b/ffmpeg/libavutil/opt.c index a2cdcb4..07864f2 100644 --- a/ffmpeg/libavutil/opt.c +++ b/ffmpeg/libavutil/opt.c @@ -27,6 +27,7 @@ #include "avutil.h" #include "avstring.h" +#include "channel_layout.h" #include "common.h" #include "opt.h" #include "eval.h" @@ -63,7 +64,7 @@ const AVOption *av_next_option(void *obj, const AVOption *last) const AVOption *av_opt_next(void *obj, const AVOption *last) { AVClass *class = *(AVClass**)obj; - if (!last && class->option && class->option[0].name) + if (!last && class && class->option && class->option[0].name) return class->option; if (last && last[1].name) return ++last; @@ -77,6 +78,7 @@ static int read_number(const AVOption *o, void *dst, double *num, int *den, int6 case AV_OPT_TYPE_PIXEL_FMT: case AV_OPT_TYPE_SAMPLE_FMT: case AV_OPT_TYPE_INT: *intnum = *(int *)dst;return 0; + case AV_OPT_TYPE_CHANNEL_LAYOUT: case AV_OPT_TYPE_DURATION: case AV_OPT_TYPE_INT64: *intnum = *(int64_t *)dst;return 0; case AV_OPT_TYPE_FLOAT: *num = *(float *)dst;return 0; @@ -91,11 +93,21 @@ static int read_number(const AVOption *o, void *dst, double *num, int *den, int6 static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum) { - if (o->max*den < num*intnum || o->min*den > num*intnum) { + if (o->type != AV_OPT_TYPE_FLAGS && + (o->max * den < num * intnum || o->min * den > num * intnum)) { av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n", num*intnum/den, o->name, o->min, o->max); return AVERROR(ERANGE); } + if (o->type == AV_OPT_TYPE_FLAGS) { + double d = num*intnum/den; + if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (llrint(d*256) & 255)) { + av_log(obj, AV_LOG_ERROR, + "Value %f for parameter '%s' is not a valid set of 32bit integer flags\n", + num*intnum/den, o->name); + return AVERROR(ERANGE); + } + } switch (o->type) { case AV_OPT_TYPE_FLAGS: @@ -103,6 +115,7 @@ static int write_number(void *obj, const AVOption *o, void *dst, double num, int case AV_OPT_TYPE_SAMPLE_FMT: case AV_OPT_TYPE_INT: *(int *)dst= llrint(num/den)*intnum; break; case AV_OPT_TYPE_DURATION: + case AV_OPT_TYPE_CHANNEL_LAYOUT: case AV_OPT_TYPE_INT64: *(int64_t *)dst= llrint(num/den)*intnum; break; case AV_OPT_TYPE_FLOAT: *(float *)dst= num*intnum/den; break; case AV_OPT_TYPE_DOUBLE:*(double *)dst= num*intnum/den; break; @@ -239,6 +252,95 @@ static int set_string_number(void *obj, void *target_obj, const AVOption *o, con return 0; } +static int set_string_image_size(void *obj, const AVOption *o, const char *val, int *dst) +{ + int ret; + + if (!val || !strcmp(val, "none")) { + dst[0] = + dst[1] = 0; + return 0; + } + ret = av_parse_video_size(dst, dst + 1, val); + if (ret < 0) + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val); + return ret; +} + +static int set_string_video_rate(void *obj, const AVOption *o, const char *val, AVRational *dst) +{ + int ret; + if (!val) { + ret = AVERROR(EINVAL); + } else { + ret = av_parse_video_rate(dst, val); + } + if (ret < 0) + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val); + return ret; +} + +static int set_string_color(void *obj, const AVOption *o, const char *val, uint8_t *dst) +{ + int ret; + + if (!val) { + return 0; + } else { + ret = av_parse_color(dst, val, -1, obj); + if (ret < 0) + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as color\n", val); + return ret; + } + return 0; +} + +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) +{ + int fmt, min, max; + + if (!val || !strcmp(val, "none")) { + fmt = -1; + } else { + fmt = get_fmt(val); + if (fmt == -1) { + char *tail; + fmt = strtol(val, &tail, 0); + if (*tail || (unsigned)fmt >= fmt_nb) { + av_log(obj, AV_LOG_ERROR, + "Unable to parse option value \"%s\" as %s\n", val, desc); + return AVERROR(EINVAL); + } + } + } + + min = FFMAX(o->min, -1); + max = FFMIN(o->max, fmt_nb-1); + + if (fmt < min || fmt > max) { + av_log(obj, AV_LOG_ERROR, + "Value %d for parameter '%s' out of %s format range [%d - %d]\n", + fmt, o->name, desc, min, max); + return AVERROR(ERANGE); + } + + *(int *)dst = fmt; + return 0; +} + +static int set_string_pixel_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst) +{ + return set_string_fmt(obj, o, val, dst, + AV_PIX_FMT_NB, av_get_pix_fmt, "pixel format"); +} + +static int set_string_sample_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst) +{ + return set_string_fmt(obj, o, val, dst, + AV_SAMPLE_FMT_NB, av_get_sample_fmt, "sample format"); +} + #if FF_API_OLD_AVOPTIONS int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out) { @@ -251,7 +353,7 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons int av_opt_set(void *obj, const char *name, const char *val, int search_flags) { - int ret; + int ret = 0; void *dst, *target_obj; const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); if (!o || !target_obj) @@ -259,7 +361,8 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags) if (!val && (o->type != AV_OPT_TYPE_STRING && 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_DURATION && o->type != AV_OPT_TYPE_COLOR && + o->type != AV_OPT_TYPE_CHANNEL_LAYOUT)) return AVERROR(EINVAL); dst = ((uint8_t*)target_obj) + o->offset; @@ -272,56 +375,10 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags) case AV_OPT_TYPE_FLOAT: case AV_OPT_TYPE_DOUBLE: case AV_OPT_TYPE_RATIONAL: return set_string_number(obj, target_obj, o, val, dst); - case AV_OPT_TYPE_IMAGE_SIZE: - if (!val || !strcmp(val, "none")) { - *(int *)dst = *((int *)dst + 1) = 0; - return 0; - } - ret = av_parse_video_size(dst, ((int *)dst) + 1, val); - if (ret < 0) - av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val); - return ret; - case AV_OPT_TYPE_VIDEO_RATE: - if (!val) { - ret = AVERROR(EINVAL); - } else { - ret = av_parse_video_rate(dst, val); - } - if (ret < 0) - av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val); - return ret; - case AV_OPT_TYPE_PIXEL_FMT: - if (!val || !strcmp(val, "none")) { - ret = AV_PIX_FMT_NONE; - } else { - ret = av_get_pix_fmt(val); - if (ret == AV_PIX_FMT_NONE) { - char *tail; - ret = strtol(val, &tail, 0); - if (*tail || (unsigned)ret >= AV_PIX_FMT_NB) { - av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as pixel format\n", val); - return AVERROR(EINVAL); - } - } - } - *(enum AVPixelFormat *)dst = ret; - return 0; - case AV_OPT_TYPE_SAMPLE_FMT: - if (!val || !strcmp(val, "none")) { - ret = AV_SAMPLE_FMT_NONE; - } else { - ret = av_get_sample_fmt(val); - if (ret == AV_SAMPLE_FMT_NONE) { - char *tail; - ret = strtol(val, &tail, 0); - if (*tail || (unsigned)ret >= AV_SAMPLE_FMT_NB) { - av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as sample format\n", val); - return AVERROR(EINVAL); - } - } - } - *(enum AVSampleFormat *)dst = ret; - return 0; + case AV_OPT_TYPE_IMAGE_SIZE: return set_string_image_size(obj, o, val, dst); + case AV_OPT_TYPE_VIDEO_RATE: return set_string_video_rate(obj, o, val, dst); + case AV_OPT_TYPE_PIXEL_FMT: return set_string_pixel_fmt(obj, o, val, dst); + case AV_OPT_TYPE_SAMPLE_FMT: return set_string_sample_fmt(obj, o, val, dst); case AV_OPT_TYPE_DURATION: if (!val) { *(int64_t *)dst = 0; @@ -331,6 +388,25 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags) av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as duration\n", val); return ret; } + break; + case AV_OPT_TYPE_COLOR: return set_string_color(obj, o, val, dst); + case AV_OPT_TYPE_CHANNEL_LAYOUT: + if (!val || !strcmp(val, "none")) { + *(int64_t *)dst = 0; + } else { +#if FF_API_GET_CHANNEL_LAYOUT_COMPAT + int64_t cl = ff_get_channel_layout(val, 0); +#else + int64_t cl = av_get_channel_layout(val); +#endif + if (!cl) { + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val); + ret = AVERROR(EINVAL); + } + *(int64_t *)dst = cl; + return ret; + } + break; } av_log(obj, AV_LOG_ERROR, "Invalid option type.\n"); @@ -420,8 +496,8 @@ int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int if (o->type != AV_OPT_TYPE_BINARY) return AVERROR(EINVAL); - ptr = av_malloc(len); - if (!ptr) + ptr = len ? av_malloc(len) : NULL; + if (len && !ptr) return AVERROR(ENOMEM); dst = (uint8_t **)(((uint8_t *)target_obj) + o->offset); @@ -430,7 +506,8 @@ int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int av_free(*dst); *dst = ptr; *lendst = len; - memcpy(ptr, val, len); + if (len) + memcpy(ptr, val, len); return 0; } @@ -491,15 +568,15 @@ static int set_format(void *obj, const char *name, int fmt, int search_flags, return AVERROR(EINVAL); } -#if LIBAVUTIL_VERSION_MAJOR < 53 +#if LIBAVUTIL_VERSION_MAJOR < 54 if (class->version && class->version < AV_VERSION_INT(52, 11, 100)) { min = -1; max = nb_fmts-1; } else #endif { - min = FFMIN(o->min, -1); - max = FFMAX(o->max, nb_fmts-1); + min = FFMAX(o->min, -1); + max = FFMIN(o->max, nb_fmts-1); } if (fmt < min || fmt > max) { av_log(obj, AV_LOG_ERROR, @@ -521,6 +598,22 @@ int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB); } +int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int search_flags) +{ + void *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) { + av_log(obj, AV_LOG_ERROR, + "The value set by option '%s' is not a channel layout.\n", o->name); + return AVERROR(EINVAL); + } + *(int *)(((int64_t *)target_obj) + o->offset) = cl; + return 0; +} + #if FF_API_OLD_AVOPTIONS /** * @@ -616,6 +709,13 @@ int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val) i64 / 3600000000, (int)((i64 / 60000000) % 60), (int)((i64 / 1000000) % 60), (int)(i64 % 1000000)); break; + case AV_OPT_TYPE_COLOR: + ret = snprintf(buf, sizeof(buf), "0x%02x%02x%02x%02x", ((int *)dst)[0], ((int *)dst)[1], ((int *)dst)[2], ((int *)dst)[3]); + break; + case AV_OPT_TYPE_CHANNEL_LAYOUT: + i64 = *(int64_t *)dst; + ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64); + break; default: return AVERROR(EINVAL); } @@ -785,6 +885,23 @@ int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AV return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample"); } +int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *cl) +{ + void *dst, *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) { + av_log(obj, AV_LOG_ERROR, + "The value for option '%s' is not a channel layout.\n", name); + return AVERROR(EINVAL); + } + + dst = ((uint8_t*)target_obj) + o->offset; + *cl = *(int64_t *)dst; + return 0; +} + int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name) { const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0); @@ -839,9 +956,11 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit, else if (unit && opt->type==AV_OPT_TYPE_CONST && strcmp(unit, opt->unit)) continue; else if (unit && opt->type == AV_OPT_TYPE_CONST) - av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name); + av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name); else - av_log(av_log_obj, AV_LOG_INFO, "-%-17s ", opt->name); + av_log(av_log_obj, AV_LOG_INFO, " %s%-17s ", + (opt->flags & AV_OPT_FLAG_FILTERING_PARAM) ? "" : "-", + opt->name); switch (opt->type) { case AV_OPT_TYPE_FLAGS: @@ -883,6 +1002,12 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit, case AV_OPT_TYPE_DURATION: av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); break; + case AV_OPT_TYPE_COLOR: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; + case AV_OPT_TYPE_CHANNEL_LAYOUT: + 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 ", ""); @@ -917,6 +1042,50 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit, av_opt_freep_ranges(&r); } + if (opt->type != AV_OPT_TYPE_CONST && + opt->type != AV_OPT_TYPE_BINARY && + !((opt->type == AV_OPT_TYPE_COLOR || + opt->type == AV_OPT_TYPE_IMAGE_SIZE || + opt->type == AV_OPT_TYPE_STRING || + opt->type == AV_OPT_TYPE_VIDEO_RATE) && + !opt->default_val.str)) { + av_log(av_log_obj, AV_LOG_INFO, " (default "); + switch (opt->type) { + case AV_OPT_TYPE_FLAGS: + av_log(av_log_obj, AV_LOG_INFO, "%"PRIX64, opt->default_val.i64); + break; + case AV_OPT_TYPE_DURATION: + case AV_OPT_TYPE_INT: + case AV_OPT_TYPE_INT64: + log_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64); + break; + case AV_OPT_TYPE_DOUBLE: + case AV_OPT_TYPE_FLOAT: + log_value(av_log_obj, AV_LOG_INFO, opt->default_val.dbl); + break; + case AV_OPT_TYPE_RATIONAL: { + AVRational q = av_d2q(opt->default_val.dbl, INT_MAX); + av_log(av_log_obj, AV_LOG_INFO, "%d/%d", q.num, q.den); } + break; + case AV_OPT_TYPE_PIXEL_FMT: + av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(opt->default_val.i64), "none")); + break; + case AV_OPT_TYPE_SAMPLE_FMT: + av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(opt->default_val.i64), "none")); + break; + case AV_OPT_TYPE_COLOR: + case AV_OPT_TYPE_IMAGE_SIZE: + case AV_OPT_TYPE_STRING: + case AV_OPT_TYPE_VIDEO_RATE: + av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str); + break; + case AV_OPT_TYPE_CHANNEL_LAYOUT: + av_log(av_log_obj, AV_LOG_INFO, "0x%"PRIx64, opt->default_val.i64); + break; + } + av_log(av_log_obj, AV_LOG_INFO, ")"); + } + av_log(av_log_obj, AV_LOG_INFO, "\n"); if (opt->unit && opt->type != AV_OPT_TYPE_CONST) { opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags); @@ -948,6 +1117,7 @@ void av_opt_set_defaults2(void *s, int mask, int flags) const AVClass *class = *(AVClass **)s; const AVOption *opt = NULL; while ((opt = av_opt_next(s, opt)) != NULL) { + void *dst = ((uint8_t*)s) + opt->offset; #if FF_API_OLD_AVOPTIONS if ((opt->flags & mask) != flags) continue; @@ -960,41 +1130,49 @@ void av_opt_set_defaults2(void *s, int mask, int flags) case AV_OPT_TYPE_INT: case AV_OPT_TYPE_INT64: case AV_OPT_TYPE_DURATION: - av_opt_set_int(s, opt->name, opt->default_val.i64, 0); + case AV_OPT_TYPE_CHANNEL_LAYOUT: + write_number(s, opt, dst, 1, 1, opt->default_val.i64); break; case AV_OPT_TYPE_DOUBLE: case AV_OPT_TYPE_FLOAT: { double val; val = opt->default_val.dbl; - av_opt_set_double(s, opt->name, val, 0); + write_number(s, opt, dst, val, 1, 1); } break; case AV_OPT_TYPE_RATIONAL: { AVRational val; val = av_d2q(opt->default_val.dbl, INT_MAX); - av_opt_set_q(s, opt->name, val, 0); + write_number(s, opt, dst, 1, val.den, val.num); } break; + case AV_OPT_TYPE_COLOR: + set_string_color(s, opt, opt->default_val.str, dst); + break; case AV_OPT_TYPE_STRING: + set_string(s, opt, opt->default_val.str, dst); + break; case AV_OPT_TYPE_IMAGE_SIZE: + set_string_image_size(s, opt, opt->default_val.str, dst); + break; case AV_OPT_TYPE_VIDEO_RATE: - av_opt_set(s, opt->name, opt->default_val.str, 0); + set_string_video_rate(s, opt, opt->default_val.str, dst); break; case AV_OPT_TYPE_PIXEL_FMT: -#if LIBAVUTIL_VERSION_MAJOR < 53 +#if LIBAVUTIL_VERSION_MAJOR < 54 if (class->version && class->version < AV_VERSION_INT(52, 10, 100)) av_opt_set(s, opt->name, opt->default_val.str, 0); else #endif - av_opt_set_pixel_fmt(s, opt->name, opt->default_val.i64, 0); + write_number(s, opt, dst, 1, 1, opt->default_val.i64); break; case AV_OPT_TYPE_SAMPLE_FMT: -#if LIBAVUTIL_VERSION_MAJOR < 53 +#if LIBAVUTIL_VERSION_MAJOR < 54 if (class->version && class->version < AV_VERSION_INT(52, 10, 100)) av_opt_set(s, opt->name, opt->default_val.str, 0); else #endif - av_opt_set_sample_fmt(s, opt->name, opt->default_val.i64, 0); + write_number(s, opt, dst, 1, 1, opt->default_val.i64); break; case AV_OPT_TYPE_BINARY: /* Cannot set default for binary */ @@ -1029,9 +1207,16 @@ static int parse_key_value_pair(void *ctx, const char **buf, char *val; int ret; + if (!key) + return AVERROR(ENOMEM); + if (*key && strspn(*buf, key_val_sep)) { (*buf)++; val = av_get_token(buf, pairs_sep); + if (!val) { + av_freep(&key); + return AVERROR(ENOMEM); + } } else { av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key); av_free(key); @@ -1040,7 +1225,7 @@ static int parse_key_value_pair(void *ctx, const char **buf, av_log(ctx, AV_LOG_DEBUG, "Setting entry with key '%s' to value '%s'\n", key, val); - ret = av_opt_set(ctx, key, val, 0); + ret = av_opt_set(ctx, key, val, AV_OPT_SEARCH_CHILDREN); if (ret == AVERROR_OPTION_NOT_FOUND) av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key); @@ -1227,6 +1412,9 @@ const AVOption *av_opt_find2(void *obj, const char *name, const char *unit, c= *(AVClass**)obj; + if (!c) + return NULL; + if (search_flags & AV_OPT_SEARCH_CHILDREN) { if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) { const AVClass *child = NULL; @@ -1324,6 +1512,8 @@ int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const ch case AV_OPT_TYPE_FLOAT: case AV_OPT_TYPE_DOUBLE: case AV_OPT_TYPE_DURATION: + case AV_OPT_TYPE_COLOR: + case AV_OPT_TYPE_CHANNEL_LAYOUT: break; case AV_OPT_TYPE_STRING: range->component_min = 0; @@ -1390,6 +1580,8 @@ typedef struct TestContext enum AVPixelFormat pix_fmt; enum AVSampleFormat sample_fmt; int64_t duration; + uint8_t color[4]; + int64_t channel_layout; } TestContext; #define OFFSET(x) offsetof(TestContext, x) @@ -1408,10 +1600,12 @@ static const AVOption test_options[]= { {"lame", "set lame flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_LAME}, INT_MIN, INT_MAX, 0, "flags" }, {"mu", "set mu flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_MU}, INT_MIN, INT_MAX, 0, "flags" }, {"size", "set size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE,{0}, 0, 0 }, -{"pix_fmt", "set pixfmt", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, AV_PIX_FMT_NB-1}, -{"sample_fmt", "set samplefmt", OFFSET(sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64 = AV_SAMPLE_FMT_NONE}, -1, AV_SAMPLE_FMT_NB-1}, +{"pix_fmt", "set pixfmt", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, INT_MAX}, +{"sample_fmt", "set samplefmt", OFFSET(sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64 = AV_SAMPLE_FMT_NONE}, -1, INT_MAX}, {"video_rate", "set videorate", OFFSET(video_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0 }, {"duration", "set duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX}, +{"color", "set color", OFFSET(color), AV_OPT_TYPE_COLOR, {.str = "pink"}, 0, 0}, +{"cl", "set channel layout", OFFSET(channel_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64 = AV_CH_LAYOUT_HEXAGONAL}, 0, INT64_MAX}, {NULL}, }; @@ -1433,7 +1627,7 @@ int main(void) printf("\nTesting av_set_options_string()\n"); { TestContext test_ctx = { 0 }; - const char *options[] = { + static const char * const options[] = { "", ":", "=", @@ -1470,6 +1664,11 @@ int main(void) "duration=bogus", "duration=123.45", "duration=1\\:23\\:45.67", + "color=blue", + "color=0x223300", + "color=0x42FF07AA", + "cl=stereo+downmix", + "cl=foo", }; test_ctx.class = &test_class; @@ -1483,13 +1682,13 @@ int main(void) av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]); printf("\n"); } - av_freep(&test_ctx.string); + av_opt_free(&test_ctx); } printf("\nTesting av_opt_set_from_string()\n"); { TestContext test_ctx = { 0 }; - const char *options[] = { + static const char * const options[] = { "", "5", "5:hello", @@ -1500,11 +1699,10 @@ int main(void) " 5 : hello : size = pal ", "a_very_long_option_name_that_will_need_to_be_ellipsized_around_here=42" }; - const char *shorthand[] = { "num", "string", NULL }; + static const char * const shorthand[] = { "num", "string", NULL }; test_ctx.class = &test_class; av_opt_set_defaults(&test_ctx); - test_ctx.string = av_strdup("default"); av_log_set_level(AV_LOG_DEBUG); @@ -1514,7 +1712,7 @@ int main(void) av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]); printf("\n"); } - av_freep(&test_ctx.string); + av_opt_free(&test_ctx); } return 0; -- cgit v1.2.3