diff mbox series

[FFmpeg-devel,02/16] lavfi/buffersink: move channel layout parsing to init

Message ID 20241001105421.28967-2-anton@khirnov.net
State New
Headers show
Series [FFmpeg-devel,01/16] lavfi/buffersink: move the option sanity check to init | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Anton Khirnov Oct. 1, 2024, 10:54 a.m. UTC
That is a more appropriate place for this, and will also be useful in
future commits.
---
 libavfilter/buffersink.c | 75 ++++++++++++++++++++++------------------
 1 file changed, 42 insertions(+), 33 deletions(-)
diff mbox series

Patch

diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c
index 95cb605712..0eded68b55 100644
--- a/libavfilter/buffersink.c
+++ b/libavfilter/buffersink.c
@@ -154,6 +154,7 @@  int attribute_align_arg av_buffersink_get_samples(AVFilterContext *ctx,
 static av_cold int common_init(AVFilterContext *ctx)
 {
     BufferSinkContext *buf = ctx->priv;
+    int ret = 0;
 
 #if FF_API_BUFFERSINK_OPTS
 
@@ -184,6 +185,44 @@  static av_cold int common_init(AVFilterContext *ctx)
 
         CHECK_LIST_SIZE(sample_fmts)
         CHECK_LIST_SIZE(sample_rates)
+
+        if (buf->channel_layouts_str) {
+            const char *cur = buf->channel_layouts_str;
+
+            if (buf->all_channel_counts)
+                av_log(ctx, AV_LOG_WARNING,
+                       "Conflicting all_channel_counts and list in options\n");
+
+            while (cur) {
+                void *tmp;
+                char *next = strchr(cur, '|');
+                if (next)
+                    *next++ = 0;
+
+                // +2 for the new element and terminator
+                tmp = av_realloc_array(buf->channel_layouts, buf->nb_channel_layouts + 2,
+                                       sizeof(*buf->channel_layouts));
+                if (!tmp)
+                    return AVERROR(ENOMEM);
+
+                memset(&buf->channel_layouts[buf->nb_channel_layouts], 0,
+                       sizeof(*buf->channel_layouts));
+                buf->nb_channel_layouts++;
+
+                ret = av_channel_layout_from_string(&buf->channel_layouts[buf->nb_channel_layouts - 1], cur);
+                if (ret < 0) {
+                    av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout: %s.\n", cur);
+                    return ret;
+                }
+                if (ret < 0)
+                    return ret;
+
+                cur = next;
+            }
+
+            if (buf->nb_channel_layouts)
+                buf->channel_layouts[buf->nb_channel_layouts] = (AVChannelLayout){ 0 };
+        }
     }
 
 #undef CHECK_LIST_SIZE
@@ -412,8 +451,6 @@  static int asink_query_formats(AVFilterContext *ctx)
 #if FF_API_BUFFERSINK_OPTS
     } else {
     AVFilterFormats *formats = NULL;
-    AVChannelLayout layout = { 0 };
-    AVFilterChannelLayouts *layouts = NULL;
     unsigned i;
 
     if (buf->sample_fmts_size) {
@@ -424,37 +461,9 @@  static int asink_query_formats(AVFilterContext *ctx)
             return ret;
     }
 
-    if (buf->channel_layouts_str || buf->all_channel_counts) {
-        if (buf->channel_layouts_str) {
-            const char *cur = buf->channel_layouts_str;
-
-            while (cur) {
-                char *next = strchr(cur, '|');
-                if (next)
-                    *next++ = 0;
-
-                ret = av_channel_layout_from_string(&layout, cur);
-                if (ret < 0) {
-                    av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout: %s.\n", cur);
-                    return ret;
-                }
-                ret = ff_add_channel_layout(&layouts, &layout);
-                av_channel_layout_uninit(&layout);
-                if (ret < 0)
-                    return ret;
-
-                cur = next;
-            }
-        }
-
-        if (buf->all_channel_counts) {
-            if (layouts)
-                av_log(ctx, AV_LOG_WARNING,
-                       "Conflicting all_channel_counts and list in options\n");
-            else if (!(layouts = ff_all_channel_counts()))
-                return AVERROR(ENOMEM);
-        }
-        if ((ret = ff_set_common_channel_layouts(ctx, layouts)) < 0)
+    if (buf->nb_channel_layouts) {
+        ret = ff_set_common_channel_layouts_from_list(ctx, buf->channel_layouts);
+        if (ret < 0)
             return ret;
     }