diff mbox series

[FFmpeg-devel,03/26] avfilter/af_sidechaincompress: Honour query_formats API, fix segfault

Message ID AM7PR03MB6660DE6C0E733926E2DC18088FA19@AM7PR03MB6660.eurprd03.prod.outlook.com
State Accepted
Commit 7d995078386793e0aeeedeb7803001ed8758b30b
Headers show
Series [FFmpeg-devel,01/26] avfilter/af_afade: Remove redundant checks and assignments
Related show

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

Andreas Rheinhardt Sept. 21, 2021, 6:27 a.m. UTC
Just like the sidechaingate filter, the sidechaincompress filter
overwrote the channel layout and channel count of its output in
its config_output callback to match the channel layout of its main
input instead of linking the main input and its output together
in its query_formats callback.

This is an API violation that can lead to segfaults, as in the
following filtergraph, where stereotools rightly expects stereo,
yet receives only mono:
[in]aformat=channel_layouts=mono,aformat=channel_layouts=stereo|mono[out];\
[out][in2]sidechaincompress,stereotools

Fix this by linking the channel layouts of the main input and the output
in query_formats and remove the code overwriting it in config_output.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
Will deduplicate af_agate.c and af_sidechaincompress.c later.

 libavfilter/af_sidechaincompress.c | 26 +++++++-------------------
 1 file changed, 7 insertions(+), 19 deletions(-)

Comments

Paul B Mahol Sept. 21, 2021, 7:01 a.m. UTC | #1
lgtm
diff mbox series

Patch

diff --git a/libavfilter/af_sidechaincompress.c b/libavfilter/af_sidechaincompress.c
index 48d450fd50..af4a90ea09 100644
--- a/libavfilter/af_sidechaincompress.c
+++ b/libavfilter/af_sidechaincompress.c
@@ -298,29 +298,19 @@  static int activate(AVFilterContext *ctx)
 
 static int query_formats(AVFilterContext *ctx)
 {
-    AVFilterChannelLayouts *layouts = NULL;
     static const enum AVSampleFormat sample_fmts[] = {
         AV_SAMPLE_FMT_DBL,
         AV_SAMPLE_FMT_NONE
     };
-    int ret, i;
-
-    if (!ctx->inputs[0]->incfg.channel_layouts ||
-        !ctx->inputs[0]->incfg.channel_layouts->nb_channel_layouts) {
-        av_log(ctx, AV_LOG_WARNING,
-               "No channel layout for input 1\n");
-            return AVERROR(EAGAIN);
-    }
-
-    if ((ret = ff_add_channel_layout(&layouts, ctx->inputs[0]->incfg.channel_layouts->channel_layouts[0])) < 0 ||
-        (ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts)) < 0)
+    int ret = ff_channel_layouts_ref(ff_all_channel_counts(),
+                                     &ctx->inputs[1]->outcfg.channel_layouts);
+    if (ret < 0)
         return ret;
 
-    for (i = 0; i < 2; i++) {
-        layouts = ff_all_channel_counts();
-        if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->outcfg.channel_layouts)) < 0)
-            return ret;
-    }
+    /* This will link the channel properties of the main input and the output;
+     * it won't touch the second input as its channel_layouts is already set. */
+    if ((ret = ff_set_common_all_channel_counts(ctx)) < 0)
+        return ret;
 
     if ((ret = ff_set_common_formats_from_list(ctx, sample_fmts)) < 0)
         return ret;
@@ -343,8 +333,6 @@  static int config_output(AVFilterLink *outlink)
 
     outlink->sample_rate = ctx->inputs[0]->sample_rate;
     outlink->time_base   = ctx->inputs[0]->time_base;
-    outlink->channel_layout = ctx->inputs[0]->channel_layout;
-    outlink->channels = ctx->inputs[0]->channels;
 
     s->fifo[0] = av_audio_fifo_alloc(ctx->inputs[0]->format, ctx->inputs[0]->channels, 1024);
     s->fifo[1] = av_audio_fifo_alloc(ctx->inputs[1]->format, ctx->inputs[1]->channels, 1024);