diff options
author | Anton Khirnov <anton@khirnov.net> | 2013-08-26 08:13:49 +0200 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2022-03-15 09:42:29 -0300 |
commit | f423497b455da06c1337846902c770028760e094 (patch) | |
tree | 716dfd0924b8031a2f8044399481e30decce235e /libavutil | |
parent | f51e169d2b20d731a7b338e1381e438a5abe586f (diff) |
lavu: support AVChannelLayout AVOptions
Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>
Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavutil')
-rw-r--r-- | libavutil/opt.c | 126 | ||||
-rw-r--r-- | libavutil/opt.h | 12 | ||||
-rw-r--r-- | libavutil/tests/opt.c | 8 |
3 files changed, 141 insertions, 5 deletions
diff --git a/libavutil/opt.c b/libavutil/opt.c index d951edca9d..445537fbad 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -39,6 +39,7 @@ #include "opt.h" #include "samplefmt.h" #include "bprint.h" +#include "version.h" #include <float.h> @@ -71,7 +72,11 @@ static int read_number(const AVOption *o, const void *dst, double *num, int *den case AV_OPT_TYPE_INT: *intnum = *(int *)dst; return 0; +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS case AV_OPT_TYPE_CHANNEL_LAYOUT: +FF_ENABLE_DEPRECATION_WARNINGS +#endif case AV_OPT_TYPE_DURATION: case AV_OPT_TYPE_INT64: case AV_OPT_TYPE_UINT64: @@ -126,7 +131,11 @@ static int write_number(void *obj, const AVOption *o, void *dst, double num, int *(int *)dst = llrint(num / den) * intnum; break; case AV_OPT_TYPE_DURATION: +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS case AV_OPT_TYPE_CHANNEL_LAYOUT: +FF_ENABLE_DEPRECATION_WARNINGS +#endif case AV_OPT_TYPE_INT64:{ double d = num / den; if (intnum == 1 && d == (double)INT64_MAX) { @@ -465,6 +474,16 @@ static int set_string_dict(void *obj, const AVOption *o, const char *val, uint8_ return 0; } +static int set_string_channel_layout(void *obj, const AVOption *o, + const char *val, void *dst) +{ + AVChannelLayout *channel_layout = dst; + av_channel_layout_uninit(channel_layout); + if (!val) + return 0; + return av_channel_layout_from_string(channel_layout, val); +} + int av_opt_set(void *obj, const char *name, const char *val, int search_flags) { int ret = 0; @@ -472,12 +491,17 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags) const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); if (!o || !target_obj) return AVERROR_OPTION_NOT_FOUND; +FF_DISABLE_DEPRECATION_WARNINGS 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_DURATION && o->type != AV_OPT_TYPE_COLOR && - o->type != AV_OPT_TYPE_CHANNEL_LAYOUT && o->type != AV_OPT_TYPE_BOOL)) +#if FF_API_OLD_CHANNEL_LAYOUT + o->type != AV_OPT_TYPE_CHANNEL_LAYOUT && +#endif + o->type != AV_OPT_TYPE_BOOL)) return AVERROR(EINVAL); +FF_ENABLE_DEPRECATION_WARNINGS if (o->flags & AV_OPT_FLAG_READONLY) return AVERROR(EINVAL); @@ -533,6 +557,8 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags) } case AV_OPT_TYPE_COLOR: return set_string_color(obj, o, val, dst); +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS case AV_OPT_TYPE_CHANNEL_LAYOUT: if (!val || !strcmp(val, "none")) { *(int64_t *)dst = 0; @@ -546,6 +572,15 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags) return ret; } break; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + case AV_OPT_TYPE_CHLAYOUT: + ret = set_string_channel_layout(obj, o, val, dst); + if (ret < 0) { + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val); + ret = AVERROR(EINVAL); + } + return ret; case AV_OPT_TYPE_DICT: return set_string_dict(obj, o, val, dst); } @@ -709,6 +744,8 @@ 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); } +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int search_flags) { void *target_obj; @@ -724,6 +761,8 @@ int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int searc *(int64_t *)(((uint8_t *)target_obj) + o->offset) = cl; return 0; } +FF_ENABLE_DEPRECATION_WARNINGS +#endif int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, int search_flags) @@ -744,6 +783,22 @@ int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, return 0; } +int av_opt_set_chlayout(void *obj, const char *name, + const AVChannelLayout *channel_layout, + int search_flags) +{ + void *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + AVChannelLayout *dst; + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + + dst = (AVChannelLayout*)((uint8_t*)target_obj + o->offset); + + return av_channel_layout_copy(dst, channel_layout); +} + static void format_duration(char *buf, size_t size, int64_t d) { char *e; @@ -872,10 +927,18 @@ int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val) (int)((uint8_t *)dst)[0], (int)((uint8_t *)dst)[1], (int)((uint8_t *)dst)[2], (int)((uint8_t *)dst)[3]); break; +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS case AV_OPT_TYPE_CHANNEL_LAYOUT: + i64 = *(int64_t *)dst; ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64); break; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + case AV_OPT_TYPE_CHLAYOUT: + ret = av_channel_layout_describe(dst, buf, sizeof(buf)); + break; case AV_OPT_TYPE_DICT: if (!*(AVDictionary **)dst && (search_flags & AV_OPT_ALLOW_NULL)) { *out_val = NULL; @@ -1017,6 +1080,8 @@ 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"); } +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *cl) { void *dst, *target_obj; @@ -1033,6 +1098,24 @@ int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int *cl = *(int64_t *)dst; return 0; } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + +int av_opt_get_chlayout(void *obj, const char *name, int search_flags, AVChannelLayout *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_CHLAYOUT) { + 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; + return av_channel_layout_copy(cl, dst); +} int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val) { @@ -1225,7 +1308,12 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit, case AV_OPT_TYPE_COLOR: av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<color>"); break; + case AV_OPT_TYPE_CHLAYOUT: +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS case AV_OPT_TYPE_CHANNEL_LAYOUT: +FF_ENABLE_DEPRECATION_WARNINGS +#endif av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<channel_layout>"); break; case AV_OPT_TYPE_BOOL: @@ -1282,6 +1370,7 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit, opt->type == AV_OPT_TYPE_IMAGE_SIZE || opt->type == AV_OPT_TYPE_STRING || opt->type == AV_OPT_TYPE_DICT || + opt->type == AV_OPT_TYPE_CHLAYOUT || opt->type == AV_OPT_TYPE_VIDEO_RATE) && !opt->default_val.str)) { av_log(av_log_obj, AV_LOG_INFO, " (default "); @@ -1334,11 +1423,16 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit, case AV_OPT_TYPE_STRING: case AV_OPT_TYPE_DICT: case AV_OPT_TYPE_VIDEO_RATE: + case AV_OPT_TYPE_CHLAYOUT: av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str); break; +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS case AV_OPT_TYPE_CHANNEL_LAYOUT: av_log(av_log_obj, AV_LOG_INFO, "0x%"PRIx64, opt->default_val.i64); break; +FF_ENABLE_DEPRECATION_WARNINGS +#endif } av_log(av_log_obj, AV_LOG_INFO, ")"); } @@ -1388,7 +1482,11 @@ void av_opt_set_defaults2(void *s, int mask, int flags) case AV_OPT_TYPE_INT64: case AV_OPT_TYPE_UINT64: case AV_OPT_TYPE_DURATION: +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS case AV_OPT_TYPE_CHANNEL_LAYOUT: +FF_ENABLE_DEPRECATION_WARNINGS +#endif case AV_OPT_TYPE_PIXEL_FMT: case AV_OPT_TYPE_SAMPLE_FMT: write_number(s, opt, dst, 1, 1, opt->default_val.i64); @@ -1421,6 +1519,9 @@ void av_opt_set_defaults2(void *s, int mask, int flags) case AV_OPT_TYPE_BINARY: set_string_binary(s, opt, opt->default_val.str, dst); break; + case AV_OPT_TYPE_CHLAYOUT: + set_string_channel_layout(s, opt, opt->default_val.str, dst); + break; case AV_OPT_TYPE_DICT: set_string_dict(s, opt, opt->default_val.str, dst); break; @@ -1745,7 +1846,11 @@ static int opt_size(enum AVOptionType type) case AV_OPT_TYPE_FLAGS: return sizeof(int); case AV_OPT_TYPE_DURATION: +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS case AV_OPT_TYPE_CHANNEL_LAYOUT: +FF_ENABLE_DEPRECATION_WARNINGS +#endif case AV_OPT_TYPE_INT64: case AV_OPT_TYPE_UINT64: return sizeof(int64_t); @@ -1819,6 +1924,9 @@ int av_opt_copy(void *dst, const void *src) ret2 = av_dict_copy(ddict, *sdict, 0); if (ret2 < 0) ret = ret2; + } else if (o->type == AV_OPT_TYPE_CHLAYOUT) { + if (field_dst != field_src) + ret = av_channel_layout_copy(field_dst, field_src); } else { int size = opt_size(o->type); if (size < 0) @@ -1882,7 +1990,11 @@ int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const ch case AV_OPT_TYPE_DOUBLE: case AV_OPT_TYPE_DURATION: case AV_OPT_TYPE_COLOR: +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS case AV_OPT_TYPE_CHANNEL_LAYOUT: +FF_ENABLE_DEPRECATION_WARNINGS +#endif break; case AV_OPT_TYPE_STRING: range->component_min = 0; @@ -1962,12 +2074,24 @@ 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: +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS case AV_OPT_TYPE_CHANNEL_LAYOUT: +FF_ENABLE_DEPRECATION_WARNINGS +#endif case AV_OPT_TYPE_DURATION: case AV_OPT_TYPE_INT64: case AV_OPT_TYPE_UINT64: read_number(o, dst, NULL, NULL, &i64); return o->default_val.i64 == i64; + case AV_OPT_TYPE_CHLAYOUT: { + AVChannelLayout ch_layout = { 0 }; + if (o->default_val.str) { + if ((ret = av_channel_layout_from_string(&ch_layout, o->default_val.str)) < 0) + return ret; + } + return !av_channel_layout_compare((AVChannelLayout *)dst, &ch_layout); + } case AV_OPT_TYPE_STRING: str = *(char **)dst; if (str == o->default_val.str) //2 NULLs diff --git a/libavutil/opt.h b/libavutil/opt.h index 2820435eec..461b5d3b6b 100644 --- a/libavutil/opt.h +++ b/libavutil/opt.h @@ -29,6 +29,7 @@ #include "rational.h" #include "avutil.h" +#include "channel_layout.h" #include "dict.h" #include "log.h" #include "pixfmt.h" @@ -237,8 +238,11 @@ enum AVOptionType{ AV_OPT_TYPE_VIDEO_RATE, ///< offset must point to AVRational AV_OPT_TYPE_DURATION, AV_OPT_TYPE_COLOR, +#if FF_API_OLD_CHANNEL_LAYOUT AV_OPT_TYPE_CHANNEL_LAYOUT, +#endif AV_OPT_TYPE_BOOL, + AV_OPT_TYPE_CHLAYOUT, }; /** @@ -693,7 +697,11 @@ int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_ int av_opt_set_pixel_fmt (void *obj, const char *name, enum AVPixelFormat fmt, int search_flags); int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags); int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags); +#if FF_API_OLD_CHANNEL_LAYOUT +attribute_deprecated int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, int search_flags); +#endif +int av_opt_set_chlayout(void *obj, const char *name, const AVChannelLayout *layout, int search_flags); /** * @note Any old dictionary present is discarded and replaced with a copy of the new one. The * caller still owns val is and responsible for freeing it. @@ -748,7 +756,11 @@ int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_ int av_opt_get_pixel_fmt (void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt); int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt); int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val); +#if FF_API_OLD_CHANNEL_LAYOUT +attribute_deprecated int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *ch_layout); +#endif +int av_opt_get_chlayout(void *obj, const char *name, int search_flags, AVChannelLayout *layout); /** * @param[out] out_val The returned dictionary is a copy of the actual value and must * be freed with av_dict_free() by the caller diff --git a/libavutil/tests/opt.c b/libavutil/tests/opt.c index e6ea892373..5799e45c6a 100644 --- a/libavutil/tests/opt.c +++ b/libavutil/tests/opt.c @@ -41,7 +41,7 @@ typedef struct TestContext { enum AVSampleFormat sample_fmt; int64_t duration; uint8_t color[4]; - int64_t channel_layout; + AVChannelLayout channel_layout; void *binary; int binary_size; void *binary1; @@ -81,7 +81,7 @@ static const AVOption test_options[]= { {"video_rate", "set videorate", OFFSET(video_rate), AV_OPT_TYPE_VIDEO_RATE, { .str = "25" }, 0, INT_MAX, 1 }, {"duration", "set duration", OFFSET(duration), AV_OPT_TYPE_DURATION, { .i64 = 1000 }, 0, INT64_MAX, 1 }, {"color", "set color", OFFSET(color), AV_OPT_TYPE_COLOR, { .str = "pink" }, 0, 0, 1 }, - {"cl", "set channel layout", OFFSET(channel_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, { .i64 = AV_CH_LAYOUT_HEXAGONAL }, 0, INT64_MAX, 1 }, + {"cl", "set channel layout", OFFSET(channel_layout), AV_OPT_TYPE_CHLAYOUT, { .str = "hexagonal" }, 0, 0, 1 }, {"bin", "set binary value", OFFSET(binary), AV_OPT_TYPE_BINARY, { .str="62696e00" }, 0, 0, 1 }, {"bin1", "set binary value", OFFSET(binary1), AV_OPT_TYPE_BINARY, { .str=NULL }, 0, 0, 1 }, {"bin2", "set binary value", OFFSET(binary2), AV_OPT_TYPE_BINARY, { .str="" }, 0, 0, 1 }, @@ -138,7 +138,7 @@ int main(void) printf("sample_fmt=%s\n", av_get_sample_fmt_name(test_ctx.sample_fmt)); printf("duration=%"PRId64"\n", test_ctx.duration); printf("color=%d %d %d %d\n", test_ctx.color[0], test_ctx.color[1], test_ctx.color[2], test_ctx.color[3]); - printf("channel_layout=%"PRId64"=%"PRId64"\n", test_ctx.channel_layout, (int64_t)AV_CH_LAYOUT_HEXAGONAL); + printf("channel_layout=%"PRId64"=%"PRId64"\n", test_ctx.channel_layout.u.mask, (int64_t)AV_CH_LAYOUT_HEXAGONAL); if (test_ctx.binary) printf("binary=%x %x %x %x\n", ((uint8_t*)test_ctx.binary)[0], ((uint8_t*)test_ctx.binary)[1], ((uint8_t*)test_ctx.binary)[2], ((uint8_t*)test_ctx.binary)[3]); printf("binary_size=%d\n", test_ctx.binary_size); @@ -280,7 +280,7 @@ int main(void) "color=blue", "color=0x223300", "color=0x42FF07AA", - "cl=stereo+downmix", + "cl=FL+FR", "cl=foo", "bin=boguss", "bin=111", |