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->entries[0]->stream;
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_entries) {
233 av_log(log_ctx, AV_LOG_ERROR, "Audio Element id %"PRId64" has no streams\n", stg->id);
234 return AVERROR(EINVAL);
235 }
236 for (int i = 0; i < stg->nb_entries; i++) {
238 av_log(log_ctx, AV_LOG_ERROR, "Unsupported Stream Group entry #%d "
239 "in Audio Element id %"PRId64"\n",
240 i, stg->id);
241 return AVERROR(EINVAL);
242 }
243 }
244
245 iamf_audio_element = stg->params.iamf_audio_element;
246 if (iamf_audio_element->audio_element_type == AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE) {
247 const AVIAMFLayer *layer = iamf_audio_element->layers[0];
248 if (iamf_audio_element->nb_layers != 1) {
249 av_log(log_ctx, AV_LOG_ERROR, "Invalid amount of layers for SCENE_BASED audio element. Must be 1\n");
250 return AVERROR(EINVAL);
251 }
254 av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout for SCENE_BASED audio element\n");
255 return AVERROR(EINVAL);
256 }
258 av_log(log_ctx, AV_LOG_ERROR, "Unsupported ambisonics mode %d\n", layer->ambisonics_mode);
260 }
261 for (int i = 0; i < stg->nb_entries; i++) {
262 if (stg->entries[i]->stream->codecpar->ch_layout.nb_channels > 1) {
263 av_log(log_ctx, AV_LOG_ERROR, "Invalid amount of channels in a stream for MONO mode ambisonics\n");
264 return AVERROR(EINVAL);
265 }
266 }
267 } else {
268 AVBPrint bp;
269
270 if (iamf_audio_element->nb_layers < 1) {
271 av_log(log_ctx, AV_LOG_ERROR, "Invalid amount of layers for CHANNEL_BASED audio element. Must be >= 1\n");
272 return AVERROR(EINVAL);
273 }
274
275 for (int j, i = 0; i < iamf_audio_element->nb_layers; i++) {
276 const AVIAMFLayer *layer = iamf_audio_element->layers[i];
277
278 for (j = 0; j < FF_ARRAY_ELEMS(ff_iamf_scalable_ch_layouts); j++)
279 if (av_channel_layout_subset(&layer->ch_layout, UINT64_MAX) ==
281 break;
282
285 if (av_channel_layout_subset(&layer->ch_layout, UINT64_MAX) ==
287 break;
288
292 av_log(log_ctx, AV_LOG_ERROR, "Unsupported channel layout in Audio Element id %"PRId64
293 ", Layer %d: %s\n",
294 stg->id, i, bp.str);
296 return AVERROR(EINVAL);
297 }
298 }
299
300 if (!i)
301 continue;
302
303 const AVIAMFLayer *prev_layer = iamf_audio_element->layers[i-1];
304 uint64_t prev_mask = av_channel_layout_subset(&prev_layer->ch_layout, UINT64_MAX);
305 if (av_channel_layout_subset(&layer->ch_layout, prev_mask) != prev_mask || (layer->ch_layout.nb_channels <=
306 prev_layer->ch_layout.nb_channels)) {
308 av_bprintf(&bp, "Channel layout \"");
310 av_bprintf(&bp, "\" can't follow channel layout \"");
312 av_bprintf(&bp, "\" in Scalable Audio Element id %"PRId64, stg->id);
313 av_log(log_ctx, AV_LOG_ERROR, "%s\n", bp.str);
315 return AVERROR(EINVAL);
316 }
317 }
318 }
319
320 for (int i = 0; i < iamf->nb_audio_elements; i++) {
321 if (stg->id == iamf->audio_elements[i]->audio_element_id) {
322 av_log(log_ctx, AV_LOG_ERROR, "Duplicated Audio Element id %"PRId64"\n", stg->id);
323 return AVERROR(EINVAL);
324 }
325 }
326
327 codec_config = av_mallocz(sizeof(*codec_config));
328 if (!codec_config)
329 return AVERROR(ENOMEM);
330
331 ret = fill_codec_config(iamf, stg, codec_config, log_ctx);
332 if (ret < 0) {
333 av_free(codec_config);
334 return ret;
335 }
336
337 audio_element = av_mallocz(sizeof(*audio_element));
338 if (!audio_element)
339 return AVERROR(ENOMEM);
340
341 audio_element->celement = stg->params.iamf_audio_element;
342 audio_element->audio_element_id = stg->id;
343 audio_element->codec_config_id = ret;
344
345 audio_element->substreams = av_calloc(stg->nb_entries, sizeof(*audio_element->substreams));
346 if (!audio_element->substreams) {
347 ret = AVERROR(ENOMEM);
348 goto fail;
349 }
350 audio_element->nb_substreams = stg->nb_entries;
351
352 audio_element->layers = av_calloc(iamf_audio_element->nb_layers, sizeof(*audio_element->layers));
353 if (!audio_element->layers) {
354 ret = AVERROR(ENOMEM);
355 goto fail;
356 }
357
358 for (int i = 0, j = 0; i < iamf_audio_element->nb_layers; i++) {
359 int nb_channels = iamf_audio_element->layers[i]->ch_layout.nb_channels;
360
361 IAMFLayer *layer = &audio_element->layers[i];
362
363 if (i)
364 nb_channels -= iamf_audio_element->layers[i - 1]->ch_layout.nb_channels;
365 for (; nb_channels > 0 && j < stg->nb_entries; j++) {
366 const AVStream *st = stg->entries[j]->stream;
367 IAMFSubStream *substream = &audio_element->substreams[j];
368
369 substream->audio_substream_id = st->id;
370 layer->substream_count++;
372 nb_channels -= st->codecpar->ch_layout.nb_channels;
373 }
374 if (nb_channels) {
375 av_log(log_ctx, AV_LOG_ERROR, "Invalid channel count across substreams in layer %u from stream group %u\n",
376 i, stg->index);
377 ret = AVERROR(EINVAL);
378 goto fail;
379 }
380 }
381
382 for (int i = 0; i < audio_element->nb_substreams; i++) {
383 for (int j = i + 1; j < audio_element->nb_substreams; j++)
384 if (audio_element->substreams[i].audio_substream_id ==
385 audio_element->substreams[j].audio_substream_id) {
386 av_log(log_ctx, AV_LOG_ERROR, "Duplicate id %u in streams %u and %u from stream group %u\n",
387 audio_element->substreams[i].audio_substream_id, i, j, stg->index);
388 ret = AVERROR(EINVAL);
389 goto fail;
390 }
391 }
392
393 if (iamf_audio_element->demixing_info) {
394 AVIAMFParamDefinition *param = iamf_audio_element->demixing_info;
396
397 if (param->nb_subblocks != 1) {
398 av_log(log_ctx, AV_LOG_ERROR, "nb_subblocks in demixing_info for stream group %u is not 1\n", stg->index);
399 ret = AVERROR(EINVAL);
400 goto fail;
401 }
402
403 if (!param_definition) {
404 ret = add_param_definition(iamf, param, audio_element, log_ctx);
405 if (ret < 0)
406 goto fail;
407 }
408 }
409 if (iamf_audio_element->recon_gain_info) {
410 AVIAMFParamDefinition *param = iamf_audio_element->recon_gain_info;
412
413 if (param->nb_subblocks != 1) {
414 av_log(log_ctx, AV_LOG_ERROR, "nb_subblocks in recon_gain_info for stream group %u is not 1\n", stg->index);
415 ret = AVERROR(EINVAL);
416 goto fail;
417 }
418
419 if (!param_definition) {
420 ret = add_param_definition(iamf, param, audio_element, log_ctx);
421 if (ret < 0)
422 goto fail;
423 }
424 }
425
426 tmp = av_realloc_array(iamf->audio_elements, iamf->nb_audio_elements + 1, sizeof(*iamf->audio_elements));
427 if (!tmp) {
428 ret = AVERROR(ENOMEM);
429 goto fail;
430 }
431
432 iamf->audio_elements = tmp;
433 iamf->audio_elements[iamf->nb_audio_elements++] = audio_element;
434
435 return 0;
436fail:
437 ff_iamf_free_audio_element(&audio_element);
438 return ret;
439}
440
441int ff_iamf_add_mix_presentation(IAMFContext *iamf, const AVStreamGroup *stg, void *log_ctx)
442{
443 IAMFMixPresentation **tmp, *mix_presentation;
444 int ret;
445
447 return AVERROR(EINVAL);
448 if (!stg->nb_entries) {
449 av_log(log_ctx, AV_LOG_ERROR, "Mix Presentation id %"PRId64" has no streams\n", stg->id);
450 return AVERROR(EINVAL);
451 }
452 for (int i = 0; i < stg->nb_entries; i++) {
454 av_log(log_ctx, AV_LOG_ERROR, "Unsupported Stream Group entry #%d "
455 "in Mix Presentation id %"PRId64"\n",
456 i, stg->id);
457 return AVERROR(EINVAL);
458 }
459 }
460
461 for (int i = 0; i < iamf->nb_mix_presentations; i++) {
462 if (stg->id == iamf->mix_presentations[i]->mix_presentation_id) {
463 av_log(log_ctx, AV_LOG_ERROR, "Duplicate Mix Presentation id %"PRId64"\n", stg->id);
464 return AVERROR(EINVAL);
465 }
466 }
467
468 mix_presentation = av_mallocz(sizeof(*mix_presentation));
469 if (!mix_presentation)
470 return AVERROR(ENOMEM);
471
472 mix_presentation->cmix = stg->params.iamf_mix_presentation;
473 mix_presentation->mix_presentation_id = stg->id;
474
475 for (int i = 0; i < mix_presentation->cmix->nb_submixes; i++) {
476 const AVIAMFSubmix *submix = mix_presentation->cmix->submixes[i];
479
480 if (!param) {
481 av_log(log_ctx, AV_LOG_ERROR, "output_mix_config is not present in submix %u from "
482 "Mix Presentation ID %"PRId64"\n", i, stg->id);
483 ret = AVERROR(EINVAL);
484 goto fail;
485 }
486
488 if (!param_definition) {
489 ret = add_param_definition(iamf, param, NULL, log_ctx);
490 if (ret < 0)
491 goto fail;
492 }
493
494 for (int j = 0; j < submix->nb_elements; j++) {
495 const AVIAMFSubmixElement *element = submix->elements[j];
496 param = element->element_mix_config;
497
498 if (!param) {
499 av_log(log_ctx, AV_LOG_ERROR, "element_mix_config is not present for element %u in submix %u from "
500 "Mix Presentation ID %"PRId64"\n", j, i, stg->id);
501 ret = AVERROR(EINVAL);
502 goto fail;
503 }
505 if (!param_definition) {
506 ret = add_param_definition(iamf, param, NULL, log_ctx);
507 if (ret < 0)
508 goto fail;
509 }
510 }
511 }
512
514 if (!tmp) {
515 ret = AVERROR(ENOMEM);
516 goto fail;
517 }
518
519 iamf->mix_presentations = tmp;
520 iamf->mix_presentations[iamf->nb_mix_presentations++] = mix_presentation;
521
522 return 0;
523fail:
524 ff_iamf_free_mix_presentation(&mix_presentation);
525 return ret;
526}
527
529 const IAMFCodecConfig *codec_config,
530 AVIOContext *pb)
531{
533 AVIOContext *dyn_bc;
534 uint8_t *dyn_buf = NULL;
535 PutBitContext pbc;
536 int dyn_size;
537
538 int ret = avio_open_dyn_buf(&dyn_bc);
539 if (ret < 0)
540 return ret;
541
542 ffio_write_leb(dyn_bc, codec_config->codec_config_id);
543 avio_wl32(dyn_bc, codec_config->codec_tag);
544
545 ffio_write_leb(dyn_bc, codec_config->nb_samples);
546 avio_wb16(dyn_bc, codec_config->audio_roll_distance);
547
548 switch(codec_config->codec_id) {
549 case AV_CODEC_ID_OPUS:
550 avio_write(dyn_bc, codec_config->extradata, codec_config->extradata_size);
551 break;
552 case AV_CODEC_ID_AAC:
554 case AV_CODEC_ID_FLAC:
555 avio_w8(dyn_bc, 0x80);
556 avio_wb24(dyn_bc, codec_config->extradata_size);
557 avio_write(dyn_bc, codec_config->extradata, codec_config->extradata_size);
558 break;
560 avio_w8(dyn_bc, 1);
561 avio_w8(dyn_bc, 16);
562 avio_wb32(dyn_bc, codec_config->sample_rate);
563 break;
565 avio_w8(dyn_bc, 1);
566 avio_w8(dyn_bc, 24);
567 avio_wb32(dyn_bc, codec_config->sample_rate);
568 break;
570 avio_w8(dyn_bc, 1);
571 avio_w8(dyn_bc, 32);
572 avio_wb32(dyn_bc, codec_config->sample_rate);
573 break;
575 avio_w8(dyn_bc, 0);
576 avio_w8(dyn_bc, 16);
577 avio_wb32(dyn_bc, codec_config->sample_rate);
578 break;
580 avio_w8(dyn_bc, 0);
581 avio_w8(dyn_bc, 24);
582 avio_wb32(dyn_bc, codec_config->sample_rate);
583 break;
585 avio_w8(dyn_bc, 0);
586 avio_w8(dyn_bc, 32);
587 avio_wb32(dyn_bc, codec_config->sample_rate);
588 break;
589 default:
590 break;
591 }
592
593 init_put_bits(&pbc, header, sizeof(header));
595 put_bits(&pbc, 3, 0);
596 flush_put_bits(&pbc);
597
598 dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
599 avio_write(pb, header, put_bytes_count(&pbc, 1));
600 ffio_write_leb(pb, dyn_size);
601 avio_write(pb, dyn_buf, dyn_size);
602 ffio_free_dyn_buf(&dyn_bc);
603
604 return 0;
605}
606
607static inline int rescale_rational(AVRational q, int b)
608{
609 return av_clip_int16(av_rescale(q.num, b, q.den));
610}
611
612static void get_loudspeaker_layout(const AVIAMFLayer *layer,
613 int *playout, int *pexpanded_layout)
614{
615 int layout, expanded_layout = -1;
616
619 break;
620 }
623 if (av_channel_layout_subset(&layer->ch_layout, UINT64_MAX) ==
625 break;
626 }
628 layout = 15;
629 for (expanded_layout = 0; expanded_layout < FF_ARRAY_ELEMS(ff_iamf_expanded_scalable_ch_layouts); expanded_layout++) {
631 break;
632 }
634 for (expanded_layout = 0; expanded_layout < FF_ARRAY_ELEMS(ff_iamf_expanded_scalable_ch_layouts); expanded_layout++)
635 if (av_channel_layout_subset(&layer->ch_layout, UINT64_MAX) ==
637 break;
638 }
639 }
640 av_assert0((expanded_layout > 0 && expanded_layout < FF_ARRAY_ELEMS(ff_iamf_expanded_scalable_ch_layouts)) ||
642
643 *playout = layout;
644 *pexpanded_layout = expanded_layout;
645}
646
647static int scalable_channel_layout_config(const IAMFAudioElement *audio_element,
648 AVIOContext *dyn_bc)
649{
650 const AVIAMFAudioElement *element = audio_element->celement;
652 PutBitContext pb;
653
654 init_put_bits(&pb, header, sizeof(header));
655 put_bits(&pb, 3, element->nb_layers);
656 put_bits(&pb, 5, 0);
657 flush_put_bits(&pb);
658 avio_write(dyn_bc, header, put_bytes_count(&pb, 1));
659 for (int i = 0; i < element->nb_layers; i++) {
660 const AVIAMFLayer *layer = element->layers[i];
661 int layout, expanded_layout;
662
663 get_loudspeaker_layout(layer, &layout, &expanded_layout);
664 init_put_bits(&pb, header, sizeof(header));
665 put_bits(&pb, 4, layout);
666 put_bits(&pb, 1, !!layer->output_gain_flags);
667 put_bits(&pb, 1, !!(layer->flags & AV_IAMF_LAYER_FLAG_RECON_GAIN));
668 put_bits(&pb, 2, 0); // reserved
669 put_bits(&pb, 8, audio_element->layers[i].substream_count);
670 put_bits(&pb, 8, audio_element->layers[i].coupled_substream_count);
671 if (layer->output_gain_flags) {
672 put_bits(&pb, 6, layer->output_gain_flags);
673 put_bits(&pb, 2, 0);
674 put_bits(&pb, 16, rescale_rational(layer->output_gain, 1 << 8));
675 }
676 if (expanded_layout >= 0)
677 put_bits(&pb, 8, expanded_layout);
678 flush_put_bits(&pb);
679 avio_write(dyn_bc, header, put_bytes_count(&pb, 1));
680 }
681
682 return 0;
683}
684
685static int ambisonics_config(const IAMFAudioElement *audio_element,
686 AVIOContext *dyn_bc)
687{
688 const AVIAMFAudioElement *element = audio_element->celement;
689 const IAMFLayer *ilayer = &audio_element->layers[0];
690 const AVIAMFLayer *layer = element->layers[0];
691
692 if (audio_element->nb_substreams != ilayer->substream_count)
693 return AVERROR(EINVAL);
694
695 ffio_write_leb(dyn_bc, layer->ambisonics_mode);
696 avio_w8(dyn_bc, layer->ch_layout.nb_channels); // output_channel_count
697 avio_w8(dyn_bc, audio_element->nb_substreams); // substream_count
698
701 for (int i = 0; i < layer->ch_layout.nb_channels; i++)
702 avio_w8(dyn_bc, i);
703 else
704 for (int i = 0; i < layer->ch_layout.nb_channels; i++)
705 avio_w8(dyn_bc, layer->ch_layout.u.map[i].id);
706 } else {
707 int nb_demixing_matrix = (ilayer->coupled_substream_count + ilayer->substream_count) * layer->ch_layout.nb_channels;
708 if (nb_demixing_matrix != layer->nb_demixing_matrix)
709 return AVERROR(EINVAL);
710 avio_w8(dyn_bc, ilayer->coupled_substream_count);
711 for (int i = 0; i < layer->nb_demixing_matrix; i++)
712 avio_wb16(dyn_bc, rescale_rational(layer->demixing_matrix[i], 1 << 15));
713 }
714
715 return 0;
716}
717
718static int param_definition(const IAMFContext *iamf,
719 const IAMFParamDefinition *param_def,
720 AVIOContext *dyn_bc, void *log_ctx)
721{
722 const AVIAMFParamDefinition *param = param_def->param;
723
724 ffio_write_leb(dyn_bc, param->parameter_id);
725 ffio_write_leb(dyn_bc, param->parameter_rate);
726 avio_w8(dyn_bc, param->duration ? 0 : 1 << 7);
727 if (param->duration) {
728 ffio_write_leb(dyn_bc, param->duration);
730 if (param->constant_subblock_duration == 0) {
731 ffio_write_leb(dyn_bc, param->nb_subblocks);
732 for (int i = 0; i < param->nb_subblocks; i++) {
733 const void *subblock = av_iamf_param_definition_get_subblock(param, i);
734
735 switch (param->type) {
737 const AVIAMFMixGain *mix = subblock;
738 ffio_write_leb(dyn_bc, mix->subblock_duration);
739 break;
740 }
742 const AVIAMFDemixingInfo *demix = subblock;
743 ffio_write_leb(dyn_bc, demix->subblock_duration);
744 break;
745 }
747 const AVIAMFReconGain *recon = subblock;
748 ffio_write_leb(dyn_bc, recon->subblock_duration);
749 break;
750 }
751 }
752 }
753 }
754 }
755
756 return 0;
757}
758
760 const IAMFAudioElement *audio_element,
761 AVIOContext *pb, void *log_ctx)
762{
763 const AVIAMFAudioElement *element = audio_element->celement;
764 const IAMFCodecConfig *codec_config = iamf->codec_configs[audio_element->codec_config_id];
766 AVIOContext *dyn_bc;
767 uint8_t *dyn_buf = NULL;
768 PutBitContext pbc;
769 int param_definition_types = AV_IAMF_PARAMETER_DEFINITION_DEMIXING, dyn_size;
770
771 int ret = avio_open_dyn_buf(&dyn_bc);
772 if (ret < 0)
773 return ret;
774
775 ffio_write_leb(dyn_bc, audio_element->audio_element_id);
776
777 init_put_bits(&pbc, header, sizeof(header));
778 put_bits(&pbc, 3, element->audio_element_type);
779 put_bits(&pbc, 5, 0);
780 flush_put_bits(&pbc);
781 avio_write(dyn_bc, header, put_bytes_count(&pbc, 1));
782
783 ffio_write_leb(dyn_bc, audio_element->codec_config_id);
784 ffio_write_leb(dyn_bc, audio_element->nb_substreams);
785
786 for (int i = 0; i < audio_element->nb_substreams; i++)
787 ffio_write_leb(dyn_bc, audio_element->substreams[i].audio_substream_id);
788
789 /* When audio_element_type = 1, num_parameters SHALL be set to 0 */
791 param_definition_types = 0;
792 else {
793 int layout = 0, expanded_layout = 0;
794 get_loudspeaker_layout(element->layers[0], &layout, &expanded_layout);
795 /* When the loudspeaker_layout = 15, the type PARAMETER_DEFINITION_DEMIXING SHALL NOT be present. */
796 if (layout == 15) {
797 param_definition_types &= ~AV_IAMF_PARAMETER_DEFINITION_DEMIXING;
798 /* expanded_loudspeaker_layout SHALL only be present when num_layers = 1 and loudspeaker_layout is set to 15 */
799 if (element->nb_layers > 1) {
800 av_log(log_ctx, AV_LOG_ERROR, "expanded_loudspeaker_layout present when using more than one layer in "
801 "Stream Group #%u\n",
802 audio_element->audio_element_id);
803 return AVERROR(EINVAL);
804 }
805 }
806 /* When the loudspeaker_layout of the (non-)scalable channel audio (i.e., num_layers = 1) is less than or equal to 3.1.2ch,
807 * (i.e., Mono, Stereo, or 3.1.2ch), the type PARAMETER_DEFINITION_DEMIXING SHALL NOT be present. */
808 else if (element->nb_layers == 1 && (layout == 0 || layout == 1 || layout == 8))
809 param_definition_types &= ~AV_IAMF_PARAMETER_DEFINITION_DEMIXING;
810 /* When num_layers > 1, the type PARAMETER_DEFINITION_RECON_GAIN SHALL be present */
811 if (element->nb_layers > 1)
812 param_definition_types |= AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN;
813 /* When codec_id = fLaC or ipcm, the type PARAMETER_DEFINITION_RECON_GAIN SHALL NOT be present. */
814 if (codec_config->codec_tag == MKTAG('f','L','a','C') ||
815 codec_config->codec_tag == MKTAG('i','p','c','m'))
816 param_definition_types &= ~AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN;
817 if ((param_definition_types & AV_IAMF_PARAMETER_DEFINITION_DEMIXING) && !element->demixing_info) {
818 if (element->nb_layers > 1) {
819 get_loudspeaker_layout(element->layers[element->nb_layers-1], &layout, &expanded_layout);
820 /* When the highest loudspeaker_layout of the scalable channel audio (i.e., num_layers > 1) is greater than 3.1.2ch,
821 * (i.e., 5.1.2ch, 5.1.4ch, 7.1.2ch, or 7.1.4ch), type PARAMETER_DEFINITION_DEMIXING SHALL be present. */
822 if (layout == 3 || layout == 4 || layout == 6 || layout == 7) {
823 av_log(log_ctx, AV_LOG_ERROR, "demixing_info needed but not set in Stream Group #%u\n",
824 audio_element->audio_element_id);
825 return AVERROR(EINVAL);
826 }
827 }
828 param_definition_types &= ~AV_IAMF_PARAMETER_DEFINITION_DEMIXING;
829 }
830 }
831
832 ffio_write_leb(dyn_bc, av_popcount(param_definition_types)); // num_parameters
833
834 if (param_definition_types & AV_IAMF_PARAMETER_DEFINITION_DEMIXING) {
835 const AVIAMFParamDefinition *param = element->demixing_info;
836 const IAMFParamDefinition *param_def;
837 const AVIAMFDemixingInfo *demix;
838
841
842 param_def = ff_iamf_get_param_definition(iamf, param->parameter_id);
843 ret = param_definition(iamf, param_def, dyn_bc, log_ctx);
844 if (ret < 0)
845 return ret;
846
847 avio_w8(dyn_bc, demix->dmixp_mode << 5); // dmixp_mode
848 avio_w8(dyn_bc, element->default_w << 4); // default_w
849 }
850 if (param_definition_types & AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN) {
851 const AVIAMFParamDefinition *param = element->recon_gain_info;
852 const IAMFParamDefinition *param_def;
853
854 if (!param) {
855 av_log(log_ctx, AV_LOG_ERROR, "recon_gain_info needed but not set in Stream Group #%u\n",
856 audio_element->audio_element_id);
857 return AVERROR(EINVAL);
858 }
860
861 param_def = ff_iamf_get_param_definition(iamf, param->parameter_id);
862 ret = param_definition(iamf, param_def, dyn_bc, log_ctx);
863 if (ret < 0)
864 return ret;
865 }
866
868 ret = scalable_channel_layout_config(audio_element, dyn_bc);
869 if (ret < 0)
870 return ret;
871 } else {
872 ret = ambisonics_config(audio_element, dyn_bc);
873 if (ret < 0)
874 return ret;
875 }
876
877 init_put_bits(&pbc, header, sizeof(header));
879 put_bits(&pbc, 3, 0);
880 flush_put_bits(&pbc);
881
882 dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
883 avio_write(pb, header, put_bytes_count(&pbc, 1));
884 ffio_write_leb(pb, dyn_size);
885 avio_write(pb, dyn_buf, dyn_size);
886 ffio_free_dyn_buf(&dyn_bc);
887
888 return 0;
889}
890
892 const IAMFMixPresentation *mix_presentation,
893 AVIOContext *pb, void *log_ctx)
894{
896 const AVIAMFMixPresentation *mix = mix_presentation->cmix;
897 const AVDictionaryEntry *tag = NULL;
898 PutBitContext pbc;
899 AVIOContext *dyn_bc;
900 uint8_t *dyn_buf = NULL;
901 int dyn_size;
902
903 int ret = avio_open_dyn_buf(&dyn_bc);
904 if (ret < 0)
905 return ret;
906
907 ffio_write_leb(dyn_bc, mix_presentation->mix_presentation_id); // mix_presentation_id
908 ffio_write_leb(dyn_bc, av_dict_count(mix->annotations)); // count_label
909
910 while ((tag = av_dict_iterate(mix->annotations, tag)))
911 avio_put_str(dyn_bc, tag->key);
912 while ((tag = av_dict_iterate(mix->annotations, tag)))
913 avio_put_str(dyn_bc, tag->value);
914
915 ffio_write_leb(dyn_bc, mix->nb_submixes);
916 for (int i = 0; i < mix->nb_submixes; i++) {
917 const AVIAMFSubmix *sub_mix = mix->submixes[i];
918 const IAMFParamDefinition *param_def;
919
920 ffio_write_leb(dyn_bc, sub_mix->nb_elements);
921 for (int j = 0; j < sub_mix->nb_elements; j++) {
922 const IAMFAudioElement *audio_element = NULL;
923 const AVIAMFSubmixElement *submix_element = sub_mix->elements[j];
924
925 for (int k = 0; k < iamf->nb_audio_elements; k++)
926 if (iamf->audio_elements[k]->audio_element_id == submix_element->audio_element_id) {
927 audio_element = iamf->audio_elements[k];
928 break;
929 }
930
931 av_assert0(audio_element);
932 ffio_write_leb(dyn_bc, submix_element->audio_element_id);
933
934 if (av_dict_count(submix_element->annotations) != av_dict_count(mix->annotations)) {
935 av_log(log_ctx, AV_LOG_ERROR, "Inconsistent amount of labels in submix %d from Mix Presentation id #%u\n",
936 j, audio_element->audio_element_id);
937 return AVERROR(EINVAL);
938 }
939 while ((tag = av_dict_iterate(submix_element->annotations, tag)))
940 avio_put_str(dyn_bc, tag->value);
941
942 init_put_bits(&pbc, header, sizeof(header));
943 put_bits(&pbc, 2, submix_element->headphones_rendering_mode);
944 put_bits(&pbc, 6, 0); // reserved
945 flush_put_bits(&pbc);
946 avio_write(dyn_bc, header, put_bytes_count(&pbc, 1));
947 ffio_write_leb(dyn_bc, 0); // rendering_config_extension_size
948
949 param_def = ff_iamf_get_param_definition(iamf, submix_element->element_mix_config->parameter_id);
950 ret = param_definition(iamf, param_def, dyn_bc, log_ctx);
951 if (ret < 0)
952 return ret;
953
954 avio_wb16(dyn_bc, rescale_rational(submix_element->default_mix_gain, 1 << 8));
955 }
956
958 ret = param_definition(iamf, param_def, dyn_bc, log_ctx);
959 if (ret < 0)
960 return ret;
961 avio_wb16(dyn_bc, rescale_rational(sub_mix->default_mix_gain, 1 << 8));
962
963 ffio_write_leb(dyn_bc, sub_mix->nb_layouts); // nb_layouts
964 for (int i = 0; i < sub_mix->nb_layouts; i++) {
965 const AVIAMFSubmixLayout *submix_layout = sub_mix->layouts[i];
966 int layout, info_type;
967 int dialogue = submix_layout->dialogue_anchored_loudness.num &&
968 submix_layout->dialogue_anchored_loudness.den;
969 int album = submix_layout->album_anchored_loudness.num &&
970 submix_layout->album_anchored_loudness.den;
971
975 break;
976 }
978 av_log(log_ctx, AV_LOG_ERROR, "Invalid Sound System value in a submix\n");
979 return AVERROR(EINVAL);
980 }
981 } else if (submix_layout->layout_type != AV_IAMF_SUBMIX_LAYOUT_TYPE_BINAURAL) {
982 av_log(log_ctx, AV_LOG_ERROR, "Unsupported Layout Type value in a submix\n");
983 return AVERROR(EINVAL);
984 }
985 init_put_bits(&pbc, header, sizeof(header));
986 put_bits(&pbc, 2, submix_layout->layout_type); // layout_type
988 put_bits(&pbc, 4, ff_iamf_sound_system_map[layout].id); // sound_system
989 put_bits(&pbc, 2, 0); // reserved
990 } else
991 put_bits(&pbc, 6, 0); // reserved
992 flush_put_bits(&pbc);
993 avio_write(dyn_bc, header, put_bytes_count(&pbc, 1));
994
995 info_type = (submix_layout->true_peak.num && submix_layout->true_peak.den);
996 info_type |= (dialogue || album) << 1;
997 avio_w8(dyn_bc, info_type);
998 avio_wb16(dyn_bc, rescale_rational(submix_layout->integrated_loudness, 1 << 8));
999 avio_wb16(dyn_bc, rescale_rational(submix_layout->digital_peak, 1 << 8));
1000 if (info_type & 1)
1001 avio_wb16(dyn_bc, rescale_rational(submix_layout->true_peak, 1 << 8));
1002 if (info_type & 2) {
1003 avio_w8(dyn_bc, dialogue + album); // num_anchored_loudness
1004 if (dialogue) {
1006 avio_wb16(dyn_bc, rescale_rational(submix_layout->dialogue_anchored_loudness, 1 << 8));
1007 }
1008 if (album) {
1010 avio_wb16(dyn_bc, rescale_rational(submix_layout->album_anchored_loudness, 1 << 8));
1011 }
1012 }
1013 }
1014 }
1015
1016 init_put_bits(&pbc, header, sizeof(header));
1018 put_bits(&pbc, 3, 0);
1019 flush_put_bits(&pbc);
1020
1021 dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
1022 avio_write(pb, header, put_bytes_count(&pbc, 1));
1023 ffio_write_leb(pb, dyn_size);
1024 avio_write(pb, dyn_buf, dyn_size);
1025 ffio_free_dyn_buf(&dyn_bc);
1026
1027 return 0;
1028}
1029
1030int ff_iamf_write_descriptors(const IAMFContext *iamf, AVIOContext *pb, void *log_ctx)
1031{
1032 int ret;
1033
1034 // Sequence Header
1036
1037 ffio_write_leb(pb, 6);
1038 avio_wb32(pb, MKBETAG('i','a','m','f'));
1039 avio_w8(pb, iamf->nb_audio_elements > 1); // primary_profile
1040 avio_w8(pb, iamf->nb_audio_elements > 1); // additional_profile
1041
1042 for (int i = 0; i < iamf->nb_codec_configs; i++) {
1043 ret = iamf_write_codec_config(iamf, iamf->codec_configs[i], pb);
1044 if (ret < 0)
1045 return ret;
1046 }
1047
1048 for (int i = 0; i < iamf->nb_audio_elements; i++) {
1049 ret = iamf_write_audio_element(iamf, iamf->audio_elements[i], pb, log_ctx);
1050 if (ret < 0)
1051 return ret;
1052 }
1053
1054 for (int i = 0; i < iamf->nb_mix_presentations; i++) {
1055 ret = iamf_write_mixing_presentation(iamf, iamf->mix_presentations[i], pb, log_ctx);
1056 if (ret < 0)
1057 return ret;
1058 }
1059
1060 return 0;
1061}
1062
1064 const AVIAMFParamDefinition *param, void *log_ctx)
1065{
1068 PutBitContext pbc;
1069 AVIOContext *dyn_bc;
1070 uint8_t *dyn_buf = NULL;
1071 int dyn_size, ret;
1072
1074 av_log(log_ctx, AV_LOG_DEBUG, "Ignoring side data with unknown type %u\n",
1075 param->type);
1076 return 0;
1077 }
1078
1079 if (!param_definition) {
1080 av_log(log_ctx, AV_LOG_ERROR, "Non-existent Parameter Definition with ID %u referenced by a packet\n",
1081 param->parameter_id);
1082 return AVERROR(EINVAL);
1083 }
1084
1085 if (param->type != param_definition->param->type) {
1086 av_log(log_ctx, AV_LOG_ERROR, "Inconsistent values for Parameter Definition "
1087 "with ID %u in a packet\n",
1088 param->parameter_id);
1089 return AVERROR(EINVAL);
1090 }
1091
1092 ret = avio_open_dyn_buf(&dyn_bc);
1093 if (ret < 0)
1094 return ret;
1095
1096 // Sequence Header
1097 init_put_bits(&pbc, header, sizeof(header));
1099 put_bits(&pbc, 3, 0);
1100 flush_put_bits(&pbc);
1101 avio_write(pb, header, put_bytes_count(&pbc, 1));
1102
1103 ffio_write_leb(dyn_bc, param->parameter_id);
1104 if (!param_definition->mode) {
1105 ffio_write_leb(dyn_bc, param->duration);
1107 if (param->constant_subblock_duration == 0)
1108 ffio_write_leb(dyn_bc, param->nb_subblocks);
1109 }
1110
1111 for (int i = 0; i < param->nb_subblocks; i++) {
1112 const void *subblock = av_iamf_param_definition_get_subblock(param, i);
1113
1114 switch (param->type) {
1116 const AVIAMFMixGain *mix = subblock;
1117 if (!param_definition->mode && param->constant_subblock_duration == 0)
1118 ffio_write_leb(dyn_bc, mix->subblock_duration);
1119
1120 ffio_write_leb(dyn_bc, mix->animation_type);
1121
1122 avio_wb16(dyn_bc, rescale_rational(mix->start_point_value, 1 << 8));
1123 if (mix->animation_type >= AV_IAMF_ANIMATION_TYPE_LINEAR)
1124 avio_wb16(dyn_bc, rescale_rational(mix->end_point_value, 1 << 8));
1125 if (mix->animation_type == AV_IAMF_ANIMATION_TYPE_BEZIER) {
1126 avio_wb16(dyn_bc, rescale_rational(mix->control_point_value, 1 << 8));
1127 avio_w8(dyn_bc, av_clip_uint8(av_rescale(mix->control_point_relative_time.num, 1 << 8,
1128 mix->control_point_relative_time.den)));
1129 }
1130 break;
1131 }
1133 const AVIAMFDemixingInfo *demix = subblock;
1134 if (!param_definition->mode && param->constant_subblock_duration == 0)
1135 ffio_write_leb(dyn_bc, demix->subblock_duration);
1136
1137 avio_w8(dyn_bc, demix->dmixp_mode << 5);
1138 break;
1139 }
1141 const AVIAMFReconGain *recon = subblock;
1142 const AVIAMFAudioElement *audio_element = param_definition->audio_element->celement;
1143
1144 if (!param_definition->mode && param->constant_subblock_duration == 0)
1145 ffio_write_leb(dyn_bc, recon->subblock_duration);
1146
1147 if (!audio_element) {
1148 av_log(log_ctx, AV_LOG_ERROR, "Invalid Parameter Definition with ID %u referenced by a packet\n", param->parameter_id);
1149 return AVERROR(EINVAL);
1150 }
1151
1152 for (int j = 0; j < audio_element->nb_layers; j++) {
1153 const AVIAMFLayer *layer = audio_element->layers[j];
1154
1155 if (layer->flags & AV_IAMF_LAYER_FLAG_RECON_GAIN) {
1156 unsigned int recon_gain_flags = 0;
1157 int k = 0;
1158
1159 for (; k < 7; k++)
1160 recon_gain_flags |= (1 << k) * !!recon->recon_gain[j][k];
1161 for (; k < 12; k++)
1162 recon_gain_flags |= (2 << k) * !!recon->recon_gain[j][k];
1163 if (recon_gain_flags >> 8)
1164 recon_gain_flags |= (1 << k);
1165
1166 ffio_write_leb(dyn_bc, recon_gain_flags);
1167 for (k = 0; k < 12; k++) {
1168 if (recon->recon_gain[j][k])
1169 avio_w8(dyn_bc, recon->recon_gain[j][k]);
1170 }
1171 }
1172 }
1173 break;
1174 }
1175 default:
1176 av_unreachable("param_definition_type should have been checked above");
1177 }
1178 }
1179
1180 dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
1181 ffio_write_leb(pb, dyn_size);
1182 avio_write(pb, dyn_buf, dyn_size);
1183 ffio_free_dyn_buf(&dyn_bc);
1184
1185 return 0;
1186}
1187
1189 const AVPacket *pkt, void *log_ctx)
1190{
1194 NULL);
1195 AVIAMFParamDefinition *demix =
1198 NULL);
1199 AVIAMFParamDefinition *recon =
1202 NULL);
1203
1204 if (mix) {
1205 int ret = write_parameter_block(iamf, pb, mix, log_ctx);
1206 if (ret < 0)
1207 return ret;
1208 }
1209 if (demix) {
1210 int ret = write_parameter_block(iamf, pb, demix, log_ctx);
1211 if (ret < 0)
1212 return ret;
1213 }
1214 if (recon) {
1215 int ret = write_parameter_block(iamf, pb, recon, log_ctx);
1216 if (ret < 0)
1217 return ret;
1218 }
1219
1220 return 0;
1221}
1222
1224 unsigned int audio_substream_id)
1225{
1226 for (int i = 0; i < c->nb_audio_elements; i++) {
1227 IAMFAudioElement *audio_element = c->audio_elements[i];
1228 for (int j = 0; j < audio_element->nb_substreams; j++) {
1229 IAMFSubStream *substream = &audio_element->substreams[j];
1230 if (substream->audio_substream_id == audio_substream_id)
1231 return audio_element;
1232 }
1233 }
1234
1235 return NULL;
1236}
1237
1239 unsigned audio_substream_id, const AVPacket *pkt)
1240{
1242 PutBitContext pbc;
1243 const IAMFAudioElement *audio_element;
1244 IAMFCodecConfig *codec_config;
1245 AVIOContext *dyn_bc;
1246 const uint8_t *side_data;
1247 uint8_t *dyn_buf = NULL;
1248 unsigned int skip_samples = 0, discard_padding = 0;
1249 size_t side_data_size;
1250 int dyn_size, type = audio_substream_id <= 17 ?
1252 int ret;
1253
1254 audio_element = get_audio_element(iamf, audio_substream_id);
1255 if (!audio_element)
1256 return AVERROR(EINVAL);
1257 codec_config = ff_iamf_get_codec_config(iamf, audio_element->codec_config_id);
1258 if (!codec_config)
1259 return AVERROR(EINVAL);
1260
1261 if (!pkt->size) {
1262 size_t new_extradata_size;
1263 const uint8_t *new_extradata = av_packet_get_side_data(pkt,
1265 &new_extradata_size);
1266
1267 if (!new_extradata || new_extradata_size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
1268 return AVERROR_INVALIDDATA;
1269
1270 av_free(codec_config->extradata);
1271 codec_config->extradata = av_malloc(new_extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
1272 if (!codec_config->extradata) {
1273 codec_config->extradata_size = 0;
1274 return AVERROR(ENOMEM);
1275 }
1276 memcpy(codec_config->extradata, new_extradata, new_extradata_size);
1277 memset(codec_config->extradata + new_extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1278 codec_config->extradata_size = new_extradata_size;
1279
1280 return update_extradata(codec_config);
1281 }
1282
1284 &side_data_size);
1285
1286 if (side_data && side_data_size >= 10) {
1287 skip_samples = AV_RL32(side_data);
1288 discard_padding = AV_RL32(side_data + 4);
1289 }
1290
1291 if (codec_config->codec_id == AV_CODEC_ID_OPUS) {
1292 // IAMF's num_samples_to_trim_at_start is the same as Opus's pre-skip.
1293 if (!skip_samples)
1294 skip_samples = pkt->dts < 0
1295 ? av_rescale(-pkt->dts, 48000, pkt->time_base.den)
1296 : 0;
1297 discard_padding = av_rescale(discard_padding, 48000, pkt->time_base.den);
1298 }
1299
1300 ret = avio_open_dyn_buf(&dyn_bc);
1301 if (ret < 0)
1302 return ret;
1303
1304 init_put_bits(&pbc, header, sizeof(header));
1305 put_bits(&pbc, 5, type);
1306 put_bits(&pbc, 1, 0); // obu_redundant_copy
1307 put_bits(&pbc, 1, skip_samples || discard_padding);
1308 put_bits(&pbc, 1, 0); // obu_extension_flag
1309 flush_put_bits(&pbc);
1310 avio_write(pb, header, put_bytes_count(&pbc, 1));
1311
1312 if (skip_samples || discard_padding) {
1313 ffio_write_leb(dyn_bc, discard_padding);
1314 ffio_write_leb(dyn_bc, skip_samples);
1315 }
1316
1317 if (audio_substream_id > 17)
1318 ffio_write_leb(dyn_bc, audio_substream_id);
1319
1320 dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
1321 ffio_write_leb(pb, dyn_size + pkt->size);
1322 avio_write(pb, dyn_buf, dyn_size);
1323 ffio_free_dyn_buf(&dyn_bc);
1324 avio_write(pb, pkt->data, pkt->size);
1325
1326 return 0;
1327}
#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_ENTRY_STREAM
Definition avformat.h:1172
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition avformat.h:1160
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition avformat.h:1159
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:1324
int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition aviobuf.c:1336
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition aviobuf.c:1397
void ffio_write_leb(AVIOContext *s, unsigned val)
Definition aviobuf.c:906
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition bprint.c:121
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition bprint.c:68
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:345
@ AV_CODEC_ID_PCM_S16LE
Definition codec_id.h:332
@ AV_CODEC_ID_PCM_S16BE
Definition codec_id.h:333
@ AV_CODEC_ID_PCM_S24LE
Definition codec_id.h:344
@ AV_CODEC_ID_PCM_S32LE
Definition codec_id.h:340
@ AV_CODEC_ID_AAC
Definition codec_id.h:459
@ AV_CODEC_ID_FLAC
Definition codec_id.h:469
@ AV_CODEC_ID_PCM_S32BE
Definition codec_id.h:341
@ AV_CODEC_ID_OPUS
Definition codec_id.h:517
#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:234
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:318
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
uint32_t type
Definition jpegmpfenc.c:80
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:370
Memory handling functions.
uint32_t tag
Definition movenc.c:2128
#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:587
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
enum AVStreamGroupEntryType type
Definition avformat.h:1177
AVStream * stream
Definition avformat.h:1179
unsigned int nb_entries
Number of elements in AVStreamGroup.entries.
Definition avformat.h:1285
enum AVStreamGroupParamsType type
Group type.
Definition avformat.h:1211
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition avformat.h:1218
AVStreamGroupEntry ** entries
A list of streams or child groups in the group.
Definition avformat.h:1298
unsigned int index
Group index in AVFormatContext.
Definition avformat.h:1195
union AVStreamGroup::@313244315204024013007202273061153315146016101155 params
Group type-specific parameters.
struct AVIAMFAudioElement * iamf_audio_element
Definition avformat.h:1217
int64_t id
Group type-specific group ID.
Definition avformat.h:1203
Stream structure.
Definition avformat.h:768
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:791
int id
Format-specific stream ID.
Definition avformat.h:780
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]