[FFmpeg-devel] [PATCH 3/5] avformat/iamf_parse: add support for expanded channel layouts

James Almer jamrial at gmail.com
Tue Dec 10 16:02:56 EET 2024


Defined in Immersive Audio Model and Formats 1.1.0, sections 3.6.2 and 3.7.3

Signed-off-by: James Almer <jamrial at gmail.com>
---
 libavformat/iamf.c       | 62 +++++++++++++++++++++++++++++++++++++++-
 libavformat/iamf.h       |  4 ++-
 libavformat/iamf_parse.c |  7 ++++-
 3 files changed, 70 insertions(+), 3 deletions(-)

diff --git a/libavformat/iamf.c b/libavformat/iamf.c
index 3fcf145a85..a01c99ea67 100644
--- a/libavformat/iamf.c
+++ b/libavformat/iamf.c
@@ -45,7 +45,66 @@ const AVChannelLayout ff_iamf_scalable_ch_layouts[10] = {
     AV_CHANNEL_LAYOUT_BINAURAL,
 };
 
-const struct IAMFSoundSystemMap ff_iamf_sound_system_map[13] = {
+const AVChannelLayout ff_iamf_expanded_scalable_ch_layouts[13] = {
+    {
+        .nb_channels = 1,
+        .order       = AV_CHANNEL_ORDER_NATIVE,
+        .u.mask      = AV_CH_LOW_FREQUENCY,
+    },
+    {
+        .nb_channels = 2,
+        .order       = AV_CHANNEL_ORDER_NATIVE,
+        .u.mask      = AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT,
+    },
+    {
+        .nb_channels = 2,
+        .order       = AV_CHANNEL_ORDER_NATIVE,
+        .u.mask      = AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT,
+    },
+    {
+        .nb_channels = 2,
+        .order       = AV_CHANNEL_ORDER_NATIVE,
+        .u.mask      = AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT,
+    },
+    {
+        .nb_channels = 2,
+        .order       = AV_CHANNEL_ORDER_NATIVE,
+        .u.mask      = AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT,
+    },
+    {
+        .nb_channels = 2,
+        .order       = AV_CHANNEL_ORDER_NATIVE,
+        .u.mask      = AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT,
+    },
+    {
+        .nb_channels = 4,
+        .order       = AV_CHANNEL_ORDER_NATIVE,
+        .u.mask      = AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT |
+                       AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT,
+    },
+    AV_CHANNEL_LAYOUT_SURROUND,
+    AV_CHANNEL_LAYOUT_9POINT1POINT6,
+    AV_CHANNEL_LAYOUT_STEREO,
+    {
+        .nb_channels = 2,
+        .order       = AV_CHANNEL_ORDER_NATIVE,
+        .u.mask      = AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT,
+    },
+    {
+        .nb_channels = 2,
+        .order       = AV_CHANNEL_ORDER_NATIVE,
+        .u.mask      = AV_CH_TOP_SIDE_LEFT | AV_CH_TOP_SIDE_RIGHT,
+    },
+    {
+        .nb_channels = 6,
+        .order       = AV_CHANNEL_ORDER_NATIVE,
+        .u.mask      = AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT |
+                       AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT |
+                       AV_CH_TOP_SIDE_LEFT | AV_CH_TOP_SIDE_RIGHT,
+    },
+};
+
+const struct IAMFSoundSystemMap ff_iamf_sound_system_map[14] = {
     { SOUND_SYSTEM_A_0_2_0, AV_CHANNEL_LAYOUT_STEREO },
     { SOUND_SYSTEM_B_0_5_0, AV_CHANNEL_LAYOUT_5POINT1_BACK },
     { SOUND_SYSTEM_C_2_5_0, AV_CHANNEL_LAYOUT_5POINT1POINT2_BACK },
@@ -65,6 +124,7 @@ const struct IAMFSoundSystemMap ff_iamf_sound_system_map[13] = {
     { SOUND_SYSTEM_10_2_7_0, AV_CHANNEL_LAYOUT_7POINT1POINT2 },
     { SOUND_SYSTEM_11_2_3_0, AV_CHANNEL_LAYOUT_3POINT1POINT2 },
     { SOUND_SYSTEM_12_0_1_0, AV_CHANNEL_LAYOUT_MONO },
+    { SOUND_SYSTEM_13_9_1_6, AV_CHANNEL_LAYOUT_9POINT1POINT6 },
 };
 
 void ff_iamf_free_audio_element(IAMFAudioElement **paudio_element)
diff --git a/libavformat/iamf.h b/libavformat/iamf.h
index fd8b57a096..ad874c1fa8 100644
--- a/libavformat/iamf.h
+++ b/libavformat/iamf.h
@@ -156,6 +156,7 @@ enum IAMF_Sound_System {
     SOUND_SYSTEM_10_2_7_0 = 10, // "Loudspeaker configuration for Sound System I" + Ltf + Rtf
     SOUND_SYSTEM_11_2_3_0 = 11, // Front subset of "Loudspeaker configuration for Sound System J"
     SOUND_SYSTEM_12_0_1_0 = 12, // Mono
+    SOUND_SYSTEM_13_9_1_6 = 13, // Subset of "Loudspeaker configuration for Sound System H"
 };
 
 struct IAMFSoundSystemMap {
@@ -165,7 +166,8 @@ struct IAMFSoundSystemMap {
 
 FF_VISIBILITY_PUSH_HIDDEN
 extern const AVChannelLayout ff_iamf_scalable_ch_layouts[10];
-extern const struct IAMFSoundSystemMap ff_iamf_sound_system_map[13];
+extern const AVChannelLayout ff_iamf_expanded_scalable_ch_layouts[13];
+extern const struct IAMFSoundSystemMap ff_iamf_sound_system_map[14];
 
 static inline IAMFCodecConfig *ff_iamf_get_codec_config(const IAMFContext *c,
                                                         unsigned int codec_config_id)
diff --git a/libavformat/iamf_parse.c b/libavformat/iamf_parse.c
index 1e1de167e6..6c2efc0a6c 100644
--- a/libavformat/iamf_parse.c
+++ b/libavformat/iamf_parse.c
@@ -356,6 +356,7 @@ static int scalable_channel_layout_config(void *s, AVIOContext *pb,
         AVIAMFLayer *layer;
         int loudspeaker_layout, output_gain_is_present_flag;
         int substream_count, coupled_substream_count;
+        int expanded_loudspeaker_layout = -1;
         int ret, byte = avio_r8(pb);
 
         layer = av_iamf_audio_element_add_layer(audio_element->element);
@@ -379,7 +380,11 @@ static int scalable_channel_layout_config(void *s, AVIOContext *pb,
             layer->output_gain = av_make_q(sign_extend(avio_rb16(pb), 16), 1 << 8);
         }
 
-        if (loudspeaker_layout < 10)
+        if (!i && loudspeaker_layout == 15)
+            expanded_loudspeaker_layout = avio_r8(pb);
+        if (expanded_loudspeaker_layout > 0 && expanded_loudspeaker_layout < 13)
+            av_channel_layout_copy(&layer->ch_layout, &ff_iamf_expanded_scalable_ch_layouts[expanded_loudspeaker_layout]);
+        else if (loudspeaker_layout < 10)
             av_channel_layout_copy(&layer->ch_layout, &ff_iamf_scalable_ch_layouts[loudspeaker_layout]);
         else
             layer->ch_layout = (AVChannelLayout){ .order = AV_CHANNEL_ORDER_UNSPEC,
-- 
2.47.1



More information about the ffmpeg-devel mailing list