| /* | |
| * Immersive Audio Model and Formats common helpers and structs | |
| * Copyright (c) 2023 James Almer <jamrial@gmail.com> | |
| * | |
| * This file is part of FFmpeg. | |
| * | |
| * FFmpeg is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU Lesser General Public | |
| * License as published by the Free Software Foundation; either | |
| * version 2.1 of the License, or (at your option) any later version. | |
| * | |
| * FFmpeg is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| * Lesser General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Lesser General Public | |
| * License along with FFmpeg; if not, write to the Free Software | |
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| */ | |
| #include "libavutil/channel_layout.h" | |
| #include "libavutil/iamf.h" | |
| #include "libavutil/mem.h" | |
| #include "iamf.h" | |
| const AVChannelLayout ff_iamf_scalable_ch_layouts[10] = { | |
| AV_CHANNEL_LAYOUT_MONO, | |
| AV_CHANNEL_LAYOUT_STEREO, | |
| // "Loudspeaker configuration for Sound System B" | |
| AV_CHANNEL_LAYOUT_5POINT1_BACK, | |
| // "Loudspeaker configuration for Sound System C" | |
| AV_CHANNEL_LAYOUT_5POINT1POINT2_BACK, | |
| // "Loudspeaker configuration for Sound System D" | |
| AV_CHANNEL_LAYOUT_5POINT1POINT4_BACK, | |
| // "Loudspeaker configuration for Sound System I" | |
| AV_CHANNEL_LAYOUT_7POINT1, | |
| // "Loudspeaker configuration for Sound System I" + Ltf + Rtf | |
| AV_CHANNEL_LAYOUT_7POINT1POINT2, | |
| // "Loudspeaker configuration for Sound System J" | |
| AV_CHANNEL_LAYOUT_7POINT1POINT4_BACK, | |
| // Front subset of "Loudspeaker configuration for Sound System J" | |
| AV_CHANNEL_LAYOUT_3POINT1POINT2, | |
| // Binaural | |
| AV_CHANNEL_LAYOUT_STEREO, | |
| }; | |
| const struct IAMFSoundSystemMap ff_iamf_sound_system_map[13] = { | |
| { 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 }, | |
| { SOUND_SYSTEM_D_4_5_0, AV_CHANNEL_LAYOUT_5POINT1POINT4_BACK }, | |
| { SOUND_SYSTEM_E_4_5_1, | |
| { | |
| .nb_channels = 11, | |
| .order = AV_CHANNEL_ORDER_NATIVE, | |
| .u.mask = AV_CH_LAYOUT_5POINT1POINT4_BACK | AV_CH_BOTTOM_FRONT_CENTER, | |
| }, | |
| }, | |
| { SOUND_SYSTEM_F_3_7_0, AV_CHANNEL_LAYOUT_7POINT2POINT3 }, | |
| { SOUND_SYSTEM_G_4_9_0, AV_CHANNEL_LAYOUT_9POINT1POINT4_BACK }, | |
| { SOUND_SYSTEM_H_9_10_3, AV_CHANNEL_LAYOUT_22POINT2 }, | |
| { SOUND_SYSTEM_I_0_7_0, AV_CHANNEL_LAYOUT_7POINT1 }, | |
| { SOUND_SYSTEM_J_4_7_0, AV_CHANNEL_LAYOUT_7POINT1POINT4_BACK }, | |
| { 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 }, | |
| }; | |
| void ff_iamf_free_audio_element(IAMFAudioElement **paudio_element) | |
| { | |
| IAMFAudioElement *audio_element = *paudio_element; | |
| if (!audio_element) | |
| return; | |
| for (int i = 0; i < audio_element->nb_substreams; i++) | |
| avcodec_parameters_free(&audio_element->substreams[i].codecpar); | |
| av_free(audio_element->substreams); | |
| av_free(audio_element->layers); | |
| av_iamf_audio_element_free(&audio_element->element); | |
| av_freep(paudio_element); | |
| } | |
| void ff_iamf_free_mix_presentation(IAMFMixPresentation **pmix_presentation) | |
| { | |
| IAMFMixPresentation *mix_presentation = *pmix_presentation; | |
| if (!mix_presentation) | |
| return; | |
| for (int i = 0; i < mix_presentation->count_label; i++) | |
| av_free(mix_presentation->language_label[i]); | |
| av_free(mix_presentation->language_label); | |
| av_iamf_mix_presentation_free(&mix_presentation->mix); | |
| av_freep(pmix_presentation); | |
| } | |
| void ff_iamf_uninit_context(IAMFContext *c) | |
| { | |
| if (!c) | |
| return; | |
| for (int i = 0; i < c->nb_codec_configs; i++) { | |
| av_free(c->codec_configs[i]->extradata); | |
| av_free(c->codec_configs[i]); | |
| } | |
| av_freep(&c->codec_configs); | |
| c->nb_codec_configs = 0; | |
| for (int i = 0; i < c->nb_audio_elements; i++) | |
| ff_iamf_free_audio_element(&c->audio_elements[i]); | |
| av_freep(&c->audio_elements); | |
| c->nb_audio_elements = 0; | |
| for (int i = 0; i < c->nb_mix_presentations; i++) | |
| ff_iamf_free_mix_presentation(&c->mix_presentations[i]); | |
| av_freep(&c->mix_presentations); | |
| c->nb_mix_presentations = 0; | |
| for (int i = 0; i < c->nb_param_definitions; i++) | |
| av_free(c->param_definitions[i]); | |
| av_freep(&c->param_definitions); | |
| c->nb_param_definitions = 0; | |
| } |