From 79d3fceece0ead163ffcaca753b9479669776d2f Mon Sep 17 00:00:00 2001
From: Paul B Mahol <onemda@gmail.com>
Date: Sun, 19 Nov 2023 19:35:43 +0100
Subject: [PATCH] avfilter: use AV_OPT_TYPE_CHLAYOUT

Signed-off-by: Paul B Mahol <onemda@gmail.com>
---
 libavfilter/af_channelmap.c   | 57 +++++++++--------------------------
 libavfilter/af_channelsplit.c | 14 +++------
 libavfilter/af_join.c         | 23 +-------------
 libavfilter/af_surround.c     | 28 +++++------------
 libavfilter/asrc_afdelaysrc.c | 26 ++--------------
 libavfilter/asrc_anullsrc.c   | 34 +++------------------
 6 files changed, 34 insertions(+), 148 deletions(-)

diff --git a/libavfilter/af_channelmap.c b/libavfilter/af_channelmap.c
index 09bc4cfbe1..3a16f3e4b5 100644
--- a/libavfilter/af_channelmap.c
+++ b/libavfilter/af_channelmap.c
@@ -58,7 +58,6 @@ enum MappingMode {
 typedef struct ChannelMapContext {
     const AVClass *class;
     char *mapping_str;
-    char *channel_layout_str;
     AVChannelLayout output_layout;
     struct ChannelMap map[MAX_CH];
     int nch;
@@ -72,7 +71,7 @@ static const AVOption channelmap_options[] = {
     { "map", "A comma-separated list of input channel numbers in output order.",
           OFFSET(mapping_str),        AV_OPT_TYPE_STRING, .flags = A|F },
     { "channel_layout", "Output channel layout.",
-          OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, .flags = A|F },
+          OFFSET(output_layout),      AV_OPT_TYPE_CHLAYOUT, .flags = A|F },
     { NULL }
 };
 
@@ -122,7 +121,6 @@ static av_cold int channelmap_init(AVFilterContext *ctx)
     ChannelMapContext *s = ctx->priv;
     char *mapping, separator = '|';
     int map_entries = 0;
-    char buf[256];
     enum MappingMode mode;
     uint64_t out_ch_mask = 0;
     int i;
@@ -235,47 +233,22 @@ static av_cold int channelmap_init(AVFilterContext *ctx)
     else
         av_channel_layout_default(&s->output_layout, map_entries);
 
-    if (s->channel_layout_str) {
-        AVChannelLayout fmt = { 0 };
-        int ret;
-        if ((ret = av_channel_layout_from_string(&fmt, s->channel_layout_str)) < 0) {
-#if FF_API_OLD_CHANNEL_LAYOUT
-            uint64_t mask;
-FF_DISABLE_DEPRECATION_WARNINGS
-            if ((mask = av_get_channel_layout(s->channel_layout_str)) == 0) {
-#endif
-                av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout: '%s'.\n",
-                       s->channel_layout_str);
-                return AVERROR(EINVAL);
-#if FF_API_OLD_CHANNEL_LAYOUT
-            }
-FF_ENABLE_DEPRECATION_WARNINGS
-            av_log(ctx, AV_LOG_WARNING, "Channel layout '%s' uses a deprecated syntax.\n",
-                   s->channel_layout_str);
-            av_channel_layout_from_mask(&fmt, mask);
-#endif
-        }
-        if (mode == MAP_NONE) {
-            int i;
-            s->nch = fmt.nb_channels;
-            for (i = 0; i < s->nch; i++) {
-                s->map[i].in_channel_idx  = i;
-                s->map[i].out_channel_idx = i;
-            }
-        } else if (out_ch_mask && av_channel_layout_compare(&s->output_layout, &fmt)) {
-            av_channel_layout_describe(&s->output_layout, buf, sizeof(buf));
-            av_log(ctx, AV_LOG_ERROR,
-                   "Output channel layout '%s' does not match the list of channel mapped: '%s'.\n",
-                   s->channel_layout_str, buf);
-            return AVERROR(EINVAL);
-        } else if (s->nch != fmt.nb_channels) {
-            av_log(ctx, AV_LOG_ERROR,
-                   "Output channel layout %s does not match the number of channels mapped %d.\n",
-                   s->channel_layout_str, s->nch);
-            return AVERROR(EINVAL);
+    if (mode == MAP_NONE) {
+        int i;
+        s->nch = s->output_layout.nb_channels;
+        for (i = 0; i < s->nch; i++) {
+            s->map[i].in_channel_idx  = i;
+            s->map[i].out_channel_idx = i;
         }
-        s->output_layout = fmt;
+    } else if (s->nch != s->output_layout.nb_channels) {
+        char buf[256];
+        av_channel_layout_describe(&s->output_layout, buf, sizeof(buf));
+        av_log(ctx, AV_LOG_ERROR,
+               "Output channel layout %s does not match the number of channels mapped %d.\n",
+               buf, s->nch);
+        return AVERROR(EINVAL);
     }
+
     if (!s->output_layout.nb_channels) {
         av_log(ctx, AV_LOG_ERROR, "Output channel layout is not set and "
                "cannot be guessed from the maps.\n");
diff --git a/libavfilter/af_channelsplit.c b/libavfilter/af_channelsplit.c
index bd4afff122..932b51d701 100644
--- a/libavfilter/af_channelsplit.c
+++ b/libavfilter/af_channelsplit.c
@@ -40,7 +40,6 @@ typedef struct ChannelSplitContext {
     const AVClass *class;
 
     AVChannelLayout channel_layout;
-    char    *channel_layout_str;
     char    *channels_str;
 
     int      map[64];
@@ -50,7 +49,7 @@ typedef struct ChannelSplitContext {
 #define A AV_OPT_FLAG_AUDIO_PARAM
 #define F AV_OPT_FLAG_FILTERING_PARAM
 static const AVOption channelsplit_options[] = {
-    { "channel_layout", "Input channel layout.", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, { .str = "stereo" }, .flags = A|F },
+    { "channel_layout", "Input channel layout.", OFFSET(channel_layout),   AV_OPT_TYPE_CHLAYOUT, { .str = "stereo" }, .flags = A|F },
     { "channels",        "Channels to extract.", OFFSET(channels_str),       AV_OPT_TYPE_STRING, { .str = "all" },    .flags = A|F },
     { NULL }
 };
@@ -63,13 +62,6 @@ static av_cold int init(AVFilterContext *ctx)
     AVChannelLayout channel_layout = { 0 };
     int all = 0, ret = 0, i;
 
-    if ((ret = av_channel_layout_from_string(&s->channel_layout, s->channel_layout_str)) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout '%s'.\n",
-               s->channel_layout_str);
-        ret = AVERROR(EINVAL);
-        goto fail;
-    }
-
     if (!strcmp(s->channels_str, "all")) {
         if ((ret = av_channel_layout_copy(&channel_layout, &s->channel_layout)) < 0)
             goto fail;
@@ -100,9 +92,11 @@ static av_cold int init(AVFilterContext *ctx)
         if (all) {
             s->map[i] = i;
         } else {
+            char buf[128];
+            av_channel_layout_describe(&s->channel_layout, buf, sizeof(buf));
             if ((ret = av_channel_layout_index_from_channel(&s->channel_layout, channel)) < 0) {
                 av_log(ctx, AV_LOG_ERROR, "Channel name '%s' not present in channel layout '%s'.\n",
-                       pad.name, s->channel_layout_str);
+                       pad.name, buf);
                 av_freep(&pad.name);
                 goto fail;
             }
diff --git a/libavfilter/af_join.c b/libavfilter/af_join.c
index 5dbf9d8d22..416cfd7a9a 100644
--- a/libavfilter/af_join.c
+++ b/libavfilter/af_join.c
@@ -48,7 +48,6 @@ typedef struct JoinContext {
 
     int inputs;
     char *map;
-    char    *channel_layout_str;
     AVChannelLayout ch_layout;
 
     int64_t  eof_pts;
@@ -73,7 +72,7 @@ typedef struct JoinContext {
 static const AVOption join_options[] = {
     { "inputs",         "Number of input streams.", OFFSET(inputs),             AV_OPT_TYPE_INT,    { .i64 = 2 }, 1, INT_MAX,       A|F },
     { "channel_layout", "Channel layout of the "
-                        "output stream.",           OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, {.str = "stereo"}, 0, 0, A|F },
+                        "output stream.",           OFFSET(ch_layout),          AV_OPT_TYPE_CHLAYOUT, {.str = "stereo"}, 0, 0, A|F },
     { "map",            "A comma-separated list of channels maps in the format "
                         "'input_stream.input_channel-output_channel.",
                                                     OFFSET(map),                AV_OPT_TYPE_STRING,                 .flags = A|F },
@@ -157,26 +156,6 @@ static av_cold int join_init(AVFilterContext *ctx)
     JoinContext *s = ctx->priv;
     int ret, i;
 
-    ret = av_channel_layout_from_string(&s->ch_layout, s->channel_layout_str);
-    if (ret < 0) {
-#if FF_API_OLD_CHANNEL_LAYOUT
-        uint64_t mask;
-FF_DISABLE_DEPRECATION_WARNINGS
-        mask = av_get_channel_layout(s->channel_layout_str);
-        if (!mask) {
-#endif
-            av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout '%s'.\n",
-                   s->channel_layout_str);
-            return AVERROR(EINVAL);
-#if FF_API_OLD_CHANNEL_LAYOUT
-        }
-FF_ENABLE_DEPRECATION_WARNINGS
-        av_log(ctx, AV_LOG_WARNING, "Channel layout '%s' uses a deprecated syntax.\n",
-               s->channel_layout_str);
-        av_channel_layout_from_mask(&s->ch_layout, mask);
-#endif
-    }
-
     s->channels     = av_calloc(s->ch_layout.nb_channels, sizeof(*s->channels));
     s->buffers      = av_calloc(s->ch_layout.nb_channels, sizeof(*s->buffers));
     s->input_frames = av_calloc(s->inputs, sizeof(*s->input_frames));
diff --git a/libavfilter/af_surround.c b/libavfilter/af_surround.c
index 3398c25446..79df86081c 100644
--- a/libavfilter/af_surround.c
+++ b/libavfilter/af_surround.c
@@ -61,8 +61,8 @@ static const int sc_map[16] = {
 typedef struct AudioSurroundContext {
     const AVClass *class;
 
-    char *out_channel_layout_str;
-    char *in_channel_layout_str;
+    AVChannelLayout out_ch_layout;
+    AVChannelLayout in_ch_layout;
 
     float level_in;
     float level_out;
@@ -93,8 +93,6 @@ typedef struct AudioSurroundContext {
     float lowcut;
     float highcut;
 
-    AVChannelLayout out_ch_layout;
-    AVChannelLayout in_ch_layout;
     int nb_in_channels;
     int nb_out_channels;
 
@@ -1107,20 +1105,8 @@ static av_cold int init(AVFilterContext *ctx)
 {
     AudioSurroundContext *s = ctx->priv;
     int64_t in_channel_layout, out_channel_layout;
+    char in_name[128], out_name[128];
     float overlap;
-    int ret;
-
-    if ((ret = av_channel_layout_from_string(&s->out_ch_layout, s->out_channel_layout_str)) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing output channel layout '%s'.\n",
-               s->out_channel_layout_str);
-        return ret;
-    }
-
-    if ((ret = av_channel_layout_from_string(&s->in_ch_layout, s->in_channel_layout_str)) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing input channel layout '%s'.\n",
-               s->in_channel_layout_str);
-        return AVERROR(EINVAL);
-    }
 
     if (s->lowcutf >= s->highcutf) {
         av_log(ctx, AV_LOG_ERROR, "Low cut-off '%d' should be less than high cut-off '%d'.\n",
@@ -1181,8 +1167,10 @@ static av_cold int init(AVFilterContext *ctx)
         break;
     default:
 fail:
+        av_channel_layout_describe(&s->out_ch_layout, out_name, sizeof(out_name));
+        av_channel_layout_describe(&s->in_ch_layout, in_name, sizeof(in_name));
         av_log(ctx, AV_LOG_ERROR, "Unsupported upmix: '%s' -> '%s'.\n",
-               s->in_channel_layout_str, s->out_channel_layout_str);
+               in_name, out_name);
         return AVERROR(EINVAL);
     }
 
@@ -1417,8 +1405,8 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar
 #define TFLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
 
 static const AVOption surround_options[] = {
-    { "chl_out",   "set output channel layout", OFFSET(out_channel_layout_str), AV_OPT_TYPE_STRING, {.str="5.1"}, 0,   0, FLAGS },
-    { "chl_in",    "set input channel layout",  OFFSET(in_channel_layout_str),  AV_OPT_TYPE_STRING, {.str="stereo"},0, 0, FLAGS },
+    { "chl_out",   "set output channel layout", OFFSET(out_ch_layout),          AV_OPT_TYPE_CHLAYOUT, {.str="5.1"}, 0,   0, FLAGS },
+    { "chl_in",    "set input channel layout",  OFFSET(in_ch_layout),           AV_OPT_TYPE_CHLAYOUT, {.str="stereo"},0, 0, FLAGS },
     { "level_in",  "set input level",           OFFSET(level_in),               AV_OPT_TYPE_FLOAT,  {.dbl=1},     0,  10, TFLAGS },
     { "level_out", "set output level",          OFFSET(level_out),              AV_OPT_TYPE_FLOAT,  {.dbl=1},     0,  10, TFLAGS },
     { "lfe",       "output LFE",                OFFSET(output_lfe),             AV_OPT_TYPE_BOOL,   {.i64=1},     0,   1, TFLAGS },
diff --git a/libavfilter/asrc_afdelaysrc.c b/libavfilter/asrc_afdelaysrc.c
index a7d25c5309..f3f0b080a0 100644
--- a/libavfilter/asrc_afdelaysrc.c
+++ b/libavfilter/asrc_afdelaysrc.c
@@ -36,23 +36,10 @@ typedef struct AFDelaySrcContext {
     int nb_samples;
     int nb_taps;
     AVChannelLayout chlayout;
-    char *chlayout_str;
 
     int64_t pts;
 } AFDelaySrcContext;
 
-static av_cold int init(AVFilterContext *ctx)
-{
-    AFDelaySrcContext *s = ctx->priv;
-    int ret;
-
-    ret = ff_parse_channel_layout(&s->chlayout, NULL, s->chlayout_str, ctx);
-    if (ret < 0)
-        return ret;
-
-    return 0;
-}
-
 static float sincf(float x)
 {
     if (x == 0.f)
@@ -134,13 +121,6 @@ static const AVFilterPad afdelaysrc_outputs[] = {
     },
 };
 
-static av_cold void uninit(AVFilterContext *ctx)
-{
-    AFDelaySrcContext *s = ctx->priv;
-
-    av_channel_layout_uninit(&s->chlayout);
-}
-
 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
 #define OFFSET(x) offsetof(AFDelaySrcContext, x)
 
@@ -153,8 +133,8 @@ static const AVOption afdelaysrc_options[] = {
     { "n",           "set the number of samples per requested frame", OFFSET(nb_samples),  AV_OPT_TYPE_INT,   {.i64=1024},   1, INT_MAX,   AF },
     { "taps",        "set number of taps for delay filter",           OFFSET(nb_taps),     AV_OPT_TYPE_INT,   {.i64=0},      0,   32768,   AF },
     { "t",           "set number of taps for delay filter",           OFFSET(nb_taps),     AV_OPT_TYPE_INT,   {.i64=0},      0,   32768,   AF },
-    { "channel_layout", "set channel layout",                         OFFSET(chlayout_str),AV_OPT_TYPE_STRING,{.str="stereo"},0,      0,   AF },
-    { "c",              "set channel layout",                         OFFSET(chlayout_str),AV_OPT_TYPE_STRING,{.str="stereo"},0,      0,   AF },
+    { "channel_layout", "set channel layout",                         OFFSET(chlayout),    AV_OPT_TYPE_CHLAYOUT,{.str="stereo"},0,      0,   AF },
+    { "c",              "set channel layout",                         OFFSET(chlayout),    AV_OPT_TYPE_CHLAYOUT,{.str="stereo"},0,      0,   AF },
     { NULL }
 };
 
@@ -165,9 +145,7 @@ const AVFilter ff_asrc_afdelaysrc = {
     .description   = NULL_IF_CONFIG_SMALL("Generate a Fractional delay FIR coefficients."),
     .priv_size     = sizeof(AFDelaySrcContext),
     .priv_class    = &afdelaysrc_class,
-    .init          = init,
     .activate      = activate,
-    .uninit        = uninit,
     .inputs        = NULL,
     FILTER_OUTPUTS(afdelaysrc_outputs),
     FILTER_QUERY_FUNC(query_formats),
diff --git a/libavfilter/asrc_anullsrc.c b/libavfilter/asrc_anullsrc.c
index c89100c0dc..a8887da62d 100644
--- a/libavfilter/asrc_anullsrc.c
+++ b/libavfilter/asrc_anullsrc.c
@@ -38,9 +38,7 @@
 
 typedef struct ANullContext {
     const AVClass *class;
-    char   *channel_layout_str;
     AVChannelLayout ch_layout;
-    char   *sample_rate_str;
     int     sample_rate;
     int64_t duration;
     int nb_samples;             ///< number of samples per requested frame
@@ -51,10 +49,10 @@ typedef struct ANullContext {
 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
 
 static const AVOption anullsrc_options[]= {
-    { "channel_layout", "set channel_layout", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, {.str = "stereo"}, 0, 0, FLAGS },
-    { "cl",             "set channel_layout", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, {.str = "stereo"}, 0, 0, FLAGS },
-    { "sample_rate",    "set sample rate",    OFFSET(sample_rate_str)   , AV_OPT_TYPE_STRING, {.str = "44100"}, 0, 0, FLAGS },
-    { "r",              "set sample rate",    OFFSET(sample_rate_str)   , AV_OPT_TYPE_STRING, {.str = "44100"}, 0, 0, FLAGS },
+    { "channel_layout", "set channel_layout", OFFSET(ch_layout), AV_OPT_TYPE_CHLAYOUT, {.str = "stereo"}, 0, 0, FLAGS },
+    { "cl",             "set channel_layout", OFFSET(ch_layout), AV_OPT_TYPE_CHLAYOUT, {.str = "stereo"}, 0, 0, FLAGS },
+    { "sample_rate",    "set sample rate",    OFFSET(sample_rate)   , AV_OPT_TYPE_INT, {.i64 = 44100}, 0, 0, FLAGS },
+    { "r",              "set sample rate",    OFFSET(sample_rate)   , AV_OPT_TYPE_INT, {.i64 = 44100}, 0, 0, FLAGS },
     { "nb_samples",     "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, UINT16_MAX, FLAGS },
     { "n",              "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, UINT16_MAX, FLAGS },
     { "duration",       "set the audio duration",                        OFFSET(duration),   AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },
@@ -64,22 +62,6 @@ static const AVOption anullsrc_options[]= {
 
 AVFILTER_DEFINE_CLASS(anullsrc);
 
-static av_cold int init(AVFilterContext *ctx)
-{
-    ANullContext *null = ctx->priv;
-    int ret;
-
-    if ((ret = ff_parse_sample_rate(&null->sample_rate,
-                                     null->sample_rate_str, ctx)) < 0)
-        return ret;
-
-    if ((ret = ff_parse_channel_layout(&null->ch_layout, NULL,
-                                        null->channel_layout_str, ctx)) < 0)
-        return ret;
-
-    return 0;
-}
-
 static int query_formats(AVFilterContext *ctx)
 {
     ANullContext *null = ctx->priv;
@@ -129,12 +111,6 @@ static int activate(AVFilterContext *ctx)
     return FFERROR_NOT_READY;
 }
 
-static av_cold void uninit(AVFilterContext *ctx)
-{
-    ANullContext *s = ctx->priv;
-    av_channel_layout_uninit(&s->ch_layout);
-}
-
 static const AVFilterPad avfilter_asrc_anullsrc_outputs[] = {
     {
         .name          = "default",
@@ -146,8 +122,6 @@ static const AVFilterPad avfilter_asrc_anullsrc_outputs[] = {
 const AVFilter ff_asrc_anullsrc = {
     .name          = "anullsrc",
     .description   = NULL_IF_CONFIG_SMALL("Null audio source, return empty audio frames."),
-    .init          = init,
-    .uninit        = uninit,
     .priv_size     = sizeof(ANullContext),
     .inputs        = NULL,
     FILTER_OUTPUTS(avfilter_asrc_anullsrc_outputs),
-- 
2.42.1

