| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * Immersive Audio Model and Formats common helpers and structs | ||
| 3 | * Copyright (c) 2023 James Almer <jamrial@gmail.com> | ||
| 4 | * | ||
| 5 | * This file is part of FFmpeg. | ||
| 6 | * | ||
| 7 | * FFmpeg is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU Lesser General Public | ||
| 9 | * License as published by the Free Software Foundation; either | ||
| 10 | * version 2.1 of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | * FFmpeg is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | * Lesser General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU Lesser General Public | ||
| 18 | * License along with FFmpeg; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include "libavutil/channel_layout.h" | ||
| 23 | #include "libavutil/iamf.h" | ||
| 24 | #include "libavutil/mem.h" | ||
| 25 | #include "iamf.h" | ||
| 26 | |||
| 27 | const AVChannelLayout ff_iamf_scalable_ch_layouts[10] = { | ||
| 28 | AV_CHANNEL_LAYOUT_MONO, | ||
| 29 | AV_CHANNEL_LAYOUT_STEREO, | ||
| 30 | // "Loudspeaker configuration for Sound System B" | ||
| 31 | AV_CHANNEL_LAYOUT_5POINT1, | ||
| 32 | // "Loudspeaker configuration for Sound System C" | ||
| 33 | AV_CHANNEL_LAYOUT_5POINT1POINT2, | ||
| 34 | // "Loudspeaker configuration for Sound System D" | ||
| 35 | AV_CHANNEL_LAYOUT_5POINT1POINT4_BACK, | ||
| 36 | // "Loudspeaker configuration for Sound System I" | ||
| 37 | AV_CHANNEL_LAYOUT_7POINT1, | ||
| 38 | // "Loudspeaker configuration for Sound System I" + Ltf + Rtf | ||
| 39 | AV_CHANNEL_LAYOUT_7POINT1POINT2, | ||
| 40 | // "Loudspeaker configuration for Sound System J" | ||
| 41 | AV_CHANNEL_LAYOUT_7POINT1POINT4_BACK, | ||
| 42 | // Front subset of "Loudspeaker configuration for Sound System J" | ||
| 43 | AV_CHANNEL_LAYOUT_3POINT1POINT2, | ||
| 44 | // Binaural | ||
| 45 | AV_CHANNEL_LAYOUT_BINAURAL, | ||
| 46 | }; | ||
| 47 | |||
| 48 | const AVChannelLayout ff_iamf_expanded_scalable_ch_layouts[13] = { | ||
| 49 | // The low-frequency effects subset (LFE) of "Loudspeaker configuration for Sound System J" | ||
| 50 | { | ||
| 51 | .nb_channels = 1, | ||
| 52 | .order = AV_CHANNEL_ORDER_NATIVE, | ||
| 53 | .u.mask = AV_CH_LOW_FREQUENCY, | ||
| 54 | }, | ||
| 55 | // The surround subset (Ls/Rs) of "Loudspeaker configuration for Sound System I" | ||
| 56 | { | ||
| 57 | .nb_channels = 2, | ||
| 58 | .order = AV_CHANNEL_ORDER_NATIVE, | ||
| 59 | .u.mask = AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT, | ||
| 60 | }, | ||
| 61 | // The side surround subset (Lss/Rss) of "Loudspeaker configuration for Sound System J" | ||
| 62 | { | ||
| 63 | .nb_channels = 2, | ||
| 64 | .order = AV_CHANNEL_ORDER_NATIVE, | ||
| 65 | .u.mask = AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT, | ||
| 66 | }, | ||
| 67 | // The rear surround subset (Lrs/Rrs) of "Loudspeaker configuration for Sound System J" | ||
| 68 | { | ||
| 69 | .nb_channels = 2, | ||
| 70 | .order = AV_CHANNEL_ORDER_NATIVE, | ||
| 71 | .u.mask = AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT, | ||
| 72 | }, | ||
| 73 | // The top front subset (Ltf/Rtf) of "Loudspeaker configuration for Sound System J" | ||
| 74 | { | ||
| 75 | .nb_channels = 2, | ||
| 76 | .order = AV_CHANNEL_ORDER_NATIVE, | ||
| 77 | .u.mask = AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT, | ||
| 78 | }, | ||
| 79 | // The top back subset (Ltb/Rtb) of "Loudspeaker configuration for Sound System J" | ||
| 80 | { | ||
| 81 | .nb_channels = 2, | ||
| 82 | .order = AV_CHANNEL_ORDER_NATIVE, | ||
| 83 | .u.mask = AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT, | ||
| 84 | }, | ||
| 85 | // The top 4 channels (Ltf/Rtf/Ltb/Rtb) of "Loudspeaker configuration for Sound System J" | ||
| 86 | { | ||
| 87 | .nb_channels = 4, | ||
| 88 | .order = AV_CHANNEL_ORDER_NATIVE, | ||
| 89 | .u.mask = AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT | | ||
| 90 | AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT, | ||
| 91 | }, | ||
| 92 | // The front 3 channels (L/C/R) of "Loudspeaker configuration for Sound System J" | ||
| 93 | AV_CHANNEL_LAYOUT_SURROUND, | ||
| 94 | // Subset of "Loudspeaker configuration for Sound System H" | ||
| 95 | AV_CHANNEL_LAYOUT_9POINT1POINT6, | ||
| 96 | // Front subset of "Loudspeaker configuration for Sound System H" | ||
| 97 | AV_CHANNEL_LAYOUT_STEREO, | ||
| 98 | // The side subset (SiL/SiR) of "Loudspeaker configuration for Sound System H" | ||
| 99 | { | ||
| 100 | .nb_channels = 2, | ||
| 101 | .order = AV_CHANNEL_ORDER_NATIVE, | ||
| 102 | .u.mask = AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT, | ||
| 103 | }, | ||
| 104 | // The top side subset (TpSiL/TpSiR) of "Loudspeaker configuration for Sound System H" | ||
| 105 | { | ||
| 106 | .nb_channels = 2, | ||
| 107 | .order = AV_CHANNEL_ORDER_NATIVE, | ||
| 108 | .u.mask = AV_CH_TOP_SIDE_LEFT | AV_CH_TOP_SIDE_RIGHT, | ||
| 109 | }, | ||
| 110 | // The top 6 channels (TpFL/TpFR/TpSiL/TpSiR/TpBL/TpBR) of "Loudspeaker configuration for Sound System H" | ||
| 111 | { | ||
| 112 | .nb_channels = 6, | ||
| 113 | .order = AV_CHANNEL_ORDER_NATIVE, | ||
| 114 | .u.mask = AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT | | ||
| 115 | AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT | | ||
| 116 | AV_CH_TOP_SIDE_LEFT | AV_CH_TOP_SIDE_RIGHT, | ||
| 117 | }, | ||
| 118 | }; | ||
| 119 | |||
| 120 | const struct IAMFSoundSystemMap ff_iamf_sound_system_map[14] = { | ||
| 121 | { SOUND_SYSTEM_A_0_2_0, AV_CHANNEL_LAYOUT_STEREO }, | ||
| 122 | { SOUND_SYSTEM_B_0_5_0, AV_CHANNEL_LAYOUT_5POINT1 }, | ||
| 123 | { SOUND_SYSTEM_C_2_5_0, AV_CHANNEL_LAYOUT_5POINT1POINT2 }, | ||
| 124 | { SOUND_SYSTEM_D_4_5_0, AV_CHANNEL_LAYOUT_5POINT1POINT4_BACK }, | ||
| 125 | { SOUND_SYSTEM_E_4_5_1, | ||
| 126 | { | ||
| 127 | .nb_channels = 11, | ||
| 128 | .order = AV_CHANNEL_ORDER_NATIVE, | ||
| 129 | .u.mask = AV_CH_LAYOUT_5POINT1POINT4_BACK | AV_CH_BOTTOM_FRONT_CENTER, | ||
| 130 | }, | ||
| 131 | }, | ||
| 132 | { SOUND_SYSTEM_F_3_7_0, AV_CHANNEL_LAYOUT_7POINT2POINT3 }, | ||
| 133 | { SOUND_SYSTEM_G_4_9_0, AV_CHANNEL_LAYOUT_9POINT1POINT4_BACK }, | ||
| 134 | { SOUND_SYSTEM_H_9_10_3, AV_CHANNEL_LAYOUT_22POINT2 }, | ||
| 135 | { SOUND_SYSTEM_I_0_7_0, AV_CHANNEL_LAYOUT_7POINT1 }, | ||
| 136 | { SOUND_SYSTEM_J_4_7_0, AV_CHANNEL_LAYOUT_7POINT1POINT4_BACK }, | ||
| 137 | { SOUND_SYSTEM_10_2_7_0, AV_CHANNEL_LAYOUT_7POINT1POINT2 }, | ||
| 138 | { SOUND_SYSTEM_11_2_3_0, AV_CHANNEL_LAYOUT_3POINT1POINT2 }, | ||
| 139 | { SOUND_SYSTEM_12_0_1_0, AV_CHANNEL_LAYOUT_MONO }, | ||
| 140 | { SOUND_SYSTEM_13_9_1_6, AV_CHANNEL_LAYOUT_9POINT1POINT6 }, | ||
| 141 | }; | ||
| 142 | |||
| 143 | 52 | void ff_iamf_free_audio_element(IAMFAudioElement **paudio_element) | |
| 144 | { | ||
| 145 | 52 | IAMFAudioElement *audio_element = *paudio_element; | |
| 146 | |||
| 147 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
|
52 | if (!audio_element) |
| 148 | ✗ | return; | |
| 149 | |||
| 150 |
2/2✓ Branch 0 taken 235 times.
✓ Branch 1 taken 52 times.
|
287 | for (int i = 0; i < audio_element->nb_substreams; i++) |
| 151 | 235 | avcodec_parameters_free(&audio_element->substreams[i].codecpar); | |
| 152 | 52 | av_free(audio_element->substreams); | |
| 153 | 52 | av_free(audio_element->layers); | |
| 154 | 52 | av_iamf_audio_element_free(&audio_element->element); | |
| 155 | 52 | av_freep(paudio_element); | |
| 156 | } | ||
| 157 | |||
| 158 | 49 | void ff_iamf_free_mix_presentation(IAMFMixPresentation **pmix_presentation) | |
| 159 | { | ||
| 160 | 49 | IAMFMixPresentation *mix_presentation = *pmix_presentation; | |
| 161 | |||
| 162 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
|
49 | if (!mix_presentation) |
| 163 | ✗ | return; | |
| 164 | |||
| 165 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 49 times.
|
85 | for (int i = 0; i < mix_presentation->count_label; i++) |
| 166 | 36 | av_free(mix_presentation->language_label[i]); | |
| 167 | 49 | av_free(mix_presentation->language_label); | |
| 168 | 49 | av_iamf_mix_presentation_free(&mix_presentation->mix); | |
| 169 | 49 | av_freep(pmix_presentation); | |
| 170 | } | ||
| 171 | |||
| 172 | 49 | void ff_iamf_uninit_context(IAMFContext *c) | |
| 173 | { | ||
| 174 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
|
49 | if (!c) |
| 175 | ✗ | return; | |
| 176 | |||
| 177 |
2/2✓ Branch 0 taken 49 times.
✓ Branch 1 taken 49 times.
|
98 | for (int i = 0; i < c->nb_codec_configs; i++) { |
| 178 | 49 | av_free(c->codec_configs[i]->extradata); | |
| 179 | 49 | av_free(c->codec_configs[i]); | |
| 180 | } | ||
| 181 | 49 | av_freep(&c->codec_configs); | |
| 182 | 49 | c->nb_codec_configs = 0; | |
| 183 | |||
| 184 |
2/2✓ Branch 0 taken 52 times.
✓ Branch 1 taken 49 times.
|
101 | for (int i = 0; i < c->nb_audio_elements; i++) |
| 185 | 52 | ff_iamf_free_audio_element(&c->audio_elements[i]); | |
| 186 | 49 | av_freep(&c->audio_elements); | |
| 187 | 49 | c->nb_audio_elements = 0; | |
| 188 | |||
| 189 |
2/2✓ Branch 0 taken 49 times.
✓ Branch 1 taken 49 times.
|
98 | for (int i = 0; i < c->nb_mix_presentations; i++) |
| 190 | 49 | ff_iamf_free_mix_presentation(&c->mix_presentations[i]); | |
| 191 | 49 | av_freep(&c->mix_presentations); | |
| 192 | 49 | c->nb_mix_presentations = 0; | |
| 193 | |||
| 194 |
2/2✓ Branch 0 taken 99 times.
✓ Branch 1 taken 49 times.
|
148 | for (int i = 0; i < c->nb_param_definitions; i++) |
| 195 | 99 | av_free(c->param_definitions[i]); | |
| 196 | 49 | av_freep(&c->param_definitions); | |
| 197 | 49 | c->nb_param_definitions = 0; | |
| 198 | } | ||
| 199 |