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 | |
parent | f51e169d2b20d731a7b338e1381e438a5abe586f (diff) | |
download | ffmpeg-f423497b455da06c1337846902c770028760e094.tar.gz |
lavu: support AVChannelLayout AVOptions
Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>
Signed-off-by: James Almer <jamrial@gmail.com>
-rw-r--r-- | libavutil/opt.c | 126 | ||||
-rw-r--r-- | libavutil/opt.h | 12 | ||||
-rw-r--r-- | libavutil/tests/opt.c | 8 | ||||
-rw-r--r-- | tests/ref/fate/opt | 16 |
4 files changed, 149 insertions, 13 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", diff --git a/tests/ref/fate/opt b/tests/ref/fate/opt index aac3fa0e7e..832f9cc8a9 100644 --- a/tests/ref/fate/opt +++ b/tests/ref/fate/opt @@ -33,7 +33,7 @@ TestContext AVOptions: -video_rate <video_rate> E.......... set videorate (default "25") -duration <duration> E.......... set duration (default 0.001) -color <color> E.......... set color (default "pink") - -cl <channel_layout> E.......... set channel layout (default 0x137) + -cl <channel_layout> E.......... set channel layout (default "hexagonal") -bin <binary> E.......... set binary value -bin1 <binary> E.......... set binary value -bin2 <binary> E.......... set binary value @@ -115,7 +115,7 @@ name: sample_fmt get: s16 set: OK get: s16 name: video_rate get: 25/1 set: OK get: 25/1 OK name: duration get: 0.001 set: OK get: 0.001 OK name: color get: 0xffc0cbff set: OK get: 0xffc0cbff OK -name: cl get: 0x137 set: OK get: 0x137 OK +name: cl get: hexagonal set: OK get: hexagonal OK name: bin get: 62696E00 set: OK get: 62696E00 OK name: bin1 get: set: OK get: OK name: bin2 get: set: OK get: OK @@ -129,7 +129,7 @@ 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=0x137,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333,bool1=auto,bool2=true,bool3=false,dict1=,dict2=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\=\\:-) 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' @@ -142,7 +142,7 @@ Setting entry with key 'sample_fmt' to value 's16' Setting entry with key 'video_rate' to value '25/1' Setting entry with key 'duration' to value '0.001' Setting entry with key 'color' to value '0xffc0cbff' -Setting entry with key 'cl' to value '0x137' +Setting entry with key 'cl' to value 'hexagonal' Setting entry with key 'bin' to value '62696E00' Setting entry with key 'bin1' to value '' Setting entry with key 'bin2' to value '' @@ -154,7 +154,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=0x137,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333,bool1=auto,bool2=true,bool3=false,dict1=,dict2=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\=\\:-) Testing av_set_options_string() Setting options string '' @@ -296,9 +296,9 @@ OK 'color=0x223300' Setting options string 'color=0x42FF07AA' Setting entry with key 'color' to value '0x42FF07AA' OK 'color=0x42FF07AA' -Setting options string 'cl=stereo+downmix' -Setting entry with key 'cl' to value 'stereo+downmix' -OK 'cl=stereo+downmix' +Setting options string 'cl=FL+FR' +Setting entry with key 'cl' to value 'FL+FR' +OK 'cl=FL+FR' Setting options string 'cl=foo' Setting entry with key 'cl' to value 'foo' Unable to parse option value "foo" as channel layout |