FFmpeg
Loading...
Searching...
No Matches
iamf_writer.c
Go to the documentation of this file.
1/*
2 * Immersive Audio Model and Formats muxing 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/bprint.h"
25#include "libavutil/iamf.h"
26#include "libavutil/mem.h"
27#include "libavcodec/get_bits.h"
28#include "libavcodec/put_bits.h"
29#include "avformat.h"
30#include "avio_internal.h"
31#include "iamf.h"
32#include "iamf_writer.h"
33
34
35static int update_extradata(IAMFCodecConfig *codec_config)
36{
39 int ret;
40
41 switch(codec_config->codec_id) {
43 if (codec_config->extradata_size != 19)
45 codec_config->extradata_size -= 8;
46 AV_WB8(codec_config->extradata + 0, AV_RL8(codec_config->extradata + 8)); // version
47 AV_WB8(codec_config->extradata + 1, 2); // set channels to stereo
48 AV_WB16A(codec_config->extradata + 2, AV_RL16A(codec_config->extradata + 10)); // Byte swap pre-skip
49 AV_WB32A(codec_config->extradata + 4, AV_RL32A(codec_config->extradata + 12)); // Byte swap sample rate
50 AV_WB16A(codec_config->extradata + 8, 0); // set Output Gain to 0
51 AV_WB8(codec_config->extradata + 10, AV_RL8(codec_config->extradata + 18)); // Mapping family
52 break;
53 case AV_CODEC_ID_FLAC: {
54 uint8_t buf[13];
55
56 init_put_bits(&pb, buf, sizeof(buf));
57 ret = init_get_bits8(&gb, codec_config->extradata, codec_config->extradata_size);
58 if (ret < 0)
59 return ret;
60
61 put_bits32(&pb, get_bits_long(&gb, 32)); // min/max blocksize
62 put_bits63(&pb, 48, get_bits64(&gb, 48)); // min/max framesize
63 put_bits(&pb, 20, get_bits(&gb, 20)); // samplerate
64 skip_bits(&gb, 3);
65 put_bits(&pb, 3, 1); // set channels to stereo
66 ret = put_bits_left(&pb);
67 put_bits(&pb, ret, get_bits(&gb, ret));
68 flush_put_bits(&pb);
69
70 memcpy(codec_config->extradata, buf, sizeof(buf));
71 break;
72 }
73 default:
74 break;
75 }
76
77 return 0;
78}
79
81{
82 switch (codec_config->codec_id) {
84 if (!codec_config->nb_samples)
85 return AVERROR(EINVAL);
86 // ceil(3840 / nb_samples)
87 codec_config->audio_roll_distance = -(1 + ((3840 - 1) / codec_config->nb_samples));
88 break;
89 case AV_CODEC_ID_AAC:
90 codec_config->audio_roll_distance = -1;
91 break;
99 codec_config->audio_roll_distance = 0;
100 break;
101 default:
102 return AVERROR(EINVAL);
103 }
104
105 return 0;
106}
107
108static int fill_codec_config(IAMFContext *iamf, const AVStreamGroup *stg,
109 IAMFCodecConfig *codec_config, void *log_ctx)
110{
111 const AVStream *st = stg->streams[0];
113 int j, ret = 0;
114
115 if (!st->codecpar->frame_size) {
116 av_log(log_ctx, AV_LOG_ERROR, "frame_size is unset for stream id %d\n",
117 st->id);
118 return AVERROR(EINVAL);
119 }
120
121 codec_config->codec_id = st->codecpar->codec_id;
122 codec_config->codec_tag = st->codecpar->codec_tag;
123 switch (codec_config->codec_id) {
124 case AV_CODEC_ID_OPUS:
125 codec_config->sample_rate = 48000;
126 codec_config->nb_samples = av_rescale(st->codecpar->frame_size, 48000, st->codecpar->sample_rate);
127 break;
128 default:
129 codec_config->sample_rate = st->codecpar->sample_rate;
130 codec_config->nb_samples = st->codecpar->frame_size;
131 break;
132 }
133 populate_audio_roll_distance(codec_config);
134 if (st->codecpar->extradata_size) {
136 return AVERROR_INVALIDDATA;
137
139 if (!codec_config->extradata)
140 return AVERROR(ENOMEM);
141 memcpy(codec_config->extradata, st->codecpar->extradata, st->codecpar->extradata_size);
142 memset(codec_config->extradata + st->codecpar->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
143 codec_config->extradata_size = st->codecpar->extradata_size;
144 ret = update_extradata(codec_config);
145 if (ret < 0)
146 goto fail;
147 }
148
149 for (j = 0; j < iamf->nb_codec_configs; j++) {
150 if (!memcmp(iamf->codec_configs[j], codec_config, offsetof(IAMFCodecConfig, extradata)) &&
151 (!codec_config->extradata_size || !memcmp(iamf->codec_configs[j]->extradata,
152 codec_config->extradata, codec_config->extradata_size)))
153 break;
154 }
155
156 if (j < iamf->nb_codec_configs) {
158 av_free(iamf->codec_configs[j]);
159 iamf->codec_configs[j] = codec_config;
160 return j;
161 }
162
163 tmp = av_realloc_array(iamf->codec_configs, iamf->nb_codec_configs + 1, sizeof(*iamf->codec_configs));
164 if (!tmp) {
165 ret = AVERROR(ENOMEM);
166 goto fail;
167 }
168
169 iamf->codec_configs = tmp;
170 iamf->codec_configs[iamf->nb_codec_configs] = codec_config;
171 codec_config->codec_config_id = iamf->nb_codec_configs;
172
173 return iamf->nb_codec_configs++;
174
175fail:
176 av_freep(&codec_config->extradata);
177 return ret;
178}
179
181 const IAMFAudioElement *audio_element, void *log_ctx)
182{
184 IAMFCodecConfig *codec_config = NULL;
185
187 sizeof(*iamf->param_definitions));
188 if (!tmp)
189 return AVERROR(ENOMEM);
190
191 iamf->param_definitions = tmp;
192
193 if (audio_element)
194 codec_config = iamf->codec_configs[audio_element->codec_config_id];
195
196 if (!param->parameter_rate) {
197 if (!codec_config) {
198 av_log(log_ctx, AV_LOG_ERROR, "parameter_rate needed but not set for parameter_id %u\n",
199 param->parameter_id);
200 return AVERROR(EINVAL);
201 }
202 param->parameter_rate = codec_config->sample_rate;
203 }
204 if (codec_config) {
205 if (!param->duration)
206 param->duration = av_rescale(codec_config->nb_samples, param->parameter_rate, codec_config->sample_rate);
207 if (!param->constant_subblock_duration)
208 param->constant_subblock_duration = av_rescale(codec_config->nb_samples, param->parameter_rate, codec_config->sample_rate);
209 }
210
212 if (!param_definition)
213 return AVERROR(ENOMEM);
214
215 param_definition->mode = !!param->duration;
216 param_definition->param = param;
217 param_definition->audio_element = audio_element;
219
220 return 0;
221}
222
223int ff_iamf_add_audio_element(IAMFContext *iamf, const AVStreamGroup *stg, void *log_ctx)
224{
225 const AVIAMFAudioElement *iamf_audio_element;
226 IAMFAudioElement **tmp, *audio_element;
227 IAMFCodecConfig *codec_config;
228 int ret;
229
231 return AVERROR(EINVAL);
232 if (!stg->nb_streams) {
233 av_log(log_ctx, AV_LOG_ERROR, "Audio Element id %"PRId64" has no streams\n", stg->id);
234 return AVERROR(EINVAL);
235 }
236
237 iamf_audio_element = stg->params.iamf_audio_element;
238 if (iamf_audio_element->audio_element_type == AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE) {
239 const AVIAMFLayer *layer = iamf_audio_element->layers[0];
240 if (iamf_audio_element->nb_layers != 1) {
241 av_log(log_ctx, AV_LOG_ERROR, "Invalid amount of layers for SCENE_BASED audio element. Must be 1\n");
242 return AVERROR(EINVAL);
243 }
246 av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout for SCENE_BASED audio element\n");
247 return AVERROR(EINVAL);
248 }
250 av_log(log_ctx, AV_LOG_ERROR, "Unsupported ambisonics mode %d\n", layer->ambisonics_mode);
252 }
253 for (int i = 0; i < stg->nb_streams; i++) {
254 if (stg->streams[i]->codecpar->ch_layout.nb_channels > 1) {
255 av_log(log_ctx, AV_LOG_ERROR, "Invalid amount of channels in a stream for MONO mode ambisonics\n");
256 return AVERROR(EINVAL);
257 }
258 }
259 } else {
260 AVBPrint bp;
261
262 if (iamf_audio_element->nb_layers < 1) {
263 av_log(log_ctx, AV_LOG_ERROR, "Invalid amount of layers for CHANNEL_BASED audio element. Must be >= 1\n");
264 return AVERROR(EINVAL);
265 }
266
267 for (int j, i = 0; i < iamf_audio_element->nb_layers; i++) {
268 const AVIAMFLayer *layer = iamf_audio_element->layers[i];
269
270 for (j = 0; j < FF_ARRAY_ELEMS(ff_iamf_scalable_ch_layouts); j++)
271 if (av_channel_layout_subset(&layer->ch_layout, UINT64_MAX) ==
273 break;
274
277 if (av_channel_layout_subset(&layer->ch_layout, UINT64_MAX) ==
279 break;
280
284 av_log(log_ctx, AV_LOG_ERROR, "Unsupported channel layout in Audio Element id %"PRId64
285 ", Layer %d: %s\n",
286 stg->id, i, bp.str);
288 return AVERROR(EINVAL);
289 }
290 }
291
292 if (!i)
293 continue;
294
295 const AVIAMFLayer *prev_layer = iamf_audio_element->layers[i-1];
296 uint64_t prev_mask = av_channel_layout_subset(&prev_layer->ch_layout, UINT64_MAX);
297 if (av_channel_layout_subset(&layer->ch_layout, prev_mask) != prev_mask || (layer->ch_layout.nb_channels <=
298 prev_layer->ch_layout.nb_channels)) {
300 av_bprintf(&bp, "Channel layout \"");
302 av_bprintf(&bp, "\" can't follow channel layout \"");
304 av_bprintf(&bp, "\" in Scalable Audio Element id %"PRId64, stg->id);
305 av_log(log_ctx, AV_LOG_ERROR, "%s\n", bp.str);
307 return AVERROR(EINVAL);
308 }
309 }
310 }
311
312 for (int i = 0; i < iamf->nb_audio_elements; i++) {
313 if (stg->id == iamf->audio_elements[i]->audio_element_id) {
314 av_log(log_ctx, AV_LOG_ERROR, "Duplicated Audio Element id %"PRId64"\n", stg->id);
315 return AVERROR(EINVAL);
316 }
317 }
318
319 codec_config = av_mallocz(sizeof(*codec_config));
320 if (!codec_config)
321 return AVERROR(ENOMEM);
322
323 ret = fill_codec_config(iamf, stg, codec_config, log_ctx);
324 if (ret < 0) {
325 av_free(codec_config);
326 return ret;
327 }
328
329 audio_element = av_mallocz(sizeof(*audio_element));
330 if (!audio_element)
331 return AVERROR(ENOMEM);
332
333 audio_element->celement = stg->params.iamf_audio_element;
334 audio_element->audio_element_id = stg->id;
335 audio_element->codec_config_id = ret;
336
337 audio_element->substreams = av_calloc(stg->nb_streams, sizeof(*audio_element->substreams));
338 if (!audio_element->substreams) {
339 ret = AVERROR(ENOMEM);
340 goto fail;
341 }
342 audio_element->nb_substreams = stg->nb_streams;
343
344 audio_element->layers = av_calloc(iamf_audio_element->nb_layers, sizeof(*audio_element->layers));
345 if (!audio_element->layers) {
346 ret = AVERROR(ENOMEM);
347 goto fail;
348 }
349
350 for (int i = 0, j = 0; i < iamf_audio_element->nb_layers; i++) {
351 int nb_channels = iamf_audio_element->layers[i]->ch_layout.nb_channels;
352
353 IAMFLayer *layer = &audio_element->layers[i];
354
355 if (i)
356 nb_channels -= iamf_audio_element->layers[i - 1]->ch_layout.nb_channels;
357 for (; nb_channels > 0 && j < stg->nb_streams; j++) {
358 const AVStream *st = stg->streams[j];
359 IAMFSubStream *substream = &audio_element->substreams[j];
360
361 substream->audio_substream_id = st->id;
362 layer->substream_count++;
364 nb_channels -= st->codecpar->ch_layout.nb_channels;
365 }
366 if (nb_channels) {
367 av_log(log_ctx, AV_LOG_ERROR, "Invalid channel count across substreams in layer %u from stream group %u\n",
368 i, stg->index);
369 ret = AVERROR(EINVAL);
370 goto fail;
371 }
372 }
373
374 for (int i = 0; i < audio_element->nb_substreams; i++) {
375 for (int j = i + 1; j < audio_element->nb_substreams; j++)
376 if (audio_element->substreams[i].audio_substream_id ==
377 audio_element->substreams[j].audio_substream_id) {
378 av_log(log_ctx, AV_LOG_ERROR, "Duplicate id %u in streams %u and %u from stream group %u\n",
379 audio_element->substreams[i].audio_substream_id, i, j, stg->index);
380 ret = AVERROR(EINVAL);
381 goto fail;
382 }
383 }
384
385 if (iamf_audio_element->demixing_info) {
386 AVIAMFParamDefinition *param = iamf_audio_element->demixing_info;
388
389 if (param->nb_subblocks != 1) {
390 av_log(log_ctx, AV_LOG_ERROR, "nb_subblocks in demixing_info for stream group %u is not 1\n", stg->index);
391 ret = AVERROR(EINVAL);
392 goto fail;
393 }
394
395 if (!param_definition) {
396 ret = add_param_definition(iamf, param, audio_element, log_ctx);
397 if (ret < 0)
398 goto fail;
399 }
400 }
401 if (iamf_audio_element->recon_gain_info) {
402 AVIAMFParamDefinition *param = iamf_audio_element->recon_gain_info;
404
405 if (param->nb_subblocks != 1) {
406 av_log(log_ctx, AV_LOG_ERROR, "nb_subblocks in recon_gain_info for stream group %u is not 1\n", stg->index);
407 ret = AVERROR(EINVAL);
408 goto fail;
409 }
410
411 if (!param_definition) {
412 ret = add_param_definition(iamf, param, audio_element, log_ctx);
413 if (ret < 0)
414 goto fail;
415 }
416 }
417
418 tmp = av_realloc_array(iamf->audio_elements, iamf->nb_audio_elements + 1, sizeof(*iamf->audio_elements));
419 if (!tmp) {
420 ret = AVERROR(ENOMEM);
421 goto fail;
422 }
423
424 iamf->audio_elements = tmp;
425 iamf->audio_elements[iamf->nb_audio_elements++] = audio_element;
426
427 return 0;
428fail:
429 ff_iamf_free_audio_element(&audio_element);
430 return ret;
431}
432
433int ff_iamf_add_mix_presentation(IAMFContext *iamf, const AVStreamGroup *stg, void *log_ctx)
434{
435 IAMFMixPresentation **tmp, *mix_presentation;
436 int ret;
437
439 return AVERROR(EINVAL);
440 if (!stg->nb_streams) {
441 av_log(log_ctx, AV_LOG_ERROR, "Mix Presentation id %"PRId64" has no streams\n", stg->id);
442 return AVERROR(EINVAL);
443 }
444
445 for (int i = 0; i < iamf->nb_mix_presentations; i++) {
446 if (stg->id == iamf->mix_presentations[i]->mix_presentation_id) {
447 av_log(log_ctx, AV_LOG_ERROR, "Duplicate Mix Presentation id %"PRId64"\n", stg->id);
448 return AVERROR(EINVAL);
449 }
450 }
451
452 mix_presentation = av_mallocz(sizeof(*mix_presentation));
453 if (!mix_presentation)
454 return AVERROR(ENOMEM);
455
456 mix_presentation->cmix = stg->params.iamf_mix_presentation;
457 mix_presentation->mix_presentation_id = stg->id;
458
459 for (int i = 0; i < mix_presentation->cmix->nb_submixes; i++) {
460 const AVIAMFSubmix *submix = mix_presentation->cmix->submixes[i];
463
464 if (!param) {
465 av_log(log_ctx, AV_LOG_ERROR, "output_mix_config is not present in submix %u from "
466 "Mix Presentation ID %"PRId64"\n", i, stg->id);
467 ret = AVERROR(EINVAL);
468 goto fail;
469 }
470
472 if (!param_definition) {
473 ret = add_param_definition(iamf, param, NULL, log_ctx);
474 if (ret < 0)
475 goto fail;
476 }
477
478 for (int j = 0; j < submix->nb_elements; j++) {
479 const AVIAMFSubmixElement *element = submix->elements[j];
480 param = element->element_mix_config;
481
482 if (!param) {
483 av_log(log_ctx, AV_LOG_ERROR, "element_mix_config is not present for element %u in submix %u from "
484 "Mix Presentation ID %"PRId64"\n", j, i, stg->id);
485 ret = AVERROR(EINVAL);
486 goto fail;
487 }
489 if (!param_definition) {
490 ret = add_param_definition(iamf, param, NULL, log_ctx);
491 if (ret < 0)
492 goto fail;
493 }
494 }
495 }
496
498 if (!tmp) {
499 ret = AVERROR(ENOMEM);
500 goto fail;
501 }
502
503 iamf->mix_presentations = tmp;
504 iamf->mix_presentations[iamf->nb_mix_presentations++] = mix_presentation;
505
506 return 0;
507fail:
508 ff_iamf_free_mix_presentation(&mix_presentation);
509 return ret;
510}
511
513 const IAMFCodecConfig *codec_config,
514 AVIOContext *pb)
515{
517 AVIOContext *dyn_bc;
518 uint8_t *dyn_buf = NULL;
519 PutBitContext pbc;
520 int dyn_size;
521
522 int ret = avio_open_dyn_buf(&dyn_bc);
523 if (ret < 0)
524 return ret;
525
526 ffio_write_leb(dyn_bc, codec_config->codec_config_id);
527 avio_wl32(dyn_bc, codec_config->codec_tag);
528
529 ffio_write_leb(dyn_bc, codec_config->nb_samples);
530 avio_wb16(dyn_bc, codec_config->audio_roll_distance);
531
532 switch(codec_config->codec_id) {
533 case AV_CODEC_ID_OPUS:
534 avio_write(dyn_bc, codec_config->extradata, codec_config->extradata_size);
535 break;
536 case AV_CODEC_ID_AAC:
538 case AV_CODEC_ID_FLAC:
539 avio_w8(dyn_bc, 0x80);
540 avio_wb24(dyn_bc, codec_config->extradata_size);
541 avio_write(dyn_bc, codec_config->extradata, codec_config->extradata_size);
542 break;
544 avio_w8(dyn_bc, 1);
545 avio_w8(dyn_bc, 16);
546 avio_wb32(dyn_bc, codec_config->sample_rate);
547 break;
549 avio_w8(dyn_bc, 1);
550 avio_w8(dyn_bc, 24);
551 avio_wb32(dyn_bc, codec_config->sample_rate);
552 break;
554 avio_w8(dyn_bc, 1);
555 avio_w8(dyn_bc, 32);
556 avio_wb32(dyn_bc, codec_config->sample_rate);
557 break;
559 avio_w8(dyn_bc, 0);
560 avio_w8(dyn_bc, 16);
561 avio_wb32(dyn_bc, codec_config->sample_rate);
562 break;
564 avio_w8(dyn_bc, 0);
565 avio_w8(dyn_bc, 24);
566 avio_wb32(dyn_bc, codec_config->sample_rate);
567 break;
569 avio_w8(dyn_bc, 0);
570 avio_w8(dyn_bc, 32);
571 avio_wb32(dyn_bc, codec_config->sample_rate);
572 break;
573 default:
574 break;
575 }
576
577 init_put_bits(&pbc, header, sizeof(header));
579 put_bits(&pbc, 3, 0);
580 flush_put_bits(&pbc);
581
582 dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
583 avio_write(pb, header, put_bytes_count(&pbc, 1));
584 ffio_write_leb(pb, dyn_size);
585 avio_write(pb, dyn_buf, dyn_size);
586 ffio_free_dyn_buf(&dyn_bc);
587
588 return 0;
589}
590
591static inline int rescale_rational(AVRational q, int b)
592{
593 return av_clip_int16(av_rescale(q.num, b, q.den));
594}
595
596static void get_loudspeaker_layout(const AVIAMFLayer *layer,
597 int *playout, int *pexpanded_layout)
598{
599 int layout, expanded_layout = -1;
600
603 break;
604 }
607 if (av_channel_layout_subset(&layer->ch_layout, UINT64_MAX) ==
609 break;
610 }
612 layout = 15;
613 for (expanded_layout = 0; expanded_layout < FF_ARRAY_ELEMS(ff_iamf_expanded_scalable_ch_layouts); expanded_layout++) {
615 break;
616 }
618 for (expanded_layout = 0; expanded_layout < FF_ARRAY_ELEMS(ff_iamf_expanded_scalable_ch_layouts); expanded_layout++)
619 if (av_channel_layout_subset(&layer->ch_layout, UINT64_MAX) ==
621 break;
622 }
623 }
624 av_assert0((expanded_layout > 0 && expanded_layout < FF_ARRAY_ELEMS(ff_iamf_expanded_scalable_ch_layouts)) ||
626
627 *playout = layout;
628 *pexpanded_layout = expanded_layout;
629}
630
631static int scalable_channel_layout_config(const IAMFAudioElement *audio_element,
632 AVIOContext *dyn_bc)
633{
634 const AVIAMFAudioElement *element = audio_element->celement;
636 PutBitContext pb;
637
638 init_put_bits(&pb, header, sizeof(header));
639 put_bits(&pb, 3, element->nb_layers);
640 put_bits(&pb, 5, 0);
641 flush_put_bits(&pb);
642 avio_write(dyn_bc, header, put_bytes_count(&pb, 1));
643 for (int i = 0; i < element->nb_layers; i++) {
644 const AVIAMFLayer *layer = element->layers[i];
645 int layout, expanded_layout;
646
647 get_loudspeaker_layout(layer, &layout, &expanded_layout);
648 init_put_bits(&pb, header, sizeof(header));
649 put_bits(&pb, 4, layout);
650 put_bits(&pb, 1, !!layer->output_gain_flags);
651 put_bits(&pb, 1, !!(layer->flags & AV_IAMF_LAYER_FLAG_RECON_GAIN));
652 put_bits(&pb, 2, 0); // reserved
653 put_bits(&pb, 8, audio_element->layers[i].substream_count);
654 put_bits(&pb, 8, audio_element->layers[i].coupled_substream_count);
655 if (layer->output_gain_flags) {
656 put_bits(&pb, 6, layer->output_gain_flags);
657 put_bits(&pb, 2, 0);
658 put_bits(&pb, 16, rescale_rational(layer->output_gain, 1 << 8));
659 }
660 if (expanded_layout >= 0)
661 put_bits(&pb, 8, expanded_layout);
662 flush_put_bits(&pb);
663 avio_write(dyn_bc, header, put_bytes_count(&pb, 1));
664 }
665
666 return 0;
667}
668
669static int ambisonics_config(const IAMFAudioElement *audio_element,
670 AVIOContext *dyn_bc)
671{
672 const AVIAMFAudioElement *element = audio_element->celement;
673 const IAMFLayer *ilayer = &audio_element->layers[0];
674 const AVIAMFLayer *layer = element->layers[0];
675
676 if (audio_element->nb_substreams != ilayer->substream_count)
677 return AVERROR(EINVAL);
678
679 ffio_write_leb(dyn_bc, layer->ambisonics_mode);
680 avio_w8(dyn_bc, layer->ch_layout.nb_channels); // output_channel_count
681 avio_w8(dyn_bc, audio_element->nb_substreams); // substream_count
682
685 for (int i = 0; i < layer->ch_layout.nb_channels; i++)
686 avio_w8(dyn_bc, i);
687 else
688 for (int i = 0; i < layer->ch_layout.nb_channels; i++)
689 avio_w8(dyn_bc, layer->ch_layout.u.map[i].id);
690 } else {
691 int nb_demixing_matrix = (ilayer->coupled_substream_count + ilayer->substream_count) * layer->ch_layout.nb_channels;
692 if (nb_demixing_matrix != layer->nb_demixing_matrix)
693 return AVERROR(EINVAL);
694 avio_w8(dyn_bc, ilayer->coupled_substream_count);
695 for (int i = 0; i < layer->nb_demixing_matrix; i++)
696 avio_wb16(dyn_bc, rescale_rational(layer->demixing_matrix[i], 1 << 15));
697 }
698
699 return 0;
700}
701
702static int param_definition(const IAMFContext *iamf,
703 const IAMFParamDefinition *param_def,
704 AVIOContext *dyn_bc, void *log_ctx)
705{
706 const AVIAMFParamDefinition *param = param_def->param;
707
708 ffio_write_leb(dyn_bc, param->parameter_id);
709 ffio_write_leb(dyn_bc, param->parameter_rate);
710 avio_w8(dyn_bc, param->duration ? 0 : 1 << 7);
711 if (param->duration) {
712 ffio_write_leb(dyn_bc, param->duration);
714 if (param->constant_subblock_duration == 0) {
715 ffio_write_leb(dyn_bc, param->nb_subblocks);
716 for (int i = 0; i < param->nb_subblocks; i++) {
717 const void *subblock = av_iamf_param_definition_get_subblock(param, i);
718
719 switch (param->type) {
721 const AVIAMFMixGain *mix = subblock;
722 ffio_write_leb(dyn_bc, mix->subblock_duration);
723 break;
724 }
726 const AVIAMFDemixingInfo *demix = subblock;
727 ffio_write_leb(dyn_bc, demix->subblock_duration);
728 break;
729 }
731 const AVIAMFReconGain *recon = subblock;
732 ffio_write_leb(dyn_bc, recon->subblock_duration);
733 break;
734 }
735 }
736 }
737 }
738 }
739
740 return 0;
741}
742
744 const IAMFAudioElement *audio_element,
745 AVIOContext *pb, void *log_ctx)
746{
747 const AVIAMFAudioElement *element = audio_element->celement;
748 const IAMFCodecConfig *codec_config = iamf->codec_configs[audio_element->codec_config_id];
750 AVIOContext *dyn_bc;
751 uint8_t *dyn_buf = NULL;
752 PutBitContext pbc;
753 int param_definition_types = AV_IAMF_PARAMETER_DEFINITION_DEMIXING, dyn_size;
754
755 int ret = avio_open_dyn_buf(&dyn_bc);
756 if (ret < 0)
757 return ret;
758
759 ffio_write_leb(dyn_bc, audio_element->audio_element_id);
760
761 init_put_bits(&pbc, header, sizeof(header));
762 put_bits(&pbc, 3, element->audio_element_type);
763 put_bits(&pbc, 5, 0);
764 flush_put_bits(&pbc);
765 avio_write(dyn_bc, header, put_bytes_count(&pbc, 1));
766
767 ffio_write_leb(dyn_bc, audio_element->codec_config_id);
768 ffio_write_leb(dyn_bc, audio_element->nb_substreams);
769
770 for (int i = 0; i < audio_element->nb_substreams; i++)
771 ffio_write_leb(dyn_bc, audio_element->substreams[i].audio_substream_id);
772
773 /* When audio_element_type = 1, num_parameters SHALL be set to 0 */
775 param_definition_types = 0;
776 else {
777 int layout = 0, expanded_layout = 0;
778 get_loudspeaker_layout(element->layers[0], &layout, &expanded_layout);
779 /* When the loudspeaker_layout = 15, the type PARAMETER_DEFINITION_DEMIXING SHALL NOT be present. */
780 if (layout == 15) {
781 param_definition_types &= ~AV_IAMF_PARAMETER_DEFINITION_DEMIXING;
782 /* expanded_loudspeaker_layout SHALL only be present when num_layers = 1 and loudspeaker_layout is set to 15 */
783 if (element->nb_layers > 1) {
784 av_log(log_ctx, AV_LOG_ERROR, "expanded_loudspeaker_layout present when using more than one layer in "
785 "Stream Group #%u\n",
786 audio_element->audio_element_id);
787 return AVERROR(EINVAL);
788 }
789 }
790 /* When the loudspeaker_layout of the (non-)scalable channel audio (i.e., num_layers = 1) is less than or equal to 3.1.2ch,
791 * (i.e., Mono, Stereo, or 3.1.2ch), the type PARAMETER_DEFINITION_DEMIXING SHALL NOT be present. */
792 else if (element->nb_layers == 1 && (layout == 0 || layout == 1 || layout == 8))
793 param_definition_types &= ~AV_IAMF_PARAMETER_DEFINITION_DEMIXING;
794 /* When num_layers > 1, the type PARAMETER_DEFINITION_RECON_GAIN SHALL be present */
795 if (element->nb_layers > 1)
796 param_definition_types |= AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN;
797 /* When codec_id = fLaC or ipcm, the type PARAMETER_DEFINITION_RECON_GAIN SHALL NOT be present. */
798 if (codec_config->codec_tag == MKTAG('f','L','a','C') ||
799 codec_config->codec_tag == MKTAG('i','p','c','m'))
800 param_definition_types &= ~AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN;
801 if ((param_definition_types & AV_IAMF_PARAMETER_DEFINITION_DEMIXING) && !element->demixing_info) {
802 if (element->nb_layers > 1) {
803 get_loudspeaker_layout(element->layers[element->nb_layers-1], &layout, &expanded_layout);
804 /* When the highest loudspeaker_layout of the scalable channel audio (i.e., num_layers > 1) is greater than 3.1.2ch,
805 * (i.e., 5.1.2ch, 5.1.4ch, 7.1.2ch, or 7.1.4ch), type PARAMETER_DEFINITION_DEMIXING SHALL be present. */
806 if (layout == 3 || layout == 4 || layout == 6 || layout == 7) {
807 av_log(log_ctx, AV_LOG_ERROR, "demixing_info needed but not set in Stream Group #%u\n",
808 audio_element->audio_element_id);
809 return AVERROR(EINVAL);
810 }
811 }
812 param_definition_types &= ~AV_IAMF_PARAMETER_DEFINITION_DEMIXING;
813 }
814 }
815
816 ffio_write_leb(dyn_bc, av_popcount(param_definition_types)); // num_parameters
817
818 if (param_definition_types & AV_IAMF_PARAMETER_DEFINITION_DEMIXING) {
819 const AVIAMFParamDefinition *param = element->demixing_info;
820 const IAMFParamDefinition *param_def;
821 const AVIAMFDemixingInfo *demix;
822
825
826 param_def = ff_iamf_get_param_definition(iamf, param->parameter_id);
827 ret = param_definition(iamf, param_def, dyn_bc, log_ctx);
828 if (ret < 0)
829 return ret;
830
831 avio_w8(dyn_bc, demix->dmixp_mode << 5); // dmixp_mode
832 avio_w8(dyn_bc, element->default_w << 4); // default_w
833 }
834 if (param_definition_types & AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN) {
835 const AVIAMFParamDefinition *param = element->recon_gain_info;
836 const IAMFParamDefinition *param_def;
837
838 if (!param) {
839 av_log(log_ctx, AV_LOG_ERROR, "recon_gain_info needed but not set in Stream Group #%u\n",
840 audio_element->audio_element_id);
841 return AVERROR(EINVAL);
842 }
844
845 param_def = ff_iamf_get_param_definition(iamf, param->parameter_id);
846 ret = param_definition(iamf, param_def, dyn_bc, log_ctx);
847 if (ret < 0)
848 return ret;
849 }
850
852 ret = scalable_channel_layout_config(audio_element, dyn_bc);
853 if (ret < 0)
854 return ret;
855 } else {
856 ret = ambisonics_config(audio_element, dyn_bc);
857 if (ret < 0)
858 return ret;
859 }
860
861 init_put_bits(&pbc, header, sizeof(header));
863 put_bits(&pbc, 3, 0);
864 flush_put_bits(&pbc);
865
866 dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
867 avio_write(pb, header, put_bytes_count(&pbc, 1));
868 ffio_write_leb(pb, dyn_size);
869 avio_write(pb, dyn_buf, dyn_size);
870 ffio_free_dyn_buf(&dyn_bc);
871
872 return 0;
873}
874
876 const IAMFMixPresentation *mix_presentation,
877 AVIOContext *pb, void *log_ctx)
878{
880 const AVIAMFMixPresentation *mix = mix_presentation->cmix;
881 const AVDictionaryEntry *tag = NULL;
882 PutBitContext pbc;
883 AVIOContext *dyn_bc;
884 uint8_t *dyn_buf = NULL;
885 int dyn_size;
886
887 int ret = avio_open_dyn_buf(&dyn_bc);
888 if (ret < 0)
889 return ret;
890
891 ffio_write_leb(dyn_bc, mix_presentation->mix_presentation_id); // mix_presentation_id
892 ffio_write_leb(dyn_bc, av_dict_count(mix->annotations)); // count_label
893
894 while ((tag = av_dict_iterate(mix->annotations, tag)))
895 avio_put_str(dyn_bc, tag->key);
896 while ((tag = av_dict_iterate(mix->annotations, tag)))
897 avio_put_str(dyn_bc, tag->value);
898
899 ffio_write_leb(dyn_bc, mix->nb_submixes);
900 for (int i = 0; i < mix->nb_submixes; i++) {
901 const AVIAMFSubmix *sub_mix = mix->submixes[i];
902 const IAMFParamDefinition *param_def;
903
904 ffio_write_leb(dyn_bc, sub_mix->nb_elements);
905 for (int j = 0; j < sub_mix->nb_elements; j++) {
906 const IAMFAudioElement *audio_element = NULL;
907 const AVIAMFSubmixElement *submix_element = sub_mix->elements[j];
908
909 for (int k = 0; k < iamf->nb_audio_elements; k++)
910 if (iamf->audio_elements[k]->audio_element_id == submix_element->audio_element_id) {
911 audio_element = iamf->audio_elements[k];
912 break;
913 }
914
915 av_assert0(audio_element);
916 ffio_write_leb(dyn_bc, submix_element->audio_element_id);
917
918 if (av_dict_count(submix_element->annotations) != av_dict_count(mix->annotations)) {
919 av_log(log_ctx, AV_LOG_ERROR, "Inconsistent amount of labels in submix %d from Mix Presentation id #%u\n",
920 j, audio_element->audio_element_id);
921 return AVERROR(EINVAL);
922 }
923 while ((tag = av_dict_iterate(submix_element->annotations, tag)))
924 avio_put_str(dyn_bc, tag->value);
925
926 init_put_bits(&pbc, header, sizeof(header));
927 put_bits(&pbc, 2, submix_element->headphones_rendering_mode);
928 put_bits(&pbc, 6, 0); // reserved
929 flush_put_bits(&pbc);
930 avio_write(dyn_bc, header, put_bytes_count(&pbc, 1));
931 ffio_write_leb(dyn_bc, 0); // rendering_config_extension_size
932
933 param_def = ff_iamf_get_param_definition(iamf, submix_element->element_mix_config->parameter_id);
934 ret = param_definition(iamf, param_def, dyn_bc, log_ctx);
935 if (ret < 0)
936 return ret;
937
938 avio_wb16(dyn_bc, rescale_rational(submix_element->default_mix_gain, 1 << 8));
939 }
940
942 ret = param_definition(iamf, param_def, dyn_bc, log_ctx);
943 if (ret < 0)
944 return ret;
945 avio_wb16(dyn_bc, rescale_rational(sub_mix->default_mix_gain, 1 << 8));
946
947 ffio_write_leb(dyn_bc, sub_mix->nb_layouts); // nb_layouts
948 for (int i = 0; i < sub_mix->nb_layouts; i++) {
949 const AVIAMFSubmixLayout *submix_layout = sub_mix->layouts[i];
950 int layout, info_type;
951 int dialogue = submix_layout->dialogue_anchored_loudness.num &&
952 submix_layout->dialogue_anchored_loudness.den;
953 int album = submix_layout->album_anchored_loudness.num &&
954 submix_layout->album_anchored_loudness.den;
955
959 break;
960 }
962 av_log(log_ctx, AV_LOG_ERROR, "Invalid Sound System value in a submix\n");
963 return AVERROR(EINVAL);
964 }
965 } else if (submix_layout->layout_type != AV_IAMF_SUBMIX_LAYOUT_TYPE_BINAURAL) {
966 av_log(log_ctx, AV_LOG_ERROR, "Unsupported Layout Type value in a submix\n");
967 return AVERROR(EINVAL);
968 }
969 init_put_bits(&pbc, header, sizeof(header));
970 put_bits(&pbc, 2, submix_layout->layout_type); // layout_type
972 put_bits(&pbc, 4, ff_iamf_sound_system_map[layout].id); // sound_system
973 put_bits(&pbc, 2, 0); // reserved
974 } else
975 put_bits(&pbc, 6, 0); // reserved
976 flush_put_bits(&pbc);
977 avio_write(dyn_bc, header, put_bytes_count(&pbc, 1));
978
979 info_type = (submix_layout->true_peak.num && submix_layout->true_peak.den);
980 info_type |= (dialogue || album) << 1;
981 avio_w8(dyn_bc, info_type);
982 avio_wb16(dyn_bc, rescale_rational(submix_layout->integrated_loudness, 1 << 8));
983 avio_wb16(dyn_bc, rescale_rational(submix_layout->digital_peak, 1 << 8));
984 if (info_type & 1)
985 avio_wb16(dyn_bc, rescale_rational(submix_layout->true_peak, 1 << 8));
986 if (info_type & 2) {
987 avio_w8(dyn_bc, dialogue + album); // num_anchored_loudness
988 if (dialogue) {
990 avio_wb16(dyn_bc, rescale_rational(submix_layout->dialogue_anchored_loudness, 1 << 8));
991 }
992 if (album) {
994 avio_wb16(dyn_bc, rescale_rational(submix_layout->album_anchored_loudness, 1 << 8));
995 }
996 }
997 }
998 }
999
1000 init_put_bits(&pbc, header, sizeof(header));
1002 put_bits(&pbc, 3, 0);
1003 flush_put_bits(&pbc);
1004
1005 dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
1006 avio_write(pb, header, put_bytes_count(&pbc, 1));
1007 ffio_write_leb(pb, dyn_size);
1008 avio_write(pb, dyn_buf, dyn_size);
1009 ffio_free_dyn_buf(&dyn_bc);
1010
1011 return 0;
1012}
1013
1014int ff_iamf_write_descriptors(const IAMFContext *iamf, AVIOContext *pb, void *log_ctx)
1015{
1016 int ret;
1017
1018 // Sequence Header
1020
1021 ffio_write_leb(pb, 6);
1022 avio_wb32(pb, MKBETAG('i','a','m','f'));
1023 avio_w8(pb, iamf->nb_audio_elements > 1); // primary_profile
1024 avio_w8(pb, iamf->nb_audio_elements > 1); // additional_profile
1025
1026 for (int i = 0; i < iamf->nb_codec_configs; i++) {
1027 ret = iamf_write_codec_config(iamf, iamf->codec_configs[i], pb);
1028 if (ret < 0)
1029 return ret;
1030 }
1031
1032 for (int i = 0; i < iamf->nb_audio_elements; i++) {
1033 ret = iamf_write_audio_element(iamf, iamf->audio_elements[i], pb, log_ctx);
1034 if (ret < 0)
1035 return ret;
1036 }
1037
1038 for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1039 ret = iamf_write_mixing_presentation(iamf, iamf->mix_presentations[i], pb, log_ctx);
1040 if (ret < 0)
1041 return ret;
1042 }
1043
1044 return 0;
1045}
1046
1048 const AVIAMFParamDefinition *param, void *log_ctx)
1049{
1052 PutBitContext pbc;
1053 AVIOContext *dyn_bc;
1054 uint8_t *dyn_buf = NULL;
1055 int dyn_size, ret;
1056
1058 av_log(log_ctx, AV_LOG_DEBUG, "Ignoring side data with unknown type %u\n",
1059 param->type);
1060 return 0;
1061 }
1062
1063 if (!param_definition) {
1064 av_log(log_ctx, AV_LOG_ERROR, "Non-existent Parameter Definition with ID %u referenced by a packet\n",
1065 param->parameter_id);
1066 return AVERROR(EINVAL);
1067 }
1068
1069 if (param->type != param_definition->param->type) {
1070 av_log(log_ctx, AV_LOG_ERROR, "Inconsistent values for Parameter Definition "
1071 "with ID %u in a packet\n",
1072 param->parameter_id);
1073 return AVERROR(EINVAL);
1074 }
1075
1076 ret = avio_open_dyn_buf(&dyn_bc);
1077 if (ret < 0)
1078 return ret;
1079
1080 // Sequence Header
1081 init_put_bits(&pbc, header, sizeof(header));
1083 put_bits(&pbc, 3, 0);
1084 flush_put_bits(&pbc);
1085 avio_write(pb, header, put_bytes_count(&pbc, 1));
1086
1087 ffio_write_leb(dyn_bc, param->parameter_id);
1088 if (!param_definition->mode) {
1089 ffio_write_leb(dyn_bc, param->duration);
1091 if (param->constant_subblock_duration == 0)
1092 ffio_write_leb(dyn_bc, param->nb_subblocks);
1093 }
1094
1095 for (int i = 0; i < param->nb_subblocks; i++) {
1096 const void *subblock = av_iamf_param_definition_get_subblock(param, i);
1097
1098 switch (param->type) {
1100 const AVIAMFMixGain *mix = subblock;
1101 if (!param_definition->mode && param->constant_subblock_duration == 0)
1102 ffio_write_leb(dyn_bc, mix->subblock_duration);
1103
1104 ffio_write_leb(dyn_bc, mix->animation_type);
1105
1106 avio_wb16(dyn_bc, rescale_rational(mix->start_point_value, 1 << 8));
1107 if (mix->animation_type >= AV_IAMF_ANIMATION_TYPE_LINEAR)
1108 avio_wb16(dyn_bc, rescale_rational(mix->end_point_value, 1 << 8));
1109 if (mix->animation_type == AV_IAMF_ANIMATION_TYPE_BEZIER) {
1110 avio_wb16(dyn_bc, rescale_rational(mix->control_point_value, 1 << 8));
1111 avio_w8(dyn_bc, av_clip_uint8(av_rescale(mix->control_point_relative_time.num, 1 << 8,
1112 mix->control_point_relative_time.den)));
1113 }
1114 break;
1115 }
1117 const AVIAMFDemixingInfo *demix = subblock;
1118 if (!param_definition->mode && param->constant_subblock_duration == 0)
1119 ffio_write_leb(dyn_bc, demix->subblock_duration);
1120
1121 avio_w8(dyn_bc, demix->dmixp_mode << 5);
1122 break;
1123 }
1125 const AVIAMFReconGain *recon = subblock;
1126 const AVIAMFAudioElement *audio_element = param_definition->audio_element->celement;
1127
1128 if (!param_definition->mode && param->constant_subblock_duration == 0)
1129 ffio_write_leb(dyn_bc, recon->subblock_duration);
1130
1131 if (!audio_element) {
1132 av_log(log_ctx, AV_LOG_ERROR, "Invalid Parameter Definition with ID %u referenced by a packet\n", param->parameter_id);
1133 return AVERROR(EINVAL);
1134 }
1135
1136 for (int j = 0; j < audio_element->nb_layers; j++) {
1137 const AVIAMFLayer *layer = audio_element->layers[j];
1138
1139 if (layer->flags & AV_IAMF_LAYER_FLAG_RECON_GAIN) {
1140 unsigned int recon_gain_flags = 0;
1141 int k = 0;
1142
1143 for (; k < 7; k++)
1144 recon_gain_flags |= (1 << k) * !!recon->recon_gain[j][k];
1145 for (; k < 12; k++)
1146 recon_gain_flags |= (2 << k) * !!recon->recon_gain[j][k];
1147 if (recon_gain_flags >> 8)
1148 recon_gain_flags |= (1 << k);
1149
1150 ffio_write_leb(dyn_bc, recon_gain_flags);
1151 for (k = 0; k < 12; k++) {
1152 if (recon->recon_gain[j][k])
1153 avio_w8(dyn_bc, recon->recon_gain[j][k]);
1154 }
1155 }
1156 }
1157 break;
1158 }
1159 default:
1160 av_unreachable("param_definition_type should have been checked above");
1161 }
1162 }
1163
1164 dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
1165 ffio_write_leb(pb, dyn_size);
1166 avio_write(pb, dyn_buf, dyn_size);
1167 ffio_free_dyn_buf(&dyn_bc);
1168
1169 return 0;
1170}
1171
1173 const AVPacket *pkt, void *log_ctx)
1174{
1178 NULL);
1179 AVIAMFParamDefinition *demix =
1182 NULL);
1183 AVIAMFParamDefinition *recon =
1186 NULL);
1187
1188 if (mix) {
1189 int ret = write_parameter_block(iamf, pb, mix, log_ctx);
1190 if (ret < 0)
1191 return ret;
1192 }
1193 if (demix) {
1194 int ret = write_parameter_block(iamf, pb, demix, log_ctx);
1195 if (ret < 0)
1196 return ret;
1197 }
1198 if (recon) {
1199 int ret = write_parameter_block(iamf, pb, recon, log_ctx);
1200 if (ret < 0)
1201 return ret;
1202 }
1203
1204 return 0;
1205}
1206
1208 unsigned int audio_substream_id)
1209{
1210 for (int i = 0; i < c->nb_audio_elements; i++) {
1211 IAMFAudioElement *audio_element = c->audio_elements[i];
1212 for (int j = 0; j < audio_element->nb_substreams; j++) {
1213 IAMFSubStream *substream = &audio_element->substreams[j];
1214 if (substream->audio_substream_id == audio_substream_id)
1215 return audio_element;
1216 }
1217 }
1218
1219 return NULL;
1220}
1221
1223 unsigned audio_substream_id, const AVPacket *pkt)
1224{
1226 PutBitContext pbc;
1227 const IAMFAudioElement *audio_element;
1228 IAMFCodecConfig *codec_config;
1229 AVIOContext *dyn_bc;
1230 const uint8_t *side_data;
1231 uint8_t *dyn_buf = NULL;
1232 unsigned int skip_samples = 0, discard_padding = 0;
1233 size_t side_data_size;
1234 int dyn_size, type = audio_substream_id <= 17 ?
1236 int ret;
1237
1238 audio_element = get_audio_element(iamf, audio_substream_id);
1239 if (!audio_element)
1240 return AVERROR(EINVAL);
1241 codec_config = ff_iamf_get_codec_config(iamf, audio_element->codec_config_id);
1242 if (!codec_config)
1243 return AVERROR(EINVAL);
1244
1245 if (!pkt->size) {
1246 size_t new_extradata_size;
1247 const uint8_t *new_extradata = av_packet_get_side_data(pkt,
1249 &new_extradata_size);
1250
1251 if (!new_extradata || new_extradata_size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
1252 return AVERROR_INVALIDDATA;
1253
1254 av_free(codec_config->extradata);
1255 codec_config->extradata = av_malloc(new_extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
1256 if (!codec_config->extradata) {
1257 codec_config->extradata_size = 0;
1258 return AVERROR(ENOMEM);
1259 }
1260 memcpy(codec_config->extradata, new_extradata, new_extradata_size);
1261 memset(codec_config->extradata + new_extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1262 codec_config->extradata_size = new_extradata_size;
1263
1264 return update_extradata(codec_config);
1265 }
1266
1268 &side_data_size);
1269
1270 if (side_data && side_data_size >= 10) {
1271 skip_samples = AV_RL32(side_data);
1272 discard_padding = AV_RL32(side_data + 4);
1273 }
1274
1275 if (codec_config->codec_id == AV_CODEC_ID_OPUS) {
1276 // IAMF's num_samples_to_trim_at_start is the same as Opus's pre-skip.
1277 skip_samples = pkt->dts < 0
1278 ? av_rescale(-pkt->dts, 48000, pkt->time_base.den)
1279 : 0;
1280 discard_padding = av_rescale(discard_padding, 48000, pkt->time_base.den);
1281 }
1282
1283 ret = avio_open_dyn_buf(&dyn_bc);
1284 if (ret < 0)
1285 return ret;
1286
1287 init_put_bits(&pbc, header, sizeof(header));
1288 put_bits(&pbc, 5, type);
1289 put_bits(&pbc, 1, 0); // obu_redundant_copy
1290 put_bits(&pbc, 1, skip_samples || discard_padding);
1291 put_bits(&pbc, 1, 0); // obu_extension_flag
1292 flush_put_bits(&pbc);
1293 avio_write(pb, header, put_bytes_count(&pbc, 1));
1294
1295 if (skip_samples || discard_padding) {
1296 ffio_write_leb(dyn_bc, discard_padding);
1297 ffio_write_leb(dyn_bc, skip_samples);
1298 }
1299
1300 if (audio_substream_id > 17)
1301 ffio_write_leb(dyn_bc, audio_substream_id);
1302
1303 dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
1304 ffio_write_leb(pb, dyn_size + pkt->size);
1305 avio_write(pb, dyn_buf, dyn_size);
1306 ffio_free_dyn_buf(&dyn_bc);
1307 avio_write(pb, pkt->data, pkt->size);
1308
1309 return 0;
1310}
#define av_unreachable(msg)
Asserts that are used as compiler optimization hints depending upon ASSERT_LEVEL and NBDEBUG.
Definition avassert.h:109
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
Main libavformat public API header.
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition avformat.h:1149
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition avformat.h:1148
void avio_wl32(AVIOContext *s, unsigned int val)
Definition aviobuf.c:360
int avio_put_str(AVIOContext *s, const char *str)
Write a NULL-terminated string.
Definition aviobuf.c:376
void avio_w8(AVIOContext *s, int b)
Definition aviobuf.c:184
void avio_wb32(AVIOContext *s, unsigned int val)
Definition aviobuf.c:368
void avio_wb16(AVIOContext *s, unsigned int val)
Definition aviobuf.c:446
void avio_wb24(AVIOContext *s, unsigned int val)
Definition aviobuf.c:458
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition aviobuf.c:206
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition aviobuf.c:1365
int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition aviobuf.c:1377
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition aviobuf.c:1438
void ffio_write_leb(AVIOContext *s, unsigned val)
Definition aviobuf.c:947
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition bprint.c:122
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition bprint.c:69
AVBPrint public header.
#define AV_BPRINT_SIZE_AUTOMATIC
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
Public libavutil channel layout APIs header.
#define av_popcount
Definition common.h:154
#define av_clip_int16
Definition common.h:115
#define av_clip_uint8
Definition common.h:106
#define NULL
Definition coverity.c:32
static AVPacket * pkt
bitstream reader API header.
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition get_bits.h:424
static void skip_bits(GetBitContext *s, int n)
Definition get_bits.h:383
static uint64_t get_bits64(GetBitContext *s, int n)
Read 0-64 bits.
Definition get_bits.h:456
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition get_bits.h:544
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition get_bits.h:337
#define fail
Definition test.h:479
@ AV_CODEC_ID_PCM_S24BE
Definition codec_id.h:343
@ AV_CODEC_ID_PCM_S16LE
Definition codec_id.h:330
@ AV_CODEC_ID_PCM_S16BE
Definition codec_id.h:331
@ AV_CODEC_ID_PCM_S24LE
Definition codec_id.h:342
@ AV_CODEC_ID_PCM_S32LE
Definition codec_id.h:338
@ AV_CODEC_ID_AAC
Definition codec_id.h:455
@ AV_CODEC_ID_FLAC
Definition codec_id.h:465
@ AV_CODEC_ID_PCM_S32BE
Definition codec_id.h:339
@ AV_CODEC_ID_OPUS
Definition codec_id.h:513
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
@ AV_PKT_DATA_SKIP_SAMPLES
Recommends skipping the specified number of samples.
Definition packet.h:153
@ AV_PKT_DATA_IAMF_RECON_GAIN_INFO_PARAM
IAMF Recon Gain Info Parameter Data associated with the audio frame.
Definition packet.h:320
@ AV_PKT_DATA_IAMF_DEMIXING_INFO_PARAM
IAMF Demixing Info Parameter Data associated with the audio frame.
Definition packet.h:312
@ AV_PKT_DATA_NEW_EXTRADATA
The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format that the extradata buffer was...
Definition packet.h:56
@ AV_PKT_DATA_IAMF_MIX_GAIN_PARAM
IAMF Mix Gain Parameter Data associated with the audio frame.
Definition packet.h:304
uint8_t * av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, size_t *size)
Get side information from packet.
Definition packet.c:252
int av_channel_layout_describe_bprint(const AVChannelLayout *channel_layout, AVBPrint *bp)
bprint variant of av_channel_layout_describe().
int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout *chl1)
Check whether two channel layouts are semantically the same, i.e.
uint64_t av_channel_layout_subset(const AVChannelLayout *channel_layout, uint64_t mask)
Find out what channels from a given set are present in a channel layout, without regard for their pos...
@ AV_CHANNEL_ORDER_CUSTOM
The channel order does not correspond to any other predefined order and is stored as an explicit map.
@ AV_CHANNEL_ORDER_AMBISONIC
The audio is represented as the decomposition of the sound field into spherical harmonics.
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition bprint.c:235
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition dict.c:42
int av_dict_count(const AVDictionary *m)
Get number of entries in dictionary.
Definition dict.c:37
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_IAMF_LAYER_FLAG_RECON_GAIN
Recon gain information for the layer is present in AVIAMFReconGain.
Definition iamf.h:280
@ AV_IAMF_AMBISONICS_MODE_MONO
Definition iamf.h:273
@ AV_IAMF_AMBISONICS_MODE_PROJECTION
Definition iamf.h:274
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition iamf.h:349
@ AV_IAMF_AUDIO_ELEMENT_TYPE_CHANNEL
Definition iamf.h:348
@ AV_IAMF_SUBMIX_LAYOUT_TYPE_BINAURAL
The layout is binaural.
Definition iamf.h:508
@ AV_IAMF_SUBMIX_LAYOUT_TYPE_LOUDSPEAKERS
The layout follows the loudspeaker sound system convention of ITU-2051-3.
Definition iamf.h:501
static av_always_inline void * av_iamf_param_definition_get_subblock(const AVIAMFParamDefinition *par, unsigned int idx)
Get the subblock at the specified idx.
Definition iamf.h:260
@ AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN
Subblocks are of struct type AVIAMFReconGain.
Definition iamf.h:181
@ AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN
Subblocks are of struct type AVIAMFMixGain.
Definition iamf.h:173
@ AV_IAMF_PARAMETER_DEFINITION_DEMIXING
Subblocks are of struct type AVIAMFDemixingInfo.
Definition iamf.h:177
@ AV_IAMF_ANIMATION_TYPE_BEZIER
Definition iamf.h:69
@ AV_IAMF_ANIMATION_TYPE_LINEAR
Definition iamf.h:68
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition mem.c:217
cl_device_type type
static IAMFAudioElement * get_audio_element(const IAMFContext *c, unsigned int audio_substream_id)
static int iamf_write_codec_config(const IAMFContext *iamf, const IAMFCodecConfig *codec_config, AVIOContext *pb)
int ff_iamf_write_descriptors(const IAMFContext *iamf, AVIOContext *pb, void *log_ctx)
int ff_iamf_write_audio_frame(const IAMFContext *iamf, AVIOContext *pb, unsigned audio_substream_id, const AVPacket *pkt)
int ff_iamf_add_mix_presentation(IAMFContext *iamf, const AVStreamGroup *stg, void *log_ctx)
static int ambisonics_config(const IAMFAudioElement *audio_element, AVIOContext *dyn_bc)
static int iamf_write_audio_element(const IAMFContext *iamf, const IAMFAudioElement *audio_element, AVIOContext *pb, void *log_ctx)
static int add_param_definition(IAMFContext *iamf, AVIAMFParamDefinition *param, const IAMFAudioElement *audio_element, void *log_ctx)
static int populate_audio_roll_distance(IAMFCodecConfig *codec_config)
Definition iamf_writer.c:80
static int param_definition(const IAMFContext *iamf, const IAMFParamDefinition *param_def, AVIOContext *dyn_bc, void *log_ctx)
static int write_parameter_block(const IAMFContext *iamf, AVIOContext *pb, const AVIAMFParamDefinition *param, void *log_ctx)
static int iamf_write_mixing_presentation(const IAMFContext *iamf, const IAMFMixPresentation *mix_presentation, AVIOContext *pb, void *log_ctx)
static int rescale_rational(AVRational q, int b)
int ff_iamf_add_audio_element(IAMFContext *iamf, const AVStreamGroup *stg, void *log_ctx)
static void get_loudspeaker_layout(const AVIAMFLayer *layer, int *playout, int *pexpanded_layout)
static int scalable_channel_layout_config(const IAMFAudioElement *audio_element, AVIOContext *dyn_bc)
int ff_iamf_write_parameter_blocks(const IAMFContext *iamf, AVIOContext *pb, const AVPacket *pkt, void *log_ctx)
static int fill_codec_config(IAMFContext *iamf, const AVStreamGroup *stg, IAMFCodecConfig *codec_config, void *log_ctx)
static int update_extradata(IAMFCodecConfig *codec_config)
Definition iamf_writer.c:35
#define b
Definition input.c:43
#define AV_RL16A(p)
#define AV_RL8(x)
#define AV_RL32(p)
#define AV_WB8(p, d)
#define AV_WB16A(p, v)
#define AV_RL32A(p)
#define AV_WB32A(p, v)
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition j2kenc.c:154
static int mix(int c0, int c1)
Definition 4xm.c:717
void ff_iamf_free_mix_presentation(IAMFMixPresentation **pmix_presentation)
Definition iamf.c:158
void ff_iamf_free_audio_element(IAMFAudioElement **paudio_element)
Definition iamf.c:143
const AVChannelLayout ff_iamf_expanded_scalable_ch_layouts[13]
Definition iamf.c:48
const AVChannelLayout ff_iamf_scalable_ch_layouts[10]
Definition iamf.c:27
const struct IAMFSoundSystemMap ff_iamf_sound_system_map[14]
Definition iamf.c:120
static IAMFParamDefinition * ff_iamf_get_param_definition(const IAMFContext *iamf, unsigned int parameter_id)
Definition iamf.h:185
#define MAX_IAMF_OBU_HEADER_SIZE
Definition iamf.h:34
@ IAMF_ANCHOR_ELEMENT_DIALOGUE
Definition iamf.h:141
@ IAMF_ANCHOR_ELEMENT_ALBUM
Definition iamf.h:142
static IAMFCodecConfig * ff_iamf_get_codec_config(const IAMFContext *c, unsigned int codec_config_id)
Definition iamf.h:172
@ IAMF_OBU_IA_AUDIO_FRAME
Definition iamf.h:43
@ IAMF_OBU_IA_MIX_PRESENTATION
Definition iamf.h:40
@ IAMF_OBU_IA_PARAMETER_BLOCK
Definition iamf.h:41
@ IAMF_OBU_IA_AUDIO_ELEMENT
Definition iamf.h:39
@ IAMF_OBU_IA_SEQUENCE_HEADER
Definition iamf.h:63
@ IAMF_OBU_IA_CODEC_CONFIG
Definition iamf.h:38
@ IAMF_OBU_IA_AUDIO_FRAME_ID0
Definition iamf.h:44
Immersive Audio Model and Formats API header.
#define MKTAG(a, b, c, d)
Definition macros.h:55
#define MKBETAG(a, b, c, d)
Definition macros.h:56
uint64_t layout
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:264
Memory handling functions.
uint32_t tag
Definition movenc.c:2073
#define av_malloc(s)
Definition ops_static.c:52
bitstream writer API
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition put_bits.h:62
static int put_bytes_count(const PutBitContext *s, int round_up)
Definition put_bits.h:110
static int put_bits_left(PutBitContext *s)
Definition put_bits.h:135
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition put_bits.h:153
static void put_bits63(PutBitContext *s, int n, uint64_t value)
Write up to 63 bits into a bitstream.
Definition put_bits.h:344
static av_unused void put_bits32(PutBitContext *s, uint32_t value)
Write exactly 32 bits into a bitstream.
Definition put_bits.h:301
static const uint8_t header[24]
Definition sdr2.c:68
#define FF_ARRAY_ELEMS(a)
enum AVChannel id
enum AVChannelOrder order
Channel order used in this layout.
union AVChannelLayout::@162063043056170047076125117143030261346263330336 u
Details about which channels are present in this layout.
int nb_channels
Number of channels in this layout.
AVChannelCustom * map
This member must be used when the channel order is AV_CHANNEL_ORDER_CUSTOM.
int extradata_size
Size of the extradata content in bytes.
Definition codec_par.h:75
int frame_size
Audio frame size, if known.
Definition codec_par.h:227
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition codec_par.h:207
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition codec_par.h:61
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition codec_par.h:71
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
int sample_rate
The number of audio samples per second.
Definition codec_par.h:213
Information on how to combine one or more audio streams, as defined in section 3.6 of IAMF.
Definition iamf.h:359
enum AVIAMFAudioElementType audio_element_type
Audio element type as defined in section 3.6 of IAMF.
Definition iamf.h:391
AVIAMFParamDefinition * recon_gain_info
Recon gain information used to reconstruct a scalable channel audio representation.
Definition iamf.h:386
unsigned int default_w
Default weight value as defined in section 3.6 of IAMF.
Definition iamf.h:396
AVIAMFParamDefinition * demixing_info
Demixing information used to reconstruct a scalable channel audio representation.
Definition iamf.h:379
AVIAMFLayer ** layers
Definition iamf.h:362
unsigned int nb_layers
Number of layers, or channel groups, in the Audio Element.
Definition iamf.h:371
Demixing Info Parameter Data as defined in section 3.8.2 of IAMF.
Definition iamf.h:128
unsigned int dmixp_mode
Pre-defined combination of demixing parameters.
Definition iamf.h:140
unsigned int subblock_duration
Duration for the given subblock, in units of 1 / parameter_rate.
Definition iamf.h:136
A layer defining a Channel Layout in the Audio Element.
Definition iamf.h:294
unsigned int flags
A bitmask which may contain a combination of AV_IAMF_LAYER_FLAG_* flags.
Definition iamf.h:302
unsigned int output_gain_flags
Output gain channel flags as defined in section 3.6.2 of IAMF.
Definition iamf.h:310
enum AVIAMFAmbisonicsMode ambisonics_mode
Ambisonics mode as defined in section 3.6.3 of IAMF.
Definition iamf.h:328
unsigned int nb_demixing_matrix
The length of the Demixing matrix array.
Definition iamf.h:343
AVRational * demixing_matrix
Demixing matrix as defined in section 3.6.3 of IAMF.
Definition iamf.h:336
AVChannelLayout ch_layout
Definition iamf.h:297
AVRational output_gain
Output gain as defined in section 3.6.2 of IAMF.
Definition iamf.h:316
Mix Gain Parameter Data as defined in section 3.8.1 of IAMF.
Definition iamf.h:77
Information on how to render and mix one or more AVIAMFAudioElement to generate the final audio outpu...
Definition iamf.h:616
unsigned int nb_submixes
Number of submixes in the presentation.
Definition iamf.h:632
AVIAMFSubmix ** submixes
Array of submixes.
Definition iamf.h:625
Parameters as defined in section 3.6.1 of IAMF.
Definition iamf.h:193
unsigned int parameter_rate
Sample rate for the parameter substream.
Definition iamf.h:222
unsigned int duration
The accumulated duration of all blocks in this parameter definition, in units of 1 / parameter_rate.
Definition iamf.h:231
unsigned int constant_subblock_duration
The duration of every subblock in the case where all subblocks, with the optional exception of the la...
Definition iamf.h:238
unsigned int parameter_id
Identifier for the parameter substream.
Definition iamf.h:218
enum AVIAMFParamDefinitionType type
Parameters type.
Definition iamf.h:213
unsigned int nb_subblocks
Number of subblocks in the array.
Definition iamf.h:208
Recon Gain Info Parameter Data as defined in section 3.8.3 of IAMF.
Definition iamf.h:148
unsigned int subblock_duration
Duration for the given subblock, in units of 1 / parameter_rate.
Definition iamf.h:156
uint8_t recon_gain[6][12]
Array of gain values to be applied to each channel for each layer defined in the Audio Element refere...
Definition iamf.h:166
Submix element as defined in section 3.7 of IAMF.
Definition iamf.h:449
AVIAMFParamDefinition * element_mix_config
Information required required for applying any processing to the referenced and rendered Audio Elemen...
Definition iamf.h:464
unsigned int audio_element_id
The id of the Audio Element this submix element references.
Definition iamf.h:455
AVDictionary * annotations
A dictionary of strings describing the submix in different languages.
Definition iamf.h:493
enum AVIAMFHeadphonesMode headphones_rendering_mode
A value that indicates whether the referenced channel-based Audio Element shall be rendered to stereo...
Definition iamf.h:481
AVRational default_mix_gain
Default mix gain value to apply when there are no AVIAMFParamDefinition with element_mix_config's par...
Definition iamf.h:472
Submix layout as defined in section 3.7.6 of IAMF.
Definition iamf.h:517
AVRational true_peak
The true peak of the audio signal, as defined in ITU-1770-4.
Definition iamf.h:542
AVRational digital_peak
The digital (sampled) peak value of the audio signal, as defined in ITU-1770-4.
Definition iamf.h:538
enum AVIAMFSubmixLayoutType layout_type
Definition iamf.h:520
AVRational dialogue_anchored_loudness
The Dialogue loudness information, as defined in ITU-1770-4.
Definition iamf.h:546
AVRational album_anchored_loudness
The Album loudness information, as defined in ITU-1770-4.
Definition iamf.h:550
AVRational integrated_loudness
The program integrated loudness information, as defined in ITU-1770-4.
Definition iamf.h:533
AVChannelLayout sound_system
Channel layout matching one of Sound Systems A to J of ITU-2051-3, plus 7.1.2ch, 3....
Definition iamf.h:528
Submix layout as defined in section 3.7 of IAMF.
Definition iamf.h:559
AVRational default_mix_gain
Default mix gain value to apply when there are no AVIAMFParamDefinition with output_mix_config's para...
Definition iamf.h:606
unsigned int nb_elements
Number of elements in the submix.
Definition iamf.h:575
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition iamf.h:568
AVIAMFSubmixLayout ** layouts
Array of submix layouts.
Definition iamf.h:583
AVIAMFParamDefinition * output_mix_config
Information required for post-processing the mixed audio signal to generate the audio signal for play...
Definition iamf.h:598
unsigned int nb_layouts
Number of layouts in the submix.
Definition iamf.h:590
Bytestream IO Context.
Definition avio.h:160
This structure stores compressed data.
Definition packet.h:580
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
union AVStreamGroup::@166361102046003066253145020066347265153020354020 params
Group type-specific parameters.
enum AVStreamGroupParamsType type
Group type.
Definition avformat.h:1186
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition avformat.h:1193
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition avformat.h:1221
unsigned int index
Group index in AVFormatContext.
Definition avformat.h:1170
struct AVIAMFAudioElement * iamf_audio_element
Definition avformat.h:1192
int64_t id
Group type-specific group ID.
Definition avformat.h:1178
AVStream ** streams
A list of streams in the group.
Definition avformat.h:1234
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
int id
Format-specific stream ID.
Definition avformat.h:778
unsigned int codec_config_id
Definition iamf.h:101
IAMFLayer * layers
Definition iamf.h:103
unsigned int audio_element_id
Definition iamf.h:96
const AVIAMFAudioElement * celement
Definition iamf.h:90
unsigned int nb_substreams
Definition iamf.h:99
IAMFSubStream * substreams
Definition iamf.h:98
int sample_rate
Definition iamf.h:72
int audio_roll_distance
Definition iamf.h:71
int extradata_size
Definition iamf.h:73
enum AVCodecID codec_id
Definition iamf.h:68
unsigned nb_samples
Definition iamf.h:70
unsigned codec_config_id
Definition iamf.h:67
uint32_t codec_tag
Definition iamf.h:69
uint8_t * extradata
Definition iamf.h:74
IAMFParamDefinition ** param_definitions
Definition iamf.h:135
int nb_param_definitions
Definition iamf.h:136
int nb_mix_presentations
Definition iamf.h:134
int nb_codec_configs
Definition iamf.h:130
IAMFMixPresentation ** mix_presentations
Definition iamf.h:133
IAMFAudioElement ** audio_elements
Definition iamf.h:131
IAMFCodecConfig ** codec_configs
Definition iamf.h:129
int nb_audio_elements
Definition iamf.h:132
unsigned int substream_count
Definition iamf.h:78
unsigned int coupled_substream_count
Definition iamf.h:79
const AVIAMFMixPresentation * cmix
Definition iamf.h:108
unsigned int mix_presentation_id
Definition iamf.h:114
AVIAMFParamDefinition * param
Definition iamf.h:123
unsigned int audio_substream_id
Definition iamf.h:83
#define av_free(p)
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
static uint8_t tmp[40]
Definition aes_ctr.c:52
static double c[64]