From d255f902428665d545cf325a0cb6740193b276eb Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 10 Dec 2024 10:01:09 -0300 Subject: [PATCH] avformat/iamf_parse: add support for expanded channel layouts Defined in Immersive Audio Model and Formats 1.1.0, sections 3.6.2 and 3.7.3 Signed-off-by: James Almer --- 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,