FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/iamf_parse.c
Date: 2024-05-03 15:42:48
Exec Total Coverage
Lines: 424 682 62.2%
Functions: 12 14 85.7%
Branches: 178 352 50.6%

Line Branch Exec Source
1 /*
2 * Immersive Audio Model and Formats parsing
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/avassert.h"
23 #include "libavutil/iamf.h"
24 #include "libavutil/intreadwrite.h"
25 #include "libavutil/log.h"
26 #include "libavutil/mem.h"
27 #include "libavcodec/get_bits.h"
28 #include "libavcodec/flac.h"
29 #include "libavcodec/leb.h"
30 #include "libavcodec/mpeg4audio.h"
31 #include "libavcodec/put_bits.h"
32 #include "avio_internal.h"
33 #include "iamf_parse.h"
34 #include "isom.h"
35
36 5 static int opus_decoder_config(IAMFCodecConfig *codec_config,
37 AVIOContext *pb, int len)
38 {
39 5 int left = len - avio_tell(pb);
40
41
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (left < 11)
42 return AVERROR_INVALIDDATA;
43
44 5 codec_config->extradata = av_malloc(left + 8);
45
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (!codec_config->extradata)
46 return AVERROR(ENOMEM);
47
48 5 AV_WB32(codec_config->extradata, MKBETAG('O','p','u','s'));
49 5 AV_WB32(codec_config->extradata + 4, MKBETAG('H','e','a','d'));
50 5 codec_config->extradata_size = avio_read(pb, codec_config->extradata + 8, left);
51
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (codec_config->extradata_size < left)
52 return AVERROR_INVALIDDATA;
53
54 5 codec_config->extradata_size += 8;
55 5 codec_config->sample_rate = 48000;
56
57 5 return 0;
58 }
59
60 static int aac_decoder_config(IAMFCodecConfig *codec_config,
61 AVIOContext *pb, int len, void *logctx)
62 {
63 MPEG4AudioConfig cfg = { 0 };
64 int object_type_id, codec_id, stream_type;
65 int ret, tag, left;
66
67 tag = avio_r8(pb);
68 if (tag != MP4DecConfigDescrTag)
69 return AVERROR_INVALIDDATA;
70
71 object_type_id = avio_r8(pb);
72 if (object_type_id != 0x40)
73 return AVERROR_INVALIDDATA;
74
75 stream_type = avio_r8(pb);
76 if (((stream_type >> 2) != 5) || ((stream_type >> 1) & 1))
77 return AVERROR_INVALIDDATA;
78
79 avio_skip(pb, 3); // buffer size db
80 avio_skip(pb, 4); // rc_max_rate
81 avio_skip(pb, 4); // avg bitrate
82
83 codec_id = ff_codec_get_id(ff_mp4_obj_type, object_type_id);
84 if (codec_id && codec_id != codec_config->codec_id)
85 return AVERROR_INVALIDDATA;
86
87 tag = avio_r8(pb);
88 if (tag != MP4DecSpecificDescrTag)
89 return AVERROR_INVALIDDATA;
90
91 left = len - avio_tell(pb);
92 if (left <= 0)
93 return AVERROR_INVALIDDATA;
94
95 codec_config->extradata = av_malloc(left);
96 if (!codec_config->extradata)
97 return AVERROR(ENOMEM);
98
99 codec_config->extradata_size = avio_read(pb, codec_config->extradata, left);
100 if (codec_config->extradata_size < left)
101 return AVERROR_INVALIDDATA;
102
103 ret = avpriv_mpeg4audio_get_config2(&cfg, codec_config->extradata,
104 codec_config->extradata_size, 1, logctx);
105 if (ret < 0)
106 return ret;
107
108 codec_config->sample_rate = cfg.sample_rate;
109
110 return 0;
111 }
112
113 16 static int flac_decoder_config(IAMFCodecConfig *codec_config,
114 AVIOContext *pb, int len)
115 {
116 int left;
117
118 16 avio_skip(pb, 4); // METADATA_BLOCK_HEADER
119
120 16 left = len - avio_tell(pb);
121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (left < FLAC_STREAMINFO_SIZE)
122 return AVERROR_INVALIDDATA;
123
124 16 codec_config->extradata = av_malloc(left);
125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (!codec_config->extradata)
126 return AVERROR(ENOMEM);
127
128 16 codec_config->extradata_size = avio_read(pb, codec_config->extradata, left);
129
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (codec_config->extradata_size < left)
130 return AVERROR_INVALIDDATA;
131
132 16 codec_config->sample_rate = AV_RB24(codec_config->extradata + 10) >> 4;
133
134 16 return 0;
135 }
136
137 static int ipcm_decoder_config(IAMFCodecConfig *codec_config,
138 AVIOContext *pb, int len)
139 {
140 static const enum AVCodecID sample_fmt[2][3] = {
141 { AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S24BE, AV_CODEC_ID_PCM_S32BE },
142 { AV_CODEC_ID_PCM_S16LE, AV_CODEC_ID_PCM_S24LE, AV_CODEC_ID_PCM_S32LE },
143 };
144 int sample_format = avio_r8(pb); // 0 = BE, 1 = LE
145 int sample_size = (avio_r8(pb) / 8 - 2); // 16, 24, 32
146 if (sample_format > 1 || sample_size > 2)
147 return AVERROR_INVALIDDATA;
148
149 codec_config->codec_id = sample_fmt[sample_format][sample_size];
150 codec_config->sample_rate = avio_rb32(pb);
151
152 if (len - avio_tell(pb))
153 return AVERROR_INVALIDDATA;
154
155 return 0;
156 }
157
158 21 static int codec_config_obu(void *s, IAMFContext *c, AVIOContext *pb, int len)
159 {
160 21 IAMFCodecConfig **tmp, *codec_config = NULL;
161 FFIOContext b;
162 AVIOContext *pbc;
163 uint8_t *buf;
164 enum AVCodecID avcodec_id;
165 unsigned codec_config_id, nb_samples, codec_id;
166 int16_t seek_preroll;
167 int ret;
168
169 21 buf = av_malloc(len);
170
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (!buf)
171 return AVERROR(ENOMEM);
172
173 21 ret = avio_read(pb, buf, len);
174
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (ret != len) {
175 if (ret >= 0)
176 ret = AVERROR_INVALIDDATA;
177 goto fail;
178 }
179
180 21 ffio_init_context(&b, buf, len, 0, NULL, NULL, NULL, NULL);
181 21 pbc = &b.pub;
182
183 21 codec_config_id = ffio_read_leb(pbc);
184 21 codec_id = avio_rb32(pbc);
185 21 nb_samples = ffio_read_leb(pbc);
186 21 seek_preroll = avio_rb16(pbc);
187
188
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
21 switch(codec_id) {
189 5 case MKBETAG('O','p','u','s'):
190 5 avcodec_id = AV_CODEC_ID_OPUS;
191 5 break;
192 case MKBETAG('m','p','4','a'):
193 avcodec_id = AV_CODEC_ID_AAC;
194 break;
195 16 case MKBETAG('f','L','a','C'):
196 16 avcodec_id = AV_CODEC_ID_FLAC;
197 16 break;
198 default:
199 avcodec_id = AV_CODEC_ID_NONE;
200 break;
201 }
202
203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 for (int i = 0; i < c->nb_codec_configs; i++)
204 if (c->codec_configs[i]->codec_config_id == codec_config_id) {
205 ret = AVERROR_INVALIDDATA;
206 goto fail;
207 }
208
209 21 tmp = av_realloc_array(c->codec_configs, c->nb_codec_configs + 1, sizeof(*c->codec_configs));
210
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (!tmp) {
211 ret = AVERROR(ENOMEM);
212 goto fail;
213 }
214 21 c->codec_configs = tmp;
215
216 21 codec_config = av_mallocz(sizeof(*codec_config));
217
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (!codec_config) {
218 ret = AVERROR(ENOMEM);
219 goto fail;
220 }
221
222 21 codec_config->codec_config_id = codec_config_id;
223 21 codec_config->codec_id = avcodec_id;
224 21 codec_config->nb_samples = nb_samples;
225 21 codec_config->seek_preroll = seek_preroll;
226
227
2/5
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
21 switch(codec_id) {
228 5 case MKBETAG('O','p','u','s'):
229 5 ret = opus_decoder_config(codec_config, pbc, len);
230 5 break;
231 case MKBETAG('m','p','4','a'):
232 ret = aac_decoder_config(codec_config, pbc, len, s);
233 break;
234 16 case MKBETAG('f','L','a','C'):
235 16 ret = flac_decoder_config(codec_config, pbc, len);
236 16 break;
237 case MKBETAG('i','p','c','m'):
238 ret = ipcm_decoder_config(codec_config, pbc, len);
239 break;
240 default:
241 break;
242 }
243
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (ret < 0)
244 goto fail;
245
246 21 c->codec_configs[c->nb_codec_configs++] = codec_config;
247
248 21 len -= avio_tell(pbc);
249
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (len)
250 av_log(s, AV_LOG_WARNING, "Underread in codec_config_obu. %d bytes left at the end\n", len);
251
252 21 ret = 0;
253 21 fail:
254 21 av_free(buf);
255
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (ret < 0) {
256 if (codec_config)
257 av_free(codec_config->extradata);
258 av_free(codec_config);
259 }
260 21 return ret;
261 }
262
263 92 static int update_extradata(AVCodecParameters *codecpar)
264 {
265 GetBitContext gb;
266 PutBitContext pb;
267 int ret;
268
269
2/4
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
92 switch(codecpar->codec_id) {
270 20 case AV_CODEC_ID_OPUS:
271 20 AV_WB8(codecpar->extradata + 9, codecpar->ch_layout.nb_channels);
272 20 break;
273 case AV_CODEC_ID_AAC: {
274 uint8_t buf[5];
275
276 init_put_bits(&pb, buf, sizeof(buf));
277 ret = init_get_bits8(&gb, codecpar->extradata, codecpar->extradata_size);
278 if (ret < 0)
279 return ret;
280
281 ret = get_bits(&gb, 5);
282 put_bits(&pb, 5, ret);
283 if (ret == AOT_ESCAPE) // violates section 3.11.2, but better check for it
284 put_bits(&pb, 6, get_bits(&gb, 6));
285 ret = get_bits(&gb, 4);
286 put_bits(&pb, 4, ret);
287 if (ret == 0x0f)
288 put_bits(&pb, 24, get_bits(&gb, 24));
289
290 skip_bits(&gb, 4);
291 put_bits(&pb, 4, codecpar->ch_layout.nb_channels); // set channel config
292 ret = put_bits_left(&pb);
293 put_bits(&pb, ret, get_bits(&gb, ret));
294 flush_put_bits(&pb);
295
296 memcpy(codecpar->extradata, buf, sizeof(buf));
297 break;
298 }
299 72 case AV_CODEC_ID_FLAC: {
300 uint8_t buf[13];
301
302 72 init_put_bits(&pb, buf, sizeof(buf));
303 72 ret = init_get_bits8(&gb, codecpar->extradata, codecpar->extradata_size);
304
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
72 if (ret < 0)
305 return ret;
306
307 72 put_bits32(&pb, get_bits_long(&gb, 32)); // min/max blocksize
308 72 put_bits64(&pb, 48, get_bits64(&gb, 48)); // min/max framesize
309 72 put_bits(&pb, 20, get_bits(&gb, 20)); // samplerate
310 72 skip_bits(&gb, 3);
311 72 put_bits(&pb, 3, codecpar->ch_layout.nb_channels - 1);
312 72 ret = put_bits_left(&pb);
313 72 put_bits(&pb, ret, get_bits(&gb, ret));
314 72 flush_put_bits(&pb);
315
316 72 memcpy(codecpar->extradata, buf, sizeof(buf));
317 72 break;
318 }
319 }
320
321 92 return 0;
322 }
323
324 17 static int scalable_channel_layout_config(void *s, AVIOContext *pb,
325 IAMFAudioElement *audio_element,
326 const IAMFCodecConfig *codec_config)
327 {
328 17 int nb_layers, k = 0;
329
330 17 nb_layers = avio_r8(pb) >> 5; // get_bits(&gb, 3);
331 // skip_bits(&gb, 5); //reserved
332
333
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if (nb_layers > 6)
334 return AVERROR_INVALIDDATA;
335
336 17 audio_element->layers = av_calloc(nb_layers, sizeof(*audio_element->layers));
337
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if (!audio_element->layers)
338 return AVERROR(ENOMEM);
339
340 17 audio_element->nb_layers = nb_layers;
341
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 17 times.
63 for (int i = 0; i < nb_layers; i++) {
342 AVIAMFLayer *layer;
343 int loudspeaker_layout, output_gain_is_present_flag;
344 int substream_count, coupled_substream_count;
345 46 int ret, byte = avio_r8(pb);
346
347 46 layer = av_iamf_audio_element_add_layer(audio_element->element);
348
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (!layer)
349 return AVERROR(ENOMEM);
350
351 46 loudspeaker_layout = byte >> 4; // get_bits(&gb, 4);
352 46 output_gain_is_present_flag = (byte >> 3) & 1; //get_bits1(&gb);
353
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 41 times.
46 if ((byte >> 2) & 1)
354 5 layer->flags |= AV_IAMF_LAYER_FLAG_RECON_GAIN;
355 46 substream_count = avio_r8(pb);
356 46 coupled_substream_count = avio_r8(pb);
357
358 46 audio_element->layers[i].substream_count = substream_count;
359 46 audio_element->layers[i].coupled_substream_count = coupled_substream_count;
360
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 if (output_gain_is_present_flag) {
361 layer->output_gain_flags = avio_r8(pb) >> 2; // get_bits(&gb, 6);
362 layer->output_gain = av_make_q(sign_extend(avio_rb16(pb), 16), 1 << 8);
363 }
364
365
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 if (loudspeaker_layout < 10)
366 46 av_channel_layout_copy(&layer->ch_layout, &ff_iamf_scalable_ch_layouts[loudspeaker_layout]);
367 else
368 layer->ch_layout = (AVChannelLayout){ .order = AV_CHANNEL_ORDER_UNSPEC,
369 .nb_channels = substream_count +
370 coupled_substream_count };
371
372
2/2
✓ Branch 0 taken 76 times.
✓ Branch 1 taken 46 times.
122 for (int j = 0; j < substream_count; j++) {
373 76 IAMFSubStream *substream = &audio_element->substreams[k++];
374
375
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 26 times.
76 substream->codecpar->ch_layout = coupled_substream_count-- > 0 ? (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO :
376 (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
377
378 76 ret = update_extradata(substream->codecpar);
379
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
76 if (ret < 0)
380 return ret;
381 }
382
383 }
384
385 17 return 0;
386 }
387
388 4 static int ambisonics_config(void *s, AVIOContext *pb,
389 IAMFAudioElement *audio_element,
390 const IAMFCodecConfig *codec_config)
391 {
392 AVIAMFLayer *layer;
393 unsigned ambisonics_mode;
394 int output_channel_count, substream_count, order;
395 int ret;
396
397 4 ambisonics_mode = ffio_read_leb(pb);
398
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (ambisonics_mode > 1)
399 return 0;
400
401 4 output_channel_count = avio_r8(pb); // C
402 4 substream_count = avio_r8(pb); // N
403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (audio_element->nb_substreams != substream_count)
404 return AVERROR_INVALIDDATA;
405
406 4 order = floor(sqrt(output_channel_count - 1));
407 /* incomplete order - some harmonics are missing */
408
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if ((order + 1) * (order + 1) != output_channel_count)
409 return AVERROR_INVALIDDATA;
410
411 4 audio_element->layers = av_mallocz(sizeof(*audio_element->layers));
412
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!audio_element->layers)
413 return AVERROR(ENOMEM);
414
415 4 audio_element->nb_layers = 1;
416 4 audio_element->layers->substream_count = substream_count;
417
418 4 layer = av_iamf_audio_element_add_layer(audio_element->element);
419
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!layer)
420 return AVERROR(ENOMEM);
421
422 4 layer->ambisonics_mode = ambisonics_mode;
423
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (ambisonics_mode == 0) {
424
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 4 times.
20 for (int i = 0; i < substream_count; i++) {
425 16 IAMFSubStream *substream = &audio_element->substreams[i];
426
427 16 substream->codecpar->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
428
429 16 ret = update_extradata(substream->codecpar);
430
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (ret < 0)
431 return ret;
432 }
433
434 4 layer->ch_layout.order = AV_CHANNEL_ORDER_CUSTOM;
435 4 layer->ch_layout.nb_channels = output_channel_count;
436 4 layer->ch_layout.u.map = av_calloc(output_channel_count, sizeof(*layer->ch_layout.u.map));
437
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!layer->ch_layout.u.map)
438 return AVERROR(ENOMEM);
439
440
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 4 times.
20 for (int i = 0; i < output_channel_count; i++)
441 16 layer->ch_layout.u.map[i].id = avio_r8(pb) + AV_CHAN_AMBISONIC_BASE;
442 } else {
443 int coupled_substream_count = avio_r8(pb); // M
444 int nb_demixing_matrix = substream_count + coupled_substream_count;
445 int demixing_matrix_size = nb_demixing_matrix * output_channel_count;
446
447 audio_element->layers->coupled_substream_count = coupled_substream_count;
448
449 layer->ch_layout = (AVChannelLayout){ .order = AV_CHANNEL_ORDER_AMBISONIC, .nb_channels = output_channel_count };
450 layer->demixing_matrix = av_malloc_array(demixing_matrix_size, sizeof(*layer->demixing_matrix));
451 if (!layer->demixing_matrix)
452 return AVERROR(ENOMEM);
453
454 for (int i = 0; i < demixing_matrix_size; i++)
455 layer->demixing_matrix[i] = av_make_q(sign_extend(avio_rb16(pb), 16), 1 << 8);
456
457 for (int i = 0; i < substream_count; i++) {
458 IAMFSubStream *substream = &audio_element->substreams[i];
459
460 substream->codecpar->ch_layout = coupled_substream_count-- > 0 ? (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO :
461 (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
462
463
464 ret = update_extradata(substream->codecpar);
465 if (ret < 0)
466 return ret;
467 }
468 }
469
470 4 return 0;
471 }
472
473 68 static int param_parse(void *s, IAMFContext *c, AVIOContext *pb,
474 unsigned int type,
475 const IAMFAudioElement *audio_element,
476 AVIAMFParamDefinition **out_param_definition)
477 {
478 68 IAMFParamDefinition *param_definition = NULL;
479 AVIAMFParamDefinition *param;
480 unsigned int parameter_id, parameter_rate, mode;
481 68 unsigned int duration = 0, constant_subblock_duration = 0, nb_subblocks = 0;
482 size_t param_size;
483
484 68 parameter_id = ffio_read_leb(pb);
485
486
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 39 times.
109 for (int i = 0; i < c->nb_param_definitions; i++)
487
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 41 times.
70 if (c->param_definitions[i]->param->parameter_id == parameter_id) {
488 29 param_definition = c->param_definitions[i];
489 29 break;
490 }
491
492 68 parameter_rate = ffio_read_leb(pb);
493 68 mode = avio_r8(pb) >> 7;
494
495
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 50 times.
68 if (mode == 0) {
496 18 duration = ffio_read_leb(pb);
497
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (!duration)
498 return AVERROR_INVALIDDATA;
499 18 constant_subblock_duration = ffio_read_leb(pb);
500
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (constant_subblock_duration == 0)
501 nb_subblocks = ffio_read_leb(pb);
502 else
503 18 nb_subblocks = duration / constant_subblock_duration;
504 }
505
506 68 param = av_iamf_param_definition_alloc(type, nb_subblocks, &param_size);
507
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 68 times.
68 if (!param)
508 return AVERROR(ENOMEM);
509
510
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 68 times.
86 for (int i = 0; i < nb_subblocks; i++) {
511 18 void *subblock = av_iamf_param_definition_get_subblock(param, i);
512 18 unsigned int subblock_duration = constant_subblock_duration;
513
514
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (constant_subblock_duration == 0)
515 subblock_duration = ffio_read_leb(pb);
516
517
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
18 switch (type) {
518 case AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN: {
519 AVIAMFMixGain *mix = subblock;
520 mix->subblock_duration = subblock_duration;
521 break;
522 }
523 13 case AV_IAMF_PARAMETER_DEFINITION_DEMIXING: {
524 13 AVIAMFDemixingInfo *demix = subblock;
525 13 demix->subblock_duration = subblock_duration;
526 // DefaultDemixingInfoParameterData
527
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 av_assert0(audio_element);
528 13 demix->dmixp_mode = avio_r8(pb) >> 5;
529 13 audio_element->element->default_w = avio_r8(pb) >> 4;
530 13 break;
531 }
532 5 case AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN: {
533 5 AVIAMFReconGain *recon = subblock;
534 5 recon->subblock_duration = subblock_duration;
535 5 break;
536 }
537 default:
538 av_free(param);
539 return AVERROR_INVALIDDATA;
540 }
541 }
542
543 68 param->parameter_id = parameter_id;
544 68 param->parameter_rate = parameter_rate;
545 68 param->duration = duration;
546 68 param->constant_subblock_duration = constant_subblock_duration;
547 68 param->nb_subblocks = nb_subblocks;
548
549
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 39 times.
68 if (param_definition) {
550
2/4
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 29 times.
29 if (param_definition->param_size != param_size || memcmp(param_definition->param, param, param_size)) {
551 av_log(s, AV_LOG_ERROR, "Incosistent parameters for parameter_id %u\n", parameter_id);
552 av_free(param);
553 return AVERROR_INVALIDDATA;
554 }
555 } else {
556 39 IAMFParamDefinition **tmp = av_realloc_array(c->param_definitions, c->nb_param_definitions + 1,
557 sizeof(*c->param_definitions));
558
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (!tmp) {
559 av_free(param);
560 return AVERROR(ENOMEM);
561 }
562 39 c->param_definitions = tmp;
563
564 39 param_definition = av_mallocz(sizeof(*param_definition));
565
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (!param_definition) {
566 av_free(param);
567 return AVERROR(ENOMEM);
568 }
569 39 param_definition->param = param;
570 39 param_definition->mode = !mode;
571 39 param_definition->param_size = param_size;
572 39 param_definition->audio_element = audio_element;
573
574 39 c->param_definitions[c->nb_param_definitions++] = param_definition;
575 }
576
577
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 68 times.
68 av_assert0(out_param_definition);
578 68 *out_param_definition = param;
579
580 68 return 0;
581 }
582
583 21 static int audio_element_obu(void *s, IAMFContext *c, AVIOContext *pb, int len)
584 {
585 const IAMFCodecConfig *codec_config;
586 AVIAMFAudioElement *element;
587 21 IAMFAudioElement **tmp, *audio_element = NULL;
588 FFIOContext b;
589 AVIOContext *pbc;
590 uint8_t *buf;
591 unsigned audio_element_id, codec_config_id, num_parameters;
592 int audio_element_type, ret;
593
594 21 buf = av_malloc(len);
595
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (!buf)
596 return AVERROR(ENOMEM);
597
598 21 ret = avio_read(pb, buf, len);
599
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (ret != len) {
600 if (ret >= 0)
601 ret = AVERROR_INVALIDDATA;
602 goto fail;
603 }
604
605 21 ffio_init_context(&b, buf, len, 0, NULL, NULL, NULL, NULL);
606 21 pbc = &b.pub;
607
608 21 audio_element_id = ffio_read_leb(pbc);
609
610
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 for (int i = 0; i < c->nb_audio_elements; i++)
611 if (c->audio_elements[i]->audio_element_id == audio_element_id) {
612 av_log(s, AV_LOG_ERROR, "Duplicate audio_element_id %d\n", audio_element_id);
613 ret = AVERROR_INVALIDDATA;
614 goto fail;
615 }
616
617 21 audio_element_type = avio_r8(pbc) >> 5;
618 21 codec_config_id = ffio_read_leb(pbc);
619
620 21 codec_config = ff_iamf_get_codec_config(c, codec_config_id);
621
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (!codec_config) {
622 av_log(s, AV_LOG_ERROR, "Non existant codec config id %d referenced in an audio element\n", codec_config_id);
623 ret = AVERROR_INVALIDDATA;
624 goto fail;
625 }
626
627
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (codec_config->codec_id == AV_CODEC_ID_NONE) {
628 av_log(s, AV_LOG_DEBUG, "Unknown codec id referenced in an audio element. Ignoring\n");
629 ret = 0;
630 goto fail;
631 }
632
633 21 tmp = av_realloc_array(c->audio_elements, c->nb_audio_elements + 1, sizeof(*c->audio_elements));
634
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (!tmp) {
635 ret = AVERROR(ENOMEM);
636 goto fail;
637 }
638 21 c->audio_elements = tmp;
639
640 21 audio_element = av_mallocz(sizeof(*audio_element));
641
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (!audio_element) {
642 ret = AVERROR(ENOMEM);
643 goto fail;
644 }
645
646 21 audio_element->nb_substreams = ffio_read_leb(pbc);
647 21 audio_element->codec_config_id = codec_config_id;
648 21 audio_element->audio_element_id = audio_element_id;
649 21 audio_element->substreams = av_calloc(audio_element->nb_substreams, sizeof(*audio_element->substreams));
650
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (!audio_element->substreams) {
651 ret = AVERROR(ENOMEM);
652 goto fail;
653 }
654
655 21 element = audio_element->element = av_iamf_audio_element_alloc();
656
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (!element) {
657 ret = AVERROR(ENOMEM);
658 goto fail;
659 }
660 21 audio_element->celement = element;
661
662 21 element->audio_element_type = audio_element_type;
663
664
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 21 times.
113 for (int i = 0; i < audio_element->nb_substreams; i++) {
665 92 IAMFSubStream *substream = &audio_element->substreams[i];
666
667 92 substream->codecpar = avcodec_parameters_alloc();
668
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
92 if (!substream->codecpar) {
669 ret = AVERROR(ENOMEM);
670 goto fail;
671 }
672
673 92 substream->audio_substream_id = ffio_read_leb(pbc);
674
675 92 substream->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
676 92 substream->codecpar->codec_id = codec_config->codec_id;
677 92 substream->codecpar->frame_size = codec_config->nb_samples;
678 92 substream->codecpar->sample_rate = codec_config->sample_rate;
679 92 substream->codecpar->seek_preroll = codec_config->seek_preroll;
680
681
1/2
✓ Branch 0 taken 92 times.
✗ Branch 1 not taken.
92 switch(substream->codecpar->codec_id) {
682 92 case AV_CODEC_ID_AAC:
683 case AV_CODEC_ID_FLAC:
684 case AV_CODEC_ID_OPUS:
685 92 substream->codecpar->extradata = av_malloc(codec_config->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
686
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
92 if (!substream->codecpar->extradata) {
687 ret = AVERROR(ENOMEM);
688 goto fail;
689 }
690 92 memcpy(substream->codecpar->extradata, codec_config->extradata, codec_config->extradata_size);
691 92 memset(substream->codecpar->extradata + codec_config->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
692 92 substream->codecpar->extradata_size = codec_config->extradata_size;
693 92 break;
694 }
695 }
696
697 21 num_parameters = ffio_read_leb(pbc);
698
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
21 if (num_parameters && audio_element_type != 0) {
699 av_log(s, AV_LOG_ERROR, "Audio Element parameter count %u is invalid"
700 " for Scene representations\n", num_parameters);
701 ret = AVERROR_INVALIDDATA;
702 goto fail;
703 }
704
705
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 21 times.
39 for (int i = 0; i < num_parameters; i++) {
706 unsigned type;
707
708 18 type = ffio_read_leb(pbc);
709
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (type == AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN)
710 ret = AVERROR_INVALIDDATA;
711
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 5 times.
18 else if (type == AV_IAMF_PARAMETER_DEFINITION_DEMIXING)
712 13 ret = param_parse(s, c, pbc, type, audio_element, &element->demixing_info);
713
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 else if (type == AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN)
714 5 ret = param_parse(s, c, pbc, type, audio_element, &element->recon_gain_info);
715 else {
716 unsigned param_definition_size = ffio_read_leb(pbc);
717 avio_skip(pbc, param_definition_size);
718 }
719
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if (ret < 0)
720 goto fail;
721 }
722
723
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 4 times.
21 if (audio_element_type == AV_IAMF_AUDIO_ELEMENT_TYPE_CHANNEL) {
724 17 ret = scalable_channel_layout_config(s, pbc, audio_element, codec_config);
725
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if (ret < 0)
726 goto fail;
727
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 } else if (audio_element_type == AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE) {
728 4 ret = ambisonics_config(s, pbc, audio_element, codec_config);
729
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (ret < 0)
730 goto fail;
731 } else {
732 unsigned audio_element_config_size = ffio_read_leb(pbc);
733 avio_skip(pbc, audio_element_config_size);
734 }
735
736 21 c->audio_elements[c->nb_audio_elements++] = audio_element;
737
738 21 len -= avio_tell(pbc);
739
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (len)
740 av_log(s, AV_LOG_WARNING, "Underread in audio_element_obu. %d bytes left at the end\n", len);
741
742 21 ret = 0;
743 21 fail:
744 21 av_free(buf);
745
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (ret < 0)
746 ff_iamf_free_audio_element(&audio_element);
747 21 return ret;
748 }
749
750 67 static int label_string(AVIOContext *pb, char **label)
751 {
752 uint8_t buf[128];
753
754 67 avio_get_str(pb, sizeof(buf), buf, sizeof(buf));
755
756
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67 times.
67 if (pb->error)
757 return pb->error;
758
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67 times.
67 if (pb->eof_reached)
759 return AVERROR_INVALIDDATA;
760 67 *label = av_strdup(buf);
761
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67 times.
67 if (!*label)
762 return AVERROR(ENOMEM);
763
764 67 return 0;
765 }
766
767 21 static int mix_presentation_obu(void *s, IAMFContext *c, AVIOContext *pb, int len)
768 {
769 AVIAMFMixPresentation *mix;
770 21 IAMFMixPresentation **tmp, *mix_presentation = NULL;
771 FFIOContext b;
772 AVIOContext *pbc;
773 uint8_t *buf;
774 unsigned nb_submixes, mix_presentation_id;
775 int ret;
776
777 21 buf = av_malloc(len);
778
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (!buf)
779 return AVERROR(ENOMEM);
780
781 21 ret = avio_read(pb, buf, len);
782
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (ret != len) {
783 if (ret >= 0)
784 ret = AVERROR_INVALIDDATA;
785 goto fail;
786 }
787
788 21 ffio_init_context(&b, buf, len, 0, NULL, NULL, NULL, NULL);
789 21 pbc = &b.pub;
790
791 21 mix_presentation_id = ffio_read_leb(pbc);
792
793
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 for (int i = 0; i < c->nb_mix_presentations; i++)
794 if (c->mix_presentations[i]->mix_presentation_id == mix_presentation_id) {
795 av_log(s, AV_LOG_ERROR, "Duplicate mix_presentation_id %d\n", mix_presentation_id);
796 ret = AVERROR_INVALIDDATA;
797 goto fail;
798 }
799
800 21 tmp = av_realloc_array(c->mix_presentations, c->nb_mix_presentations + 1, sizeof(*c->mix_presentations));
801
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (!tmp) {
802 ret = AVERROR(ENOMEM);
803 goto fail;
804 }
805 21 c->mix_presentations = tmp;
806
807 21 mix_presentation = av_mallocz(sizeof(*mix_presentation));
808
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (!mix_presentation) {
809 ret = AVERROR(ENOMEM);
810 goto fail;
811 }
812
813 21 mix_presentation->mix_presentation_id = mix_presentation_id;
814 21 mix = mix_presentation->mix = av_iamf_mix_presentation_alloc();
815
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (!mix) {
816 ret = AVERROR(ENOMEM);
817 goto fail;
818 }
819 21 mix_presentation->cmix = mix;
820
821 21 mix_presentation->count_label = ffio_read_leb(pbc);
822 21 mix_presentation->language_label = av_calloc(mix_presentation->count_label,
823 sizeof(*mix_presentation->language_label));
824
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (!mix_presentation->language_label) {
825 mix_presentation->count_label = 0;
826 ret = AVERROR(ENOMEM);
827 goto fail;
828 }
829
830
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 21 times.
42 for (int i = 0; i < mix_presentation->count_label; i++) {
831 21 ret = label_string(pbc, &mix_presentation->language_label[i]);
832
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (ret < 0)
833 goto fail;
834 }
835
836
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 21 times.
42 for (int i = 0; i < mix_presentation->count_label; i++) {
837 21 char *annotation = NULL;
838 21 ret = label_string(pbc, &annotation);
839
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (ret < 0)
840 goto fail;
841 21 ret = av_dict_set(&mix->annotations, mix_presentation->language_label[i], annotation,
842 AV_DICT_DONT_STRDUP_VAL | AV_DICT_DONT_OVERWRITE);
843
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (ret < 0)
844 goto fail;
845 }
846
847 21 nb_submixes = ffio_read_leb(pbc);
848
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 21 times.
46 for (int i = 0; i < nb_submixes; i++) {
849 AVIAMFSubmix *sub_mix;
850 unsigned nb_elements, nb_layouts;
851
852 25 sub_mix = av_iamf_mix_presentation_add_submix(mix);
853
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if (!sub_mix) {
854 ret = AVERROR(ENOMEM);
855 goto fail;
856 }
857
858 25 nb_elements = ffio_read_leb(pbc);
859
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 25 times.
50 for (int j = 0; j < nb_elements; j++) {
860 AVIAMFSubmixElement *submix_element;
861 25 IAMFAudioElement *audio_element = NULL;
862 unsigned int rendering_config_extension_size;
863
864 25 submix_element = av_iamf_submix_add_element(sub_mix);
865
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if (!submix_element) {
866 ret = AVERROR(ENOMEM);
867 goto fail;
868 }
869
870 25 submix_element->audio_element_id = ffio_read_leb(pbc);
871
872
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 for (int k = 0; k < c->nb_audio_elements; k++)
873
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if (c->audio_elements[k]->audio_element_id == submix_element->audio_element_id) {
874 25 audio_element = c->audio_elements[k];
875 25 break;
876 }
877
878
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if (!audio_element) {
879 av_log(s, AV_LOG_ERROR, "Invalid Audio Element with id %u referenced by Mix Parameters %u\n",
880 submix_element->audio_element_id, mix_presentation_id);
881 ret = AVERROR_INVALIDDATA;
882 goto fail;
883 }
884
885
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 25 times.
50 for (int k = 0; k < mix_presentation->count_label; k++) {
886 25 char *annotation = NULL;
887 25 ret = label_string(pbc, &annotation);
888
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if (ret < 0)
889 goto fail;
890 25 ret = av_dict_set(&submix_element->annotations, mix_presentation->language_label[k], annotation,
891 AV_DICT_DONT_STRDUP_VAL | AV_DICT_DONT_OVERWRITE);
892
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if (ret < 0)
893 goto fail;
894 }
895
896 25 submix_element->headphones_rendering_mode = avio_r8(pbc) >> 6;
897
898 25 rendering_config_extension_size = ffio_read_leb(pbc);
899 25 avio_skip(pbc, rendering_config_extension_size);
900
901 25 ret = param_parse(s, c, pbc, AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN,
902 NULL,
903 &submix_element->element_mix_config);
904
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if (ret < 0)
905 goto fail;
906 25 submix_element->default_mix_gain = av_make_q(sign_extend(avio_rb16(pbc), 16), 1 << 8);
907 }
908
909 25 ret = param_parse(s, c, pbc, AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN, NULL, &sub_mix->output_mix_config);
910
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if (ret < 0)
911 goto fail;
912 25 sub_mix->default_mix_gain = av_make_q(sign_extend(avio_rb16(pbc), 16), 1 << 8);
913
914 25 nb_layouts = ffio_read_leb(pbc);
915
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 25 times.
79 for (int j = 0; j < nb_layouts; j++) {
916 AVIAMFSubmixLayout *submix_layout;
917 int info_type;
918 54 int byte = avio_r8(pbc);
919
920 54 submix_layout = av_iamf_submix_add_layout(sub_mix);
921
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
54 if (!submix_layout) {
922 ret = AVERROR(ENOMEM);
923 goto fail;
924 }
925
926 54 submix_layout->layout_type = byte >> 6;
927
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 if (submix_layout->layout_type < AV_IAMF_SUBMIX_LAYOUT_TYPE_LOUDSPEAKERS ||
928
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
54 submix_layout->layout_type > AV_IAMF_SUBMIX_LAYOUT_TYPE_BINAURAL) {
929 av_log(s, AV_LOG_ERROR, "Invalid Layout type %u in a submix from Mix Presentation %u\n",
930 submix_layout->layout_type, mix_presentation_id);
931 ret = AVERROR_INVALIDDATA;
932 goto fail;
933 }
934
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 4 times.
54 if (submix_layout->layout_type == 2) {
935 int sound_system;
936 50 sound_system = (byte >> 2) & 0xF;
937
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 if (sound_system >= FF_ARRAY_ELEMS(ff_iamf_sound_system_map)) {
938 ret = AVERROR_INVALIDDATA;
939 goto fail;
940 }
941 50 av_channel_layout_copy(&submix_layout->sound_system, &ff_iamf_sound_system_map[sound_system].layout);
942 }
943
944 54 info_type = avio_r8(pbc);
945 54 submix_layout->integrated_loudness = av_make_q(sign_extend(avio_rb16(pbc), 16), 1 << 8);
946 54 submix_layout->digital_peak = av_make_q(sign_extend(avio_rb16(pbc), 16), 1 << 8);
947
948
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
54 if (info_type & 1)
949 submix_layout->true_peak = av_make_q(sign_extend(avio_rb16(pbc), 16), 1 << 8);
950
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
54 if (info_type & 2) {
951 unsigned int num_anchored_loudness = avio_r8(pbc);
952
953 for (int k = 0; k < num_anchored_loudness; k++) {
954 unsigned int anchor_element = avio_r8(pbc);
955 AVRational anchored_loudness = av_make_q(sign_extend(avio_rb16(pbc), 16), 1 << 8);
956 if (anchor_element == IAMF_ANCHOR_ELEMENT_DIALOGUE)
957 submix_layout->dialogue_anchored_loudness = anchored_loudness;
958 else if (anchor_element <= IAMF_ANCHOR_ELEMENT_ALBUM)
959 submix_layout->album_anchored_loudness = anchored_loudness;
960 else
961 av_log(s, AV_LOG_DEBUG, "Unknown anchor_element. Ignoring\n");
962 }
963 }
964
965
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
54 if (info_type & 0xFC) {
966 unsigned int info_type_size = ffio_read_leb(pbc);
967 avio_skip(pbc, info_type_size);
968 }
969 }
970 }
971
972 21 c->mix_presentations[c->nb_mix_presentations++] = mix_presentation;
973
974 21 len -= avio_tell(pbc);
975
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (len)
976 av_log(s, AV_LOG_WARNING, "Underread in mix_presentation_obu. %d bytes left at the end\n", len);
977
978 21 ret = 0;
979 21 fail:
980 21 av_free(buf);
981
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (ret < 0)
982 ff_iamf_free_mix_presentation(&mix_presentation);
983 21 return ret;
984 }
985
986 7828 int ff_iamf_parse_obu_header(const uint8_t *buf, int buf_size,
987 unsigned *obu_size, int *start_pos, enum IAMF_OBU_Type *type,
988 unsigned *skip_samples, unsigned *discard_padding)
989 {
990 GetBitContext gb;
991 int ret, extension_flag, trimming, start;
992 7828 unsigned skip = 0, discard = 0;
993 unsigned size;
994
995 7828 ret = init_get_bits8(&gb, buf, FFMIN(buf_size, MAX_IAMF_OBU_HEADER_SIZE));
996
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7828 times.
7828 if (ret < 0)
997 return ret;
998
999 7828 *type = get_bits(&gb, 5);
1000 7828 /*redundant =*/ get_bits1(&gb);
1001 7828 trimming = get_bits1(&gb);
1002 7828 extension_flag = get_bits1(&gb);
1003
1004 7828 *obu_size = get_leb(&gb);
1005
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 7819 times.
7828 if (*obu_size > INT_MAX)
1006 9 return AVERROR_INVALIDDATA;
1007
1008 7819 start = get_bits_count(&gb) / 8;
1009
1010
2/2
✓ Branch 0 taken 2313 times.
✓ Branch 1 taken 5506 times.
7819 if (trimming) {
1011 2313 discard = get_leb(&gb); // num_samples_to_trim_at_end
1012 2313 skip = get_leb(&gb); // num_samples_to_trim_at_start
1013 }
1014
1015
2/2
✓ Branch 0 taken 553 times.
✓ Branch 1 taken 7266 times.
7819 if (skip_samples)
1016 553 *skip_samples = skip;
1017
2/2
✓ Branch 0 taken 553 times.
✓ Branch 1 taken 7266 times.
7819 if (discard_padding)
1018 553 *discard_padding = discard;
1019
1020
2/2
✓ Branch 0 taken 724 times.
✓ Branch 1 taken 7095 times.
7819 if (extension_flag) {
1021 unsigned int extension_bytes;
1022 724 extension_bytes = get_leb(&gb);
1023
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 706 times.
724 if (extension_bytes > INT_MAX / 8)
1024 18 return AVERROR_INVALIDDATA;
1025 706 skip_bits_long(&gb, extension_bytes * 8);
1026 }
1027
1028
2/2
✓ Branch 1 taken 526 times.
✓ Branch 2 taken 7275 times.
7801 if (get_bits_left(&gb) < 0)
1029 526 return AVERROR_INVALIDDATA;
1030
1031 7275 size = *obu_size + start;
1032
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7275 times.
7275 if (size > INT_MAX)
1033 return AVERROR_INVALIDDATA;
1034
1035 7275 *obu_size -= get_bits_count(&gb) / 8 - start;
1036 7275 *start_pos = size - *obu_size;
1037
1038 7275 return size;
1039 }
1040
1041 21 int ff_iamfdec_read_descriptors(IAMFContext *c, AVIOContext *pb,
1042 int max_size, void *log_ctx)
1043 {
1044 uint8_t header[MAX_IAMF_OBU_HEADER_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1045 int ret;
1046
1047 76 while (1) {
1048 unsigned obu_size;
1049 enum IAMF_OBU_Type type;
1050 int start_pos, len, size;
1051
1052
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 97 times.
97 if ((ret = ffio_ensure_seekback(pb, FFMIN(MAX_IAMF_OBU_HEADER_SIZE, max_size))) < 0)
1053 return ret;
1054 97 size = avio_read(pb, header, FFMIN(MAX_IAMF_OBU_HEADER_SIZE, max_size));
1055
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 97 times.
97 if (size < 0)
1056 return size;
1057
1058 97 len = ff_iamf_parse_obu_header(header, size, &obu_size, &start_pos, &type, NULL, NULL);
1059
2/4
✓ Branch 0 taken 97 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 97 times.
97 if (len < 0 || obu_size > max_size) {
1060 av_log(log_ctx, AV_LOG_ERROR, "Failed to read obu header\n");
1061 avio_seek(pb, -size, SEEK_CUR);
1062 return len;
1063 }
1064
1065
4/4
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 63 times.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 21 times.
97 if (type >= IAMF_OBU_IA_PARAMETER_BLOCK && type < IAMF_OBU_IA_SEQUENCE_HEADER) {
1066 13 avio_seek(pb, -size, SEEK_CUR);
1067 13 break;
1068 }
1069
1070 84 avio_seek(pb, -(size - start_pos), SEEK_CUR);
1071
4/5
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 21 times.
84 switch (type) {
1072 21 case IAMF_OBU_IA_CODEC_CONFIG:
1073 21 ret = codec_config_obu(log_ctx, c, pb, obu_size);
1074 21 break;
1075 21 case IAMF_OBU_IA_AUDIO_ELEMENT:
1076 21 ret = audio_element_obu(log_ctx, c, pb, obu_size);
1077 21 break;
1078 21 case IAMF_OBU_IA_MIX_PRESENTATION:
1079 21 ret = mix_presentation_obu(log_ctx, c, pb, obu_size);
1080 21 break;
1081 case IAMF_OBU_IA_TEMPORAL_DELIMITER:
1082 break;
1083 21 default: {
1084 21 int64_t offset = avio_skip(pb, obu_size);
1085
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (offset < 0)
1086 ret = offset;
1087 21 break;
1088 }
1089 }
1090
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 if (ret < 0) {
1091 av_log(log_ctx, AV_LOG_ERROR, "Failed to read obu type %d\n", type);
1092 return ret;
1093 }
1094 84 max_size -= obu_size + start_pos;
1095
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 if (max_size < 0)
1096 return AVERROR_INVALIDDATA;
1097
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 76 times.
84 if (!max_size)
1098 8 break;
1099 }
1100
1101 21 return 0;
1102 }
1103