PR #23156 opened by James Almer (jamrial)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23156
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23156.patch

Before this change, the decoder was forcing downmixing everything to a max of 
six channels.

Layouts 6.1(back), 7.1(wide), 7.1 and 5.1.2 layouts (Channel Configurations 11, 
7, 12 and 14 respectively, as well as the equivalent PCE version) should be 
supported now.


>From 5a87681a03af96fa7cadf6ed5c4997e4bc77bd44 Mon Sep 17 00:00:00 2001
From: James Almer <[email protected]>
Date: Tue, 19 May 2026 13:13:28 -0300
Subject: [PATCH 1/2] avcodec/libfdk-aacdec: fix the check for downmix layout
 order

The code reads a mask afer this check, meaning it expects native order, not 
others.
Fix this by making it handle both native and custom orders.

Signed-off-by: James Almer <[email protected]>
---
 libavcodec/libfdk-aacdec.c | 16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/libavcodec/libfdk-aacdec.c b/libavcodec/libfdk-aacdec.c
index ac221645f0..cf45876a62 100644
--- a/libavcodec/libfdk-aacdec.c
+++ b/libavcodec/libfdk-aacdec.c
@@ -268,22 +268,16 @@ static av_cold int fdk_aac_decode_init(AVCodecContext 
*avctx)
         return AVERROR_UNKNOWN;
     }
 
-    if (s->downmix_layout.nb_channels > 0 &&
-        s->downmix_layout.order != AV_CHANNEL_ORDER_NATIVE) {
+    if (s->downmix_layout.nb_channels > 0) {
         int downmix_channels = -1;
 
-        switch (s->downmix_layout.u.mask) {
-        case AV_CH_LAYOUT_STEREO:
-        case AV_CH_LAYOUT_STEREO_DOWNMIX:
+        if (av_channel_layout_subset(&s->downmix_layout, AV_CH_LAYOUT_STEREO) 
== AV_CH_LAYOUT_STEREO ||
+            av_channel_layout_subset(&s->downmix_layout, 
AV_CH_LAYOUT_STEREO_DOWNMIX) == AV_CH_LAYOUT_STEREO_DOWNMIX)
             downmix_channels = 2;
-            break;
-        case AV_CH_LAYOUT_MONO:
+        else if (av_channel_layout_subset(&s->downmix_layout, 
AV_CH_LAYOUT_MONO) == AV_CH_LAYOUT_MONO)
             downmix_channels = 1;
-            break;
-        default:
+        else
             av_log(avctx, AV_LOG_WARNING, "Invalid downmix option\n");
-            break;
-        }
 
         if (downmix_channels != -1) {
             if (aacDecoder_SetParam(s->handle, AAC_PCM_MAX_OUTPUT_CHANNELS,
-- 
2.52.0


>From 374c4a2c51bf371d0bcf4919b03a083ceb51fcad Mon Sep 17 00:00:00 2001
From: James Almer <[email protected]>
Date: Tue, 19 May 2026 13:36:39 -0300
Subject: [PATCH 2/2] avcodec/libfdk-aacdec: support streams with more than six
 channel

Before this change, the decoder was forcing downmixing everything to a max of 6
channels.
Layouts 6.1(back), 7.1(wide), 7.1 and 5.1.2 layouts (Channel Configurations 11,
7, 12 and 14 respectively, as well as the equivalent PCE version) should be
supported now.

Signed-off-by: James Almer <[email protected]>
---
 libavcodec/libfdk-aacdec.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/libavcodec/libfdk-aacdec.c b/libavcodec/libfdk-aacdec.c
index cf45876a62..c3719a4ce9 100644
--- a/libavcodec/libfdk-aacdec.c
+++ b/libavcodec/libfdk-aacdec.c
@@ -191,6 +191,9 @@ static int get_stream_info(AVCodecContext *avctx, AVFrame 
*frame)
     }
     if (channel_counts[ACT_BACK] > 0) {
         switch (channel_counts[ACT_BACK]) {
+        case 4:
+            ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_SIDE_LEFT 
| AV_CH_SIDE_RIGHT;
+            break;
         case 3:
             ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | 
AV_CH_BACK_CENTER;
             break;
@@ -218,6 +221,26 @@ static int get_stream_info(AVCodecContext *avctx, AVFrame 
*frame)
             ch_error = 1;
         }
     }
+    if (channel_counts[ACT_FRONT_TOP] > 0) {
+        switch (channel_counts[ACT_FRONT_TOP]) {
+        case 3:
+            ch_layout |= AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT |
+                         AV_CH_TOP_FRONT_CENTER;
+            break;
+        case 2:
+            ch_layout |= AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT;
+            break;
+        case 1:
+            ch_layout |= AV_CH_TOP_FRONT_CENTER;
+            break;
+        default:
+            av_log(avctx, AV_LOG_WARNING,
+                   "unsupported number of top front channels: %d\n",
+                   channel_counts[ACT_FRONT_TOP]);
+            ch_error = 1;
+            break;
+        }
+    }
 
     av_channel_layout_uninit(&avctx->ch_layout);
     av_channel_layout_from_mask(&avctx->ch_layout, ch_layout);
@@ -295,6 +318,12 @@ static av_cold int fdk_aac_decode_init(AVCodecContext 
*avctx)
                }
             }
         }
+#if FDKDEC_VER_AT_LEAST(2, 5)
+    } else {
+        if (aacDecoder_SetParam(s->handle, AAC_PCM_MAX_OUTPUT_CHANNELS, 0) != 
AAC_DEC_OK ||
+            aacDecoder_SetParam(s->handle, AAC_PCM_MIN_OUTPUT_CHANNELS, 0) != 
AAC_DEC_OK)
+           av_log(avctx, AV_LOG_WARNING, "Unable to set output channels in the 
decoder\n");
+#endif
     }
 
     if (s->drc_boost != -1) {
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to