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

Defined in ISO/IEC 23008-3, for MPEG-H streams.


>From 50694fb4fc780662110c6eb6bbabfa4bf036da90 Mon Sep 17 00:00:00 2001
From: James Almer <[email protected]>
Date: Wed, 23 Sep 2026 11:01:32 -0300
Subject: [PATCH 1/4] avutil/channel_layout: add 5.1.6 and 7.1.6 layouts

Defined in ISO/IEC 23001-8 Table 9.

Signed-off-by: James Almer <[email protected]>
---
 libavutil/channel_layout.c | 2 ++
 libavutil/channel_layout.h | 4 ++++
 2 files changed, 6 insertions(+)

diff --git a/libavutil/channel_layout.c b/libavutil/channel_layout.c
index 53ac5cd56d..c1130b952a 100644
--- a/libavutil/channel_layout.c
+++ b/libavutil/channel_layout.c
@@ -219,8 +219,10 @@ static const struct channel_layout_name 
channel_layout_map[] = {
     { "octagonal",      AV_CHANNEL_LAYOUT_OCTAGONAL           },
     { "cube",           AV_CHANNEL_LAYOUT_CUBE                },
     { "5.1.4",          AV_CHANNEL_LAYOUT_5POINT1POINT4       },
+    { "5.1.6",          AV_CHANNEL_LAYOUT_5POINT1POINT6       },
     { "7.1.2",          AV_CHANNEL_LAYOUT_7POINT1POINT2       },
     { "7.1.4",          AV_CHANNEL_LAYOUT_7POINT1POINT4       },
+    { "7.1.6",          AV_CHANNEL_LAYOUT_7POINT1POINT6       },
     { "7.2.3",          AV_CHANNEL_LAYOUT_7POINT2POINT3       },
     { "9.1.4",          AV_CHANNEL_LAYOUT_9POINT1POINT4       },
     { "9.1.6",          AV_CHANNEL_LAYOUT_9POINT1POINT6       },
diff --git a/libavutil/channel_layout.h b/libavutil/channel_layout.h
index 534a23b78b..0004b5512d 100644
--- a/libavutil/channel_layout.h
+++ b/libavutil/channel_layout.h
@@ -245,8 +245,10 @@ enum AVChannelOrder {
 #define AV_CH_LAYOUT_OCTAGONAL         
(AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_CENTER|AV_CH_BACK_RIGHT)
 #define AV_CH_LAYOUT_CUBE              
(AV_CH_LAYOUT_QUAD|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT)
 #define AV_CH_LAYOUT_5POINT1POINT4     
(AV_CH_LAYOUT_5POINT1POINT2|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT)
+#define AV_CH_LAYOUT_5POINT1POINT6     
(AV_CH_LAYOUT_5POINT1POINT4|AV_CH_TOP_FRONT_CENTER|AV_CH_TOP_CENTER)
 #define AV_CH_LAYOUT_7POINT1POINT2     
(AV_CH_LAYOUT_7POINT1|AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT)
 #define AV_CH_LAYOUT_7POINT1POINT4     
(AV_CH_LAYOUT_7POINT1POINT2|AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_RIGHT)
+#define AV_CH_LAYOUT_7POINT1POINT6     
(AV_CH_LAYOUT_7POINT1POINT4|AV_CH_TOP_FRONT_CENTER|AV_CH_TOP_CENTER)
 #define AV_CH_LAYOUT_7POINT2POINT3     
(AV_CH_LAYOUT_7POINT1POINT2|AV_CH_TOP_BACK_CENTER|AV_CH_LOW_FREQUENCY_2)
 #define AV_CH_LAYOUT_9POINT1POINT4     
(AV_CH_LAYOUT_7POINT1POINT4|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER)
 #define AV_CH_LAYOUT_9POINT1POINT6     
(AV_CH_LAYOUT_9POINT1POINT4|AV_CH_TOP_SIDE_LEFT|AV_CH_TOP_SIDE_RIGHT)
@@ -431,8 +433,10 @@ typedef struct AVChannelLayout {
 #define AV_CHANNEL_LAYOUT_OCTAGONAL         AV_CHANNEL_LAYOUT_MASK(8,  
AV_CH_LAYOUT_OCTAGONAL)
 #define AV_CHANNEL_LAYOUT_CUBE              AV_CHANNEL_LAYOUT_MASK(8,  
AV_CH_LAYOUT_CUBE)
 #define AV_CHANNEL_LAYOUT_5POINT1POINT4     AV_CHANNEL_LAYOUT_MASK(10, 
AV_CH_LAYOUT_5POINT1POINT4)
+#define AV_CHANNEL_LAYOUT_5POINT1POINT6     AV_CHANNEL_LAYOUT_MASK(12, 
AV_CH_LAYOUT_5POINT1POINT6)
 #define AV_CHANNEL_LAYOUT_7POINT1POINT2     AV_CHANNEL_LAYOUT_MASK(10, 
AV_CH_LAYOUT_7POINT1POINT2)
 #define AV_CHANNEL_LAYOUT_7POINT1POINT4     AV_CHANNEL_LAYOUT_MASK(12, 
AV_CH_LAYOUT_7POINT1POINT4)
+#define AV_CHANNEL_LAYOUT_7POINT1POINT6     AV_CHANNEL_LAYOUT_MASK(14, 
AV_CH_LAYOUT_7POINT1POINT6)
 #define AV_CHANNEL_LAYOUT_7POINT2POINT3     AV_CHANNEL_LAYOUT_MASK(12, 
AV_CH_LAYOUT_7POINT2POINT3)
 #define AV_CHANNEL_LAYOUT_9POINT1POINT4     AV_CHANNEL_LAYOUT_MASK(14, 
AV_CH_LAYOUT_9POINT1POINT4)
 #define AV_CHANNEL_LAYOUT_9POINT1POINT6     AV_CHANNEL_LAYOUT_MASK(16, 
AV_CH_LAYOUT_9POINT1POINT6)
-- 
2.52.0


>From b5b7097b4ec8250c937246c4203d6489e388fe7d Mon Sep 17 00:00:00 2001
From: James Almer <[email protected]>
Date: Wed, 23 Sep 2026 11:04:40 -0300
Subject: [PATCH 2/4] avcodec/libmpeghdec: use the new layout defines

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

diff --git a/libavcodec/libmpeghdec.c b/libavcodec/libmpeghdec.c
index ecc3a2dc09..58a37599a4 100644
--- a/libavcodec/libmpeghdec.c
+++ b/libavcodec/libmpeghdec.c
@@ -68,14 +68,6 @@ static av_cold int mpegh3dadec_close(AVCodecContext *avctx)
 // 
https://github.com/Fraunhofer-IIS/mpeghdec/wiki/MPEG-H-decoder-target-layouts
 static av_cold int channel_layout_to_cicp(const AVChannelLayout *layout)
 {
-// different from AV_CH_LAYOUT_7POINT2POINT3
-#define CH_LAYOUT_7POINT2POINT3 AV_CH_LAYOUT_5POINT1POINT2 | 
AV_CH_SIDE_SURROUND_LEFT | \
-                                AV_CH_SIDE_SURROUND_RIGHT | 
AV_CH_TOP_BACK_CENTER |     \
-                                AV_CH_LOW_FREQUENCY_2
-#define CH_LAYOUT_5POINT1POINT6 AV_CH_LAYOUT_5POINT1POINT4_BACK | \
-                                AV_CH_TOP_FRONT_CENTER | AV_CH_TOP_CENTER
-#define CH_LAYOUT_7POINT1POINT6 AV_CH_LAYOUT_7POINT1POINT4_BACK | \
-                                AV_CH_TOP_FRONT_CENTER | AV_CH_TOP_CENTER
     static const uint64_t channel_layout_masks[] = {
         0,
         AV_CH_LAYOUT_MONO,               AV_CH_LAYOUT_STEREO,
@@ -85,9 +77,9 @@ static av_cold int channel_layout_to_cicp(const 
AVChannelLayout *layout)
         AV_CH_LAYOUT_2_1,                AV_CH_LAYOUT_2_2,
         AV_CH_LAYOUT_6POINT1,            AV_CH_LAYOUT_7POINT1,
         AV_CH_LAYOUT_22POINT2,           AV_CH_LAYOUT_5POINT1POINT2,
-        CH_LAYOUT_7POINT2POINT3,         AV_CH_LAYOUT_5POINT1POINT4_BACK,
-        CH_LAYOUT_5POINT1POINT6,         CH_LAYOUT_7POINT1POINT6,
-        AV_CH_LAYOUT_7POINT1POINT4_BACK,
+        AV_CH_LAYOUT_7POINT2POINT3,      AV_CH_LAYOUT_5POINT1POINT4,
+        AV_CH_LAYOUT_5POINT1POINT6,      AV_CH_LAYOUT_7POINT1POINT6,
+        AV_CH_LAYOUT_7POINT1POINT4,
     };
     for (size_t i = 0; i < FF_ARRAY_ELEMS(channel_layout_masks); ++i) {
         if (channel_layout_masks[i]) {
-- 
2.52.0


>From de87db170c714f001220a344445fa7d71881f6e3 Mon Sep 17 00:00:00 2001
From: James Almer <[email protected]>
Date: Wed, 23 Sep 2026 11:08:37 -0300
Subject: [PATCH 3/4] avcodec/libmpeghdec: remove AV_CODEC_CAP_CHANNEL_CONF
 capability

The decoder does not set channel layout, and will fail if not set by the caller.

Signed-off-by: James Almer <[email protected]>
---
 libavcodec/libmpeghdec.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/libavcodec/libmpeghdec.c b/libavcodec/libmpeghdec.c
index 58a37599a4..d424e34cb8 100644
--- a/libavcodec/libmpeghdec.c
+++ b/libavcodec/libmpeghdec.c
@@ -211,8 +211,7 @@ const FFCodec ff_libmpeghdec_decoder = {
     CODEC_LONG_NAME("libmpeghdec (MPEG-H 3D Audio)"),
     .p.type         = AVMEDIA_TYPE_AUDIO,
     .p.id           = AV_CODEC_ID_MPEGH_3D_AUDIO,
-    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
-                      AV_CODEC_CAP_CHANNEL_CONF,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
     .priv_data_size = sizeof(MPEGH3DADecContext),
     .init           = mpegh3dadec_init,
-- 
2.52.0


>From a293f00c6c9bc8e32e02d8b7ce11ae57ad33eaf8 Mon Sep 17 00:00:00 2001
From: James Almer <[email protected]>
Date: Wed, 23 Sep 2026 11:09:52 -0300
Subject: [PATCH 4/4] avformat/mov: parse mhaC box

Defined in ISO/IEC 23008-3, for MPEG-H streams.

Signed-off-by: James Almer <[email protected]>
---
 libavformat/mov.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 8ddedf269b..f502702b66 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -10040,6 +10040,48 @@ static int mov_read_vmhd(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
     return 0;
 }
 
+static int mov_read_mhac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+    AVFormatContext *ctx = c->fc;
+    AVStream *st;
+    static const uint64_t channel_layout_masks[] = {
+        0,
+        AV_CH_LAYOUT_MONO,               AV_CH_LAYOUT_STEREO,
+        AV_CH_LAYOUT_SURROUND,           AV_CH_LAYOUT_4POINT0,
+        AV_CH_LAYOUT_5POINT0,            AV_CH_LAYOUT_5POINT1,
+        AV_CH_LAYOUT_7POINT1_WIDE,       0,
+        AV_CH_LAYOUT_2_1,                AV_CH_LAYOUT_2_2,
+        AV_CH_LAYOUT_6POINT1,            AV_CH_LAYOUT_7POINT1,
+        AV_CH_LAYOUT_22POINT2,           AV_CH_LAYOUT_5POINT1POINT2,
+        AV_CH_LAYOUT_7POINT2POINT3,      AV_CH_LAYOUT_5POINT1POINT4_BACK,
+        AV_CH_LAYOUT_5POINT1POINT6,      AV_CH_LAYOUT_7POINT1POINT6,
+        AV_CH_LAYOUT_7POINT1POINT4_BACK,
+    };
+    uint64_t mask;
+    int reference_ch_layout;
+
+    if (ctx->nb_streams < 1)
+        return 0;
+
+    st = ctx->streams[ctx->nb_streams - 1];
+    if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
+        return 0;
+
+    if (avio_r8(pb) != 1)
+        return 0;
+
+    avio_skip(pb, 1);
+    reference_ch_layout = avio_r8(pb);
+    if (!reference_ch_layout || reference_ch_layout >= 
FF_ARRAY_ELEMS(channel_layout_masks)) {
+        av_log(ctx, AV_LOG_WARNING, "Unknown referenceChannelLayout value: 
%d\n", reference_ch_layout);
+        return 0;
+    }
+
+    av_channel_layout_from_mask(&st->codecpar->ch_layout, 
channel_layout_masks[reference_ch_layout]);
+
+    return 0;
+}
+
 static const MOVParseTableEntry mov_default_parse_table[] = {
 { MKTAG('A','C','L','R'), mov_read_aclr },
 { MKTAG('A','P','R','G'), mov_read_avid },
@@ -10172,6 +10214,7 @@ static const MOVParseTableEntry 
mov_default_parse_table[] = {
 #endif
 { MKTAG('s','r','a','t'), mov_read_srat },
 { MKTAG('v','m','h','d'), mov_read_vmhd },
+{ MKTAG('m','h','a','C'), mov_read_mhac },
 { 0, NULL }
 };
 
-- 
2.52.0

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

Reply via email to