diff mbox series

[FFmpeg-devel,003/279] lavu: support AVChannelLayout AVOptions

Message ID 20211208010649.381-4-jamrial@gmail.com
State New
Headers show
Series New channel layout API | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished
andriy/make_ppc success Make finished
andriy/make_fate_ppc success Make fate finished

Commit Message

James Almer Dec. 8, 2021, 1:06 a.m. UTC
From: Anton Khirnov <anton@khirnov.net>

Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>
Signed-off-by: James Almer <jamrial@gmail.com>
---
 libavutil/opt.c       | 126 +++++++++++++++++++++++++++++++++++++++++-
 libavutil/opt.h       |  12 ++++
 libavutil/tests/opt.c |   8 +--
 tests/ref/fate/opt    |  16 +++---
 4 files changed, 149 insertions(+), 13 deletions(-)
diff mbox series

Patch

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..f1c222e850 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..4c7290c34a 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