FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/iamf.c
Date: 2025-01-20 09:27:23
Exec Total Coverage
Lines: 36 39 92.3%
Functions: 3 3 100.0%
Branches: 15 18 83.3%

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 41 void ff_iamf_free_audio_element(IAMFAudioElement **paudio_element)
144 {
145 41 IAMFAudioElement *audio_element = *paudio_element;
146
147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if (!audio_element)
148 return;
149
150
2/2
✓ Branch 0 taken 185 times.
✓ Branch 1 taken 41 times.
226 for (int i = 0; i < audio_element->nb_substreams; i++)
151 185 avcodec_parameters_free(&audio_element->substreams[i].codecpar);
152 41 av_free(audio_element->substreams);
153 41 av_free(audio_element->layers);
154 41 av_iamf_audio_element_free(&audio_element->element);
155 41 av_freep(paudio_element);
156 }
157
158 38 void ff_iamf_free_mix_presentation(IAMFMixPresentation **pmix_presentation)
159 {
160 38 IAMFMixPresentation *mix_presentation = *pmix_presentation;
161
162
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (!mix_presentation)
163 return;
164
165
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 38 times.
65 for (int i = 0; i < mix_presentation->count_label; i++)
166 27 av_free(mix_presentation->language_label[i]);
167 38 av_free(mix_presentation->language_label);
168 38 av_iamf_mix_presentation_free(&mix_presentation->mix);
169 38 av_freep(pmix_presentation);
170 }
171
172 38 void ff_iamf_uninit_context(IAMFContext *c)
173 {
174
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (!c)
175 return;
176
177
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 38 times.
76 for (int i = 0; i < c->nb_codec_configs; i++) {
178 38 av_free(c->codec_configs[i]->extradata);
179 38 av_free(c->codec_configs[i]);
180 }
181 38 av_freep(&c->codec_configs);
182 38 c->nb_codec_configs = 0;
183
184
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 38 times.
79 for (int i = 0; i < c->nb_audio_elements; i++)
185 41 ff_iamf_free_audio_element(&c->audio_elements[i]);
186 38 av_freep(&c->audio_elements);
187 38 c->nb_audio_elements = 0;
188
189
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 38 times.
76 for (int i = 0; i < c->nb_mix_presentations; i++)
190 38 ff_iamf_free_mix_presentation(&c->mix_presentations[i]);
191 38 av_freep(&c->mix_presentations);
192 38 c->nb_mix_presentations = 0;
193
194
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 38 times.
116 for (int i = 0; i < c->nb_param_definitions; i++)
195 78 av_free(c->param_definitions[i]);
196 38 av_freep(&c->param_definitions);
197 38 c->nb_param_definitions = 0;
198 }
199