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