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 
23 #include "libavutil/intreadwrite.h"
24 #include "libavutil/iamf.h"
25 #include "libavutil/mem.h"
26 #include "libavcodec/get_bits.h"
27 #include "libavcodec/put_bits.h"
28 #include "avformat.h"
29 #include "avio_internal.h"
30 #include "iamf.h"
31 #include "iamf_writer.h"
32 
33 
34 static int update_extradata(IAMFCodecConfig *codec_config)
35 {
36  GetBitContext gb;
37  PutBitContext pb;
38  int ret;
39 
40  switch(codec_config->codec_id) {
41  case AV_CODEC_ID_OPUS:
42  if (codec_config->extradata_size < 19)
43  return AVERROR_INVALIDDATA;
44  codec_config->extradata_size -= 8;
45  memmove(codec_config->extradata, codec_config->extradata + 8, codec_config->extradata_size);
46  AV_WB8(codec_config->extradata + 1, 2); // set channels to stereo
47  break;
48  case AV_CODEC_ID_FLAC: {
49  uint8_t buf[13];
50 
51  init_put_bits(&pb, buf, sizeof(buf));
52  ret = init_get_bits8(&gb, codec_config->extradata, codec_config->extradata_size);
53  if (ret < 0)
54  return ret;
55 
56  put_bits32(&pb, get_bits_long(&gb, 32)); // min/max blocksize
57  put_bits64(&pb, 48, get_bits64(&gb, 48)); // min/max framesize
58  put_bits(&pb, 20, get_bits(&gb, 20)); // samplerate
59  skip_bits(&gb, 3);
60  put_bits(&pb, 3, 1); // set channels to stereo
61  ret = put_bits_left(&pb);
62  put_bits(&pb, ret, get_bits(&gb, ret));
63  flush_put_bits(&pb);
64 
65  memcpy(codec_config->extradata, buf, sizeof(buf));
66  break;
67  }
68  default:
69  break;
70  }
71 
72  return 0;
73 }
74 
75 static int fill_codec_config(IAMFContext *iamf, const AVStreamGroup *stg,
76  IAMFCodecConfig *codec_config)
77 {
78  const AVStream *st = stg->streams[0];
80  int j, ret = 0;
81 
82  codec_config->codec_id = st->codecpar->codec_id;
83  codec_config->sample_rate = st->codecpar->sample_rate;
84  codec_config->codec_tag = st->codecpar->codec_tag;
85  codec_config->nb_samples = st->codecpar->frame_size;
86  codec_config->seek_preroll = st->codecpar->seek_preroll;
87  if (st->codecpar->extradata_size) {
88  codec_config->extradata = av_memdup(st->codecpar->extradata, st->codecpar->extradata_size);
89  if (!codec_config->extradata)
90  return AVERROR(ENOMEM);
91  codec_config->extradata_size = st->codecpar->extradata_size;
92  ret = update_extradata(codec_config);
93  if (ret < 0)
94  goto fail;
95  }
96 
97  for (j = 0; j < iamf->nb_codec_configs; j++) {
98  if (!memcmp(iamf->codec_configs[j], codec_config, offsetof(IAMFCodecConfig, extradata)) &&
99  (!codec_config->extradata_size || !memcmp(iamf->codec_configs[j]->extradata,
100  codec_config->extradata, codec_config->extradata_size)))
101  break;
102  }
103 
104  if (j < iamf->nb_codec_configs) {
105  av_free(iamf->codec_configs[j]->extradata);
106  av_free(iamf->codec_configs[j]);
107  iamf->codec_configs[j] = codec_config;
108  return j;
109  }
110 
111  tmp = av_realloc_array(iamf->codec_configs, iamf->nb_codec_configs + 1, sizeof(*iamf->codec_configs));
112  if (!tmp) {
113  ret = AVERROR(ENOMEM);
114  goto fail;
115  }
116 
117  iamf->codec_configs = tmp;
118  iamf->codec_configs[iamf->nb_codec_configs] = codec_config;
119  codec_config->codec_config_id = iamf->nb_codec_configs;
120 
121  return iamf->nb_codec_configs++;
122 
123 fail:
124  av_freep(&codec_config->extradata);
125  return ret;
126 }
127 
129  const IAMFAudioElement *audio_element, void *log_ctx)
130 {
132  IAMFCodecConfig *codec_config = NULL;
133 
135  sizeof(*iamf->param_definitions));
136  if (!tmp)
137  return AVERROR(ENOMEM);
138 
139  iamf->param_definitions = tmp;
140 
141  if (audio_element)
142  codec_config = iamf->codec_configs[audio_element->codec_config_id];
143 
144  if (!param->parameter_rate) {
145  if (!codec_config) {
146  av_log(log_ctx, AV_LOG_ERROR, "parameter_rate needed but not set for parameter_id %u\n",
147  param->parameter_id);
148  return AVERROR(EINVAL);
149  }
150  param->parameter_rate = codec_config->sample_rate;
151  }
152  if (codec_config) {
153  if (!param->duration)
154  param->duration = codec_config->nb_samples;
155  if (!param->constant_subblock_duration)
156  param->constant_subblock_duration = codec_config->nb_samples;
157  }
158 
160  if (!param_definition)
161  return AVERROR(ENOMEM);
162 
163  param_definition->mode = !!param->duration;
164  param_definition->param = param;
165  param_definition->audio_element = audio_element;
167 
168  return 0;
169 }
170 
171 int ff_iamf_add_audio_element(IAMFContext *iamf, const AVStreamGroup *stg, void *log_ctx)
172 {
173  const AVIAMFAudioElement *iamf_audio_element;
174  IAMFAudioElement **tmp, *audio_element;
175  IAMFCodecConfig *codec_config;
176  int ret;
177 
179  return AVERROR(EINVAL);
180 
181  iamf_audio_element = stg->params.iamf_audio_element;
182  if (iamf_audio_element->audio_element_type == AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE) {
183  const AVIAMFLayer *layer = iamf_audio_element->layers[0];
184  if (iamf_audio_element->nb_layers != 1) {
185  av_log(log_ctx, AV_LOG_ERROR, "Invalid amount of layers for SCENE_BASED audio element. Must be 1\n");
186  return AVERROR(EINVAL);
187  }
188  if (layer->ch_layout.order != AV_CHANNEL_ORDER_CUSTOM &&
190  av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout for SCENE_BASED audio element\n");
191  return AVERROR(EINVAL);
192  }
194  av_log(log_ctx, AV_LOG_ERROR, "Unsuported ambisonics mode %d\n", layer->ambisonics_mode);
195  return AVERROR_PATCHWELCOME;
196  }
197  for (int i = 0; i < stg->nb_streams; i++) {
198  if (stg->streams[i]->codecpar->ch_layout.nb_channels > 1) {
199  av_log(log_ctx, AV_LOG_ERROR, "Invalid amount of channels in a stream for MONO mode ambisonics\n");
200  return AVERROR(EINVAL);
201  }
202  }
203  } else
204  for (int j, i = 0; i < iamf_audio_element->nb_layers; i++) {
205  const AVIAMFLayer *layer = iamf_audio_element->layers[i];
206  for (j = 0; j < FF_ARRAY_ELEMS(ff_iamf_scalable_ch_layouts); j++)
208  break;
209 
211  av_log(log_ctx, AV_LOG_ERROR, "Unsupported channel layout in stream group #%d\n", i);
212  return AVERROR(EINVAL);
213  }
214  }
215 
216  for (int i = 0; i < iamf->nb_audio_elements; i++) {
217  if (stg->id == iamf->audio_elements[i]->audio_element_id) {
218  av_log(log_ctx, AV_LOG_ERROR, "Duplicated Audio Element id %"PRId64"\n", stg->id);
219  return AVERROR(EINVAL);
220  }
221  }
222 
223  codec_config = av_mallocz(sizeof(*codec_config));
224  if (!codec_config)
225  return AVERROR(ENOMEM);
226 
227  ret = fill_codec_config(iamf, stg, codec_config);
228  if (ret < 0) {
229  av_free(codec_config);
230  return ret;
231  }
232 
233  audio_element = av_mallocz(sizeof(*audio_element));
234  if (!audio_element)
235  return AVERROR(ENOMEM);
236 
237  audio_element->celement = stg->params.iamf_audio_element;
238  audio_element->audio_element_id = stg->id;
239  audio_element->codec_config_id = ret;
240 
241  audio_element->substreams = av_calloc(stg->nb_streams, sizeof(*audio_element->substreams));
242  if (!audio_element->substreams) {
243  ret = AVERROR(ENOMEM);
244  goto fail;
245  }
246  audio_element->nb_substreams = stg->nb_streams;
247 
248  audio_element->layers = av_calloc(iamf_audio_element->nb_layers, sizeof(*audio_element->layers));
249  if (!audio_element->layers) {
250  ret = AVERROR(ENOMEM);
251  goto fail;
252  }
253 
254  for (int i = 0, j = 0; i < iamf_audio_element->nb_layers; i++) {
255  int nb_channels = iamf_audio_element->layers[i]->ch_layout.nb_channels;
256 
257  IAMFLayer *layer = &audio_element->layers[i];
258 
259  if (i)
260  nb_channels -= iamf_audio_element->layers[i - 1]->ch_layout.nb_channels;
261  for (; nb_channels > 0 && j < stg->nb_streams; j++) {
262  const AVStream *st = stg->streams[j];
263  IAMFSubStream *substream = &audio_element->substreams[j];
264 
265  substream->audio_substream_id = st->id;
266  layer->substream_count++;
268  nb_channels -= st->codecpar->ch_layout.nb_channels;
269  }
270  if (nb_channels) {
271  av_log(log_ctx, AV_LOG_ERROR, "Invalid channel count across substreams in layer %u from stream group %u\n",
272  i, stg->index);
273  ret = AVERROR(EINVAL);
274  goto fail;
275  }
276  }
277 
278  if (iamf_audio_element->demixing_info) {
279  AVIAMFParamDefinition *param = iamf_audio_element->demixing_info;
281 
282  if (param->nb_subblocks != 1) {
283  av_log(log_ctx, AV_LOG_ERROR, "nb_subblocks in demixing_info for stream group %u is not 1\n", stg->index);
284  ret = AVERROR(EINVAL);
285  goto fail;
286  }
287 
288  if (!param_definition) {
289  ret = add_param_definition(iamf, param, audio_element, log_ctx);
290  if (ret < 0)
291  goto fail;
292  }
293  }
294  if (iamf_audio_element->recon_gain_info) {
295  AVIAMFParamDefinition *param = iamf_audio_element->recon_gain_info;
297 
298  if (param->nb_subblocks != 1) {
299  av_log(log_ctx, AV_LOG_ERROR, "nb_subblocks in recon_gain_info for stream group %u is not 1\n", stg->index);
300  ret = AVERROR(EINVAL);
301  goto fail;
302  }
303 
304  if (!param_definition) {
305  ret = add_param_definition(iamf, param, audio_element, log_ctx);
306  if (ret < 0)
307  goto fail;
308  }
309  }
310 
311  tmp = av_realloc_array(iamf->audio_elements, iamf->nb_audio_elements + 1, sizeof(*iamf->audio_elements));
312  if (!tmp) {
313  ret = AVERROR(ENOMEM);
314  goto fail;
315  }
316 
317  iamf->audio_elements = tmp;
318  iamf->audio_elements[iamf->nb_audio_elements++] = audio_element;
319 
320  return 0;
321 fail:
322  ff_iamf_free_audio_element(&audio_element);
323  return ret;
324 }
325 
326 int ff_iamf_add_mix_presentation(IAMFContext *iamf, const AVStreamGroup *stg, void *log_ctx)
327 {
328  IAMFMixPresentation **tmp, *mix_presentation;
329  int ret;
330 
332  return AVERROR(EINVAL);
333 
334  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
335  if (stg->id == iamf->mix_presentations[i]->mix_presentation_id) {
336  av_log(log_ctx, AV_LOG_ERROR, "Duplicate Mix Presentation id %"PRId64"\n", stg->id);
337  return AVERROR(EINVAL);
338  }
339  }
340 
341  mix_presentation = av_mallocz(sizeof(*mix_presentation));
342  if (!mix_presentation)
343  return AVERROR(ENOMEM);
344 
345  mix_presentation->cmix = stg->params.iamf_mix_presentation;
346  mix_presentation->mix_presentation_id = stg->id;
347 
348  for (int i = 0; i < mix_presentation->cmix->nb_submixes; i++) {
349  const AVIAMFSubmix *submix = mix_presentation->cmix->submixes[i];
350  AVIAMFParamDefinition *param = submix->output_mix_config;
352 
353  if (!param) {
354  av_log(log_ctx, AV_LOG_ERROR, "output_mix_config is not present in submix %u from "
355  "Mix Presentation ID %"PRId64"\n", i, stg->id);
356  ret = AVERROR(EINVAL);
357  goto fail;
358  }
359 
361  if (!param_definition) {
362  ret = add_param_definition(iamf, param, NULL, log_ctx);
363  if (ret < 0)
364  goto fail;
365  }
366 
367  for (int j = 0; j < submix->nb_elements; j++) {
368  const AVIAMFSubmixElement *element = submix->elements[j];
369  param = element->element_mix_config;
370 
371  if (!param) {
372  av_log(log_ctx, AV_LOG_ERROR, "element_mix_config is not present for element %u in submix %u from "
373  "Mix Presentation ID %"PRId64"\n", j, i, stg->id);
374  ret = AVERROR(EINVAL);
375  goto fail;
376  }
378  if (!param_definition) {
379  ret = add_param_definition(iamf, param, NULL, log_ctx);
380  if (ret < 0)
381  goto fail;
382  }
383  }
384  }
385 
387  if (!tmp) {
388  ret = AVERROR(ENOMEM);
389  goto fail;
390  }
391 
392  iamf->mix_presentations = tmp;
393  iamf->mix_presentations[iamf->nb_mix_presentations++] = mix_presentation;
394 
395  return 0;
396 fail:
397  ff_iamf_free_mix_presentation(&mix_presentation);
398  return ret;
399 }
400 
401 static int iamf_write_codec_config(const IAMFContext *iamf,
402  const IAMFCodecConfig *codec_config,
403  AVIOContext *pb)
404 {
406  AVIOContext *dyn_bc;
407  uint8_t *dyn_buf = NULL;
408  PutBitContext pbc;
409  int dyn_size;
410 
411  int ret = avio_open_dyn_buf(&dyn_bc);
412  if (ret < 0)
413  return ret;
414 
415  ffio_write_leb(dyn_bc, codec_config->codec_config_id);
416  avio_wl32(dyn_bc, codec_config->codec_tag);
417 
418  ffio_write_leb(dyn_bc, codec_config->nb_samples);
419  avio_wb16(dyn_bc, codec_config->seek_preroll);
420 
421  switch(codec_config->codec_id) {
422  case AV_CODEC_ID_OPUS:
423  avio_write(dyn_bc, codec_config->extradata, codec_config->extradata_size);
424  break;
425  case AV_CODEC_ID_AAC:
426  return AVERROR_PATCHWELCOME;
427  case AV_CODEC_ID_FLAC:
428  avio_w8(dyn_bc, 0x80);
429  avio_wb24(dyn_bc, codec_config->extradata_size);
430  avio_write(dyn_bc, codec_config->extradata, codec_config->extradata_size);
431  break;
433  avio_w8(dyn_bc, 0);
434  avio_w8(dyn_bc, 16);
435  avio_wb32(dyn_bc, codec_config->sample_rate);
436  break;
438  avio_w8(dyn_bc, 0);
439  avio_w8(dyn_bc, 24);
440  avio_wb32(dyn_bc, codec_config->sample_rate);
441  break;
443  avio_w8(dyn_bc, 0);
444  avio_w8(dyn_bc, 32);
445  avio_wb32(dyn_bc, codec_config->sample_rate);
446  break;
448  avio_w8(dyn_bc, 1);
449  avio_w8(dyn_bc, 16);
450  avio_wb32(dyn_bc, codec_config->sample_rate);
451  break;
453  avio_w8(dyn_bc, 1);
454  avio_w8(dyn_bc, 24);
455  avio_wb32(dyn_bc, codec_config->sample_rate);
456  break;
458  avio_w8(dyn_bc, 1);
459  avio_w8(dyn_bc, 32);
460  avio_wb32(dyn_bc, codec_config->sample_rate);
461  break;
462  default:
463  break;
464  }
465 
466  init_put_bits(&pbc, header, sizeof(header));
468  put_bits(&pbc, 3, 0);
469  flush_put_bits(&pbc);
470 
471  dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
472  avio_write(pb, header, put_bytes_count(&pbc, 1));
473  ffio_write_leb(pb, dyn_size);
474  avio_write(pb, dyn_buf, dyn_size);
475  ffio_free_dyn_buf(&dyn_bc);
476 
477  return 0;
478 }
479 
480 static inline int rescale_rational(AVRational q, int b)
481 {
482  return av_clip_int16(av_rescale(q.num, b, q.den));
483 }
484 
485 static int scalable_channel_layout_config(const IAMFAudioElement *audio_element,
486  AVIOContext *dyn_bc)
487 {
488  const AVIAMFAudioElement *element = audio_element->celement;
490  PutBitContext pb;
491 
492  init_put_bits(&pb, header, sizeof(header));
493  put_bits(&pb, 3, element->nb_layers);
494  put_bits(&pb, 5, 0);
495  flush_put_bits(&pb);
496  avio_write(dyn_bc, header, put_bytes_count(&pb, 1));
497  for (int i = 0; i < element->nb_layers; i++) {
498  const AVIAMFLayer *layer = element->layers[i];
499  int layout;
502  break;
503  }
504  init_put_bits(&pb, header, sizeof(header));
505  put_bits(&pb, 4, layout);
506  put_bits(&pb, 1, !!layer->output_gain_flags);
507  put_bits(&pb, 1, !!(layer->flags & AV_IAMF_LAYER_FLAG_RECON_GAIN));
508  put_bits(&pb, 2, 0); // reserved
509  put_bits(&pb, 8, audio_element->layers[i].substream_count);
510  put_bits(&pb, 8, audio_element->layers[i].coupled_substream_count);
511  if (layer->output_gain_flags) {
512  put_bits(&pb, 6, layer->output_gain_flags);
513  put_bits(&pb, 2, 0);
514  put_bits(&pb, 16, rescale_rational(layer->output_gain, 1 << 8));
515  }
516  flush_put_bits(&pb);
517  avio_write(dyn_bc, header, put_bytes_count(&pb, 1));
518  }
519 
520  return 0;
521 }
522 
523 static int ambisonics_config(const IAMFAudioElement *audio_element,
524  AVIOContext *dyn_bc)
525 {
526  const AVIAMFAudioElement *element = audio_element->celement;
527  const AVIAMFLayer *layer = element->layers[0];
528 
529  ffio_write_leb(dyn_bc, 0); // ambisonics_mode
530  ffio_write_leb(dyn_bc, layer->ch_layout.nb_channels); // output_channel_count
531  ffio_write_leb(dyn_bc, audio_element->nb_substreams); // substream_count
532 
534  for (int i = 0; i < layer->ch_layout.nb_channels; i++)
535  avio_w8(dyn_bc, i);
536  else
537  for (int i = 0; i < layer->ch_layout.nb_channels; i++)
538  avio_w8(dyn_bc, layer->ch_layout.u.map[i].id);
539 
540  return 0;
541 }
542 
543 static int param_definition(const IAMFContext *iamf,
544  const IAMFParamDefinition *param_def,
545  AVIOContext *dyn_bc, void *log_ctx)
546 {
547  const AVIAMFParamDefinition *param = param_def->param;
548 
549  ffio_write_leb(dyn_bc, param->parameter_id);
550  ffio_write_leb(dyn_bc, param->parameter_rate);
551  avio_w8(dyn_bc, param->duration ? 0 : 1 << 7);
552  if (param->duration) {
553  ffio_write_leb(dyn_bc, param->duration);
555  if (param->constant_subblock_duration == 0) {
556  ffio_write_leb(dyn_bc, param->nb_subblocks);
557  for (int i = 0; i < param->nb_subblocks; i++) {
558  const void *subblock = av_iamf_param_definition_get_subblock(param, i);
559 
560  switch (param->type) {
562  const AVIAMFMixGain *mix = subblock;
563  ffio_write_leb(dyn_bc, mix->subblock_duration);
564  break;
565  }
567  const AVIAMFDemixingInfo *demix = subblock;
568  ffio_write_leb(dyn_bc, demix->subblock_duration);
569  break;
570  }
572  const AVIAMFReconGain *recon = subblock;
573  ffio_write_leb(dyn_bc, recon->subblock_duration);
574  break;
575  }
576  }
577  }
578  }
579  }
580 
581  return 0;
582 }
583 
584 static int iamf_write_audio_element(const IAMFContext *iamf,
585  const IAMFAudioElement *audio_element,
586  AVIOContext *pb, void *log_ctx)
587 {
588  const AVIAMFAudioElement *element = audio_element->celement;
589  const IAMFCodecConfig *codec_config = iamf->codec_configs[audio_element->codec_config_id];
591  AVIOContext *dyn_bc;
592  uint8_t *dyn_buf = NULL;
593  PutBitContext pbc;
594  int param_definition_types = AV_IAMF_PARAMETER_DEFINITION_DEMIXING, dyn_size;
595 
596  int ret = avio_open_dyn_buf(&dyn_bc);
597  if (ret < 0)
598  return ret;
599 
600  ffio_write_leb(dyn_bc, audio_element->audio_element_id);
601 
602  init_put_bits(&pbc, header, sizeof(header));
603  put_bits(&pbc, 3, element->audio_element_type);
604  put_bits(&pbc, 5, 0);
605  flush_put_bits(&pbc);
606  avio_write(dyn_bc, header, put_bytes_count(&pbc, 1));
607 
608  ffio_write_leb(dyn_bc, audio_element->codec_config_id);
609  ffio_write_leb(dyn_bc, audio_element->nb_substreams);
610 
611  for (int i = 0; i < audio_element->nb_substreams; i++)
612  ffio_write_leb(dyn_bc, audio_element->substreams[i].audio_substream_id);
613 
614  if (element->nb_layers == 1)
615  param_definition_types &= ~AV_IAMF_PARAMETER_DEFINITION_DEMIXING;
616  if (element->nb_layers > 1)
617  param_definition_types |= AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN;
618  if (codec_config->codec_tag == MKTAG('f','L','a','C') ||
619  codec_config->codec_tag == MKTAG('i','p','c','m'))
620  param_definition_types &= ~AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN;
621 
622  ffio_write_leb(dyn_bc, av_popcount(param_definition_types)); // num_parameters
623 
624  if (param_definition_types & 1) {
625  const AVIAMFParamDefinition *param = element->demixing_info;
626  const IAMFParamDefinition *param_def;
627  const AVIAMFDemixingInfo *demix;
628 
629  if (!param) {
630  av_log(log_ctx, AV_LOG_ERROR, "demixing_info needed but not set in Stream Group #%u\n",
631  audio_element->audio_element_id);
632  return AVERROR(EINVAL);
633  }
634 
635  demix = av_iamf_param_definition_get_subblock(param, 0);
637 
638  param_def = ff_iamf_get_param_definition(iamf, param->parameter_id);
639  ret = param_definition(iamf, param_def, dyn_bc, log_ctx);
640  if (ret < 0)
641  return ret;
642 
643  avio_w8(dyn_bc, demix->dmixp_mode << 5); // dmixp_mode
644  avio_w8(dyn_bc, element->default_w << 4); // default_w
645  }
646  if (param_definition_types & 2) {
647  const AVIAMFParamDefinition *param = element->recon_gain_info;
648  const IAMFParamDefinition *param_def;
649 
650  if (!param) {
651  av_log(log_ctx, AV_LOG_ERROR, "recon_gain_info needed but not set in Stream Group #%u\n",
652  audio_element->audio_element_id);
653  return AVERROR(EINVAL);
654  }
656 
657  param_def = ff_iamf_get_param_definition(iamf, param->parameter_id);
658  ret = param_definition(iamf, param_def, dyn_bc, log_ctx);
659  if (ret < 0)
660  return ret;
661  }
662 
664  ret = scalable_channel_layout_config(audio_element, dyn_bc);
665  if (ret < 0)
666  return ret;
667  } else {
668  ret = ambisonics_config(audio_element, dyn_bc);
669  if (ret < 0)
670  return ret;
671  }
672 
673  init_put_bits(&pbc, header, sizeof(header));
675  put_bits(&pbc, 3, 0);
676  flush_put_bits(&pbc);
677 
678  dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
679  avio_write(pb, header, put_bytes_count(&pbc, 1));
680  ffio_write_leb(pb, dyn_size);
681  avio_write(pb, dyn_buf, dyn_size);
682  ffio_free_dyn_buf(&dyn_bc);
683 
684  return 0;
685 }
686 
688  const IAMFMixPresentation *mix_presentation,
689  AVIOContext *pb, void *log_ctx)
690 {
692  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
693  const AVDictionaryEntry *tag = NULL;
694  PutBitContext pbc;
695  AVIOContext *dyn_bc;
696  uint8_t *dyn_buf = NULL;
697  int dyn_size;
698 
699  int ret = avio_open_dyn_buf(&dyn_bc);
700  if (ret < 0)
701  return ret;
702 
703  ffio_write_leb(dyn_bc, mix_presentation->mix_presentation_id); // mix_presentation_id
704  ffio_write_leb(dyn_bc, av_dict_count(mix->annotations)); // count_label
705 
706  while ((tag = av_dict_iterate(mix->annotations, tag)))
707  avio_put_str(dyn_bc, tag->key);
708  while ((tag = av_dict_iterate(mix->annotations, tag)))
709  avio_put_str(dyn_bc, tag->value);
710 
711  ffio_write_leb(dyn_bc, mix->nb_submixes);
712  for (int i = 0; i < mix->nb_submixes; i++) {
713  const AVIAMFSubmix *sub_mix = mix->submixes[i];
714  const IAMFParamDefinition *param_def;
715 
716  ffio_write_leb(dyn_bc, sub_mix->nb_elements);
717  for (int j = 0; j < sub_mix->nb_elements; j++) {
718  const IAMFAudioElement *audio_element = NULL;
719  const AVIAMFSubmixElement *submix_element = sub_mix->elements[j];
720 
721  for (int k = 0; k < iamf->nb_audio_elements; k++)
722  if (iamf->audio_elements[k]->audio_element_id == submix_element->audio_element_id) {
723  audio_element = iamf->audio_elements[k];
724  break;
725  }
726 
727  av_assert0(audio_element);
728  ffio_write_leb(dyn_bc, submix_element->audio_element_id);
729 
730  if (av_dict_count(submix_element->annotations) != av_dict_count(mix->annotations)) {
731  av_log(log_ctx, AV_LOG_ERROR, "Inconsistent amount of labels in submix %d from Mix Presentation id #%u\n",
732  j, audio_element->audio_element_id);
733  return AVERROR(EINVAL);
734  }
735  while ((tag = av_dict_iterate(submix_element->annotations, tag)))
736  avio_put_str(dyn_bc, tag->value);
737 
738  init_put_bits(&pbc, header, sizeof(header));
739  put_bits(&pbc, 2, submix_element->headphones_rendering_mode);
740  put_bits(&pbc, 6, 0); // reserved
741  flush_put_bits(&pbc);
742  avio_write(dyn_bc, header, put_bytes_count(&pbc, 1));
743  ffio_write_leb(dyn_bc, 0); // rendering_config_extension_size
744 
745  param_def = ff_iamf_get_param_definition(iamf, submix_element->element_mix_config->parameter_id);
746  ret = param_definition(iamf, param_def, dyn_bc, log_ctx);
747  if (ret < 0)
748  return ret;
749 
750  avio_wb16(dyn_bc, rescale_rational(submix_element->default_mix_gain, 1 << 8));
751  }
752 
753  param_def = ff_iamf_get_param_definition(iamf, sub_mix->output_mix_config->parameter_id);
754  ret = param_definition(iamf, param_def, dyn_bc, log_ctx);
755  if (ret < 0)
756  return ret;
757  avio_wb16(dyn_bc, rescale_rational(sub_mix->default_mix_gain, 1 << 8));
758 
759  ffio_write_leb(dyn_bc, sub_mix->nb_layouts); // nb_layouts
760  for (int i = 0; i < sub_mix->nb_layouts; i++) {
761  const AVIAMFSubmixLayout *submix_layout = sub_mix->layouts[i];
762  int layout, info_type;
763  int dialogue = submix_layout->dialogue_anchored_loudness.num &&
764  submix_layout->dialogue_anchored_loudness.den;
765  int album = submix_layout->album_anchored_loudness.num &&
766  submix_layout->album_anchored_loudness.den;
767 
771  break;
772  }
774  av_log(log_ctx, AV_LOG_ERROR, "Invalid Sound System value in a submix\n");
775  return AVERROR(EINVAL);
776  }
777  }
778  init_put_bits(&pbc, header, sizeof(header));
779  put_bits(&pbc, 2, submix_layout->layout_type); // layout_type
781  put_bits(&pbc, 4, ff_iamf_sound_system_map[layout].id); // sound_system
782  put_bits(&pbc, 2, 0); // reserved
783  } else
784  put_bits(&pbc, 6, 0); // reserved
785  flush_put_bits(&pbc);
786  avio_write(dyn_bc, header, put_bytes_count(&pbc, 1));
787 
788  info_type = (submix_layout->true_peak.num && submix_layout->true_peak.den);
789  info_type |= (dialogue || album) << 1;
790  avio_w8(dyn_bc, info_type);
791  avio_wb16(dyn_bc, rescale_rational(submix_layout->integrated_loudness, 1 << 8));
792  avio_wb16(dyn_bc, rescale_rational(submix_layout->digital_peak, 1 << 8));
793  if (info_type & 1)
794  avio_wb16(dyn_bc, rescale_rational(submix_layout->true_peak, 1 << 8));
795  if (info_type & 2) {
796  avio_w8(dyn_bc, dialogue + album); // num_anchored_loudness
797  if (dialogue) {
799  avio_wb16(dyn_bc, rescale_rational(submix_layout->dialogue_anchored_loudness, 1 << 8));
800  }
801  if (album) {
803  avio_wb16(dyn_bc, rescale_rational(submix_layout->album_anchored_loudness, 1 << 8));
804  }
805  }
806  }
807  }
808 
809  init_put_bits(&pbc, header, sizeof(header));
811  put_bits(&pbc, 3, 0);
812  flush_put_bits(&pbc);
813 
814  dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
815  avio_write(pb, header, put_bytes_count(&pbc, 1));
816  ffio_write_leb(pb, dyn_size);
817  avio_write(pb, dyn_buf, dyn_size);
818  ffio_free_dyn_buf(&dyn_bc);
819 
820  return 0;
821 }
822 
823 int ff_iamf_write_descriptors(const IAMFContext *iamf, AVIOContext *pb, void *log_ctx)
824 {
825  int ret;
826 
827  // Sequence Header
829 
830  ffio_write_leb(pb, 6);
831  avio_wb32(pb, MKBETAG('i','a','m','f'));
832  avio_w8(pb, iamf->nb_audio_elements > 1); // primary_profile
833  avio_w8(pb, iamf->nb_audio_elements > 1); // additional_profile
834 
835  for (int i = 0; i < iamf->nb_codec_configs; i++) {
836  ret = iamf_write_codec_config(iamf, iamf->codec_configs[i], pb);
837  if (ret < 0)
838  return ret;
839  }
840 
841  for (int i = 0; i < iamf->nb_audio_elements; i++) {
842  ret = iamf_write_audio_element(iamf, iamf->audio_elements[i], pb, log_ctx);
843  if (ret < 0)
844  return ret;
845  }
846 
847  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
848  ret = iamf_write_mixing_presentation(iamf, iamf->mix_presentations[i], pb, log_ctx);
849  if (ret < 0)
850  return ret;
851  }
852 
853  return 0;
854 }
855 
856 static int write_parameter_block(const IAMFContext *iamf, AVIOContext *pb,
857  const AVIAMFParamDefinition *param, void *log_ctx)
858 {
861  PutBitContext pbc;
862  AVIOContext *dyn_bc;
863  uint8_t *dyn_buf = NULL;
864  int dyn_size, ret;
865 
867  av_log(log_ctx, AV_LOG_DEBUG, "Ignoring side data with unknown type %u\n",
868  param->type);
869  return 0;
870  }
871 
872  if (!param_definition) {
873  av_log(log_ctx, AV_LOG_ERROR, "Non-existent Parameter Definition with ID %u referenced by a packet\n",
874  param->parameter_id);
875  return AVERROR(EINVAL);
876  }
877 
878  if (param->type != param_definition->param->type) {
879  av_log(log_ctx, AV_LOG_ERROR, "Inconsistent values for Parameter Definition "
880  "with ID %u in a packet\n",
881  param->parameter_id);
882  return AVERROR(EINVAL);
883  }
884 
885  ret = avio_open_dyn_buf(&dyn_bc);
886  if (ret < 0)
887  return ret;
888 
889  // Sequence Header
890  init_put_bits(&pbc, header, sizeof(header));
892  put_bits(&pbc, 3, 0);
893  flush_put_bits(&pbc);
894  avio_write(pb, header, put_bytes_count(&pbc, 1));
895 
896  ffio_write_leb(dyn_bc, param->parameter_id);
897  if (!param_definition->mode) {
898  ffio_write_leb(dyn_bc, param->duration);
900  if (param->constant_subblock_duration == 0)
901  ffio_write_leb(dyn_bc, param->nb_subblocks);
902  }
903 
904  for (int i = 0; i < param->nb_subblocks; i++) {
905  const void *subblock = av_iamf_param_definition_get_subblock(param, i);
906 
907  switch (param->type) {
909  const AVIAMFMixGain *mix = subblock;
910  if (!param_definition->mode && param->constant_subblock_duration == 0)
911  ffio_write_leb(dyn_bc, mix->subblock_duration);
912 
913  ffio_write_leb(dyn_bc, mix->animation_type);
914 
915  avio_wb16(dyn_bc, rescale_rational(mix->start_point_value, 1 << 8));
916  if (mix->animation_type >= AV_IAMF_ANIMATION_TYPE_LINEAR)
917  avio_wb16(dyn_bc, rescale_rational(mix->end_point_value, 1 << 8));
918  if (mix->animation_type == AV_IAMF_ANIMATION_TYPE_BEZIER) {
919  avio_wb16(dyn_bc, rescale_rational(mix->control_point_value, 1 << 8));
920  avio_w8(dyn_bc, av_clip_uint8(av_rescale(mix->control_point_relative_time.num, 1 << 8,
921  mix->control_point_relative_time.den)));
922  }
923  break;
924  }
926  const AVIAMFDemixingInfo *demix = subblock;
927  if (!param_definition->mode && param->constant_subblock_duration == 0)
928  ffio_write_leb(dyn_bc, demix->subblock_duration);
929 
930  avio_w8(dyn_bc, demix->dmixp_mode << 5);
931  break;
932  }
934  const AVIAMFReconGain *recon = subblock;
935  const AVIAMFAudioElement *audio_element = param_definition->audio_element->celement;
936 
937  if (!param_definition->mode && param->constant_subblock_duration == 0)
938  ffio_write_leb(dyn_bc, recon->subblock_duration);
939 
940  if (!audio_element) {
941  av_log(log_ctx, AV_LOG_ERROR, "Invalid Parameter Definition with ID %u referenced by a packet\n", param->parameter_id);
942  return AVERROR(EINVAL);
943  }
944 
945  for (int j = 0; j < audio_element->nb_layers; j++) {
946  const AVIAMFLayer *layer = audio_element->layers[j];
947 
948  if (layer->flags & AV_IAMF_LAYER_FLAG_RECON_GAIN) {
949  unsigned int recon_gain_flags = 0;
950  int k = 0;
951 
952  for (; k < 7; k++)
953  recon_gain_flags |= (1 << k) * !!recon->recon_gain[j][k];
954  for (; k < 12; k++)
955  recon_gain_flags |= (2 << k) * !!recon->recon_gain[j][k];
956  if (recon_gain_flags >> 8)
957  recon_gain_flags |= (1 << k);
958 
959  ffio_write_leb(dyn_bc, recon_gain_flags);
960  for (k = 0; k < 12; k++) {
961  if (recon->recon_gain[j][k])
962  avio_w8(dyn_bc, recon->recon_gain[j][k]);
963  }
964  }
965  }
966  break;
967  }
968  default:
969  av_assert0(0);
970  }
971  }
972 
973  dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
974  ffio_write_leb(pb, dyn_size);
975  avio_write(pb, dyn_buf, dyn_size);
976  ffio_free_dyn_buf(&dyn_bc);
977 
978  return 0;
979 }
980 
982  const AVPacket *pkt, void *log_ctx)
983 {
987  NULL);
988  AVIAMFParamDefinition *demix =
991  NULL);
992  AVIAMFParamDefinition *recon =
995  NULL);
996 
997  if (mix) {
998  int ret = write_parameter_block(iamf, pb, mix, log_ctx);
999  if (ret < 0)
1000  return ret;
1001  }
1002  if (demix) {
1003  int ret = write_parameter_block(iamf, pb, demix, log_ctx);
1004  if (ret < 0)
1005  return ret;
1006  }
1007  if (recon) {
1008  int ret = write_parameter_block(iamf, pb, recon, log_ctx);
1009  if (ret < 0)
1010  return ret;
1011  }
1012 
1013  return 0;
1014 }
1015 
1017  unsigned int audio_substream_id)
1018 {
1019  for (int i = 0; i < c->nb_audio_elements; i++) {
1020  IAMFAudioElement *audio_element = c->audio_elements[i];
1021  for (int j = 0; j < audio_element->nb_substreams; j++) {
1022  IAMFSubStream *substream = &audio_element->substreams[j];
1023  if (substream->audio_substream_id == audio_substream_id)
1024  return audio_element;
1025  }
1026  }
1027 
1028  return NULL;
1029 }
1030 
1032  unsigned audio_substream_id, const AVPacket *pkt)
1033 {
1035  PutBitContext pbc;
1036  AVIOContext *dyn_bc;
1037  const uint8_t *side_data;
1038  uint8_t *dyn_buf = NULL;
1039  unsigned int skip_samples = 0, discard_padding = 0;
1040  size_t side_data_size;
1041  int dyn_size, type = audio_substream_id <= 17 ?
1043  int ret;
1044 
1045  if (!pkt->size) {
1046  const IAMFAudioElement *audio_element;
1047  IAMFCodecConfig *codec_config;
1048  size_t new_extradata_size;
1049  const uint8_t *new_extradata = av_packet_get_side_data(pkt,
1051  &new_extradata_size);
1052 
1053  if (!new_extradata)
1054  return AVERROR_INVALIDDATA;
1055  audio_element = get_audio_element(iamf, audio_substream_id);
1056  if (!audio_element)
1057  return AVERROR(EINVAL);
1058  codec_config = ff_iamf_get_codec_config(iamf, audio_element->codec_config_id);
1059  if (!codec_config)
1060  return AVERROR(EINVAL);
1061 
1062  av_free(codec_config->extradata);
1063  codec_config->extradata = av_memdup(new_extradata, new_extradata_size);
1064  if (!codec_config->extradata) {
1065  codec_config->extradata_size = 0;
1066  return AVERROR(ENOMEM);
1067  }
1068  codec_config->extradata_size = new_extradata_size;
1069 
1070  return update_extradata(codec_config);
1071  }
1072 
1074  &side_data_size);
1075 
1076  if (side_data && side_data_size >= 10) {
1077  skip_samples = AV_RL32(side_data);
1078  discard_padding = AV_RL32(side_data + 4);
1079  }
1080 
1081  ret = avio_open_dyn_buf(&dyn_bc);
1082  if (ret < 0)
1083  return ret;
1084 
1085  init_put_bits(&pbc, header, sizeof(header));
1086  put_bits(&pbc, 5, type);
1087  put_bits(&pbc, 1, 0); // obu_redundant_copy
1088  put_bits(&pbc, 1, skip_samples || discard_padding);
1089  put_bits(&pbc, 1, 0); // obu_extension_flag
1090  flush_put_bits(&pbc);
1091  avio_write(pb, header, put_bytes_count(&pbc, 1));
1092 
1093  if (skip_samples || discard_padding) {
1094  ffio_write_leb(dyn_bc, discard_padding);
1095  ffio_write_leb(dyn_bc, skip_samples);
1096  }
1097 
1098  if (audio_substream_id > 17)
1099  ffio_write_leb(dyn_bc, audio_substream_id);
1100 
1101  dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
1102  ffio_write_leb(pb, dyn_size + pkt->size);
1103  avio_write(pb, dyn_buf, dyn_size);
1104  ffio_free_dyn_buf(&dyn_bc);
1105  avio_write(pb, pkt->data, pkt->size);
1106 
1107  return 0;
1108 }
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:328
iamf.h
ff_iamf_free_mix_presentation
void ff_iamf_free_mix_presentation(IAMFMixPresentation **pmix_presentation)
Definition: iamf.c:85
AVIAMFSubmix::elements
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition: iamf.h:552
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:488
AVIAMFAudioElement::nb_layers
unsigned int nb_layers
Number of layers, or channel groups, in the Audio Element.
Definition: iamf.h:359
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:69
AVStreamGroup::id
int64_t id
Group type-specific group ID.
Definition: avformat.h:1109
AVIAMFSubmix::layouts
AVIAMFSubmixLayout ** layouts
Array of submix layouts.
Definition: iamf.h:567
mix
static int mix(int c0, int c1)
Definition: 4xm.c:716
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
put_bits32
static void av_unused put_bits32(PutBitContext *s, uint32_t value)
Write exactly 32 bits into a bitstream.
Definition: put_bits.h:291
IAMF_OBU_IA_SEQUENCE_HEADER
@ IAMF_OBU_IA_SEQUENCE_HEADER
Definition: iamf.h:63
AVChannelLayout::u
union AVChannelLayout::@360 u
Details about which channels are present in this layout.
AVIAMFAudioElement::default_w
unsigned int default_w
Default weight value as defined in section 3.6 of IAMF.
Definition: iamf.h:384
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:350
av_dict_count
int av_dict_count(const AVDictionary *m)
Get number of entries in dictionary.
Definition: dict.c:39
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:421
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:354
AVIAMFMixPresentation::nb_submixes
unsigned int nb_submixes
Number of submixes in the presentation.
Definition: iamf.h:616
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
put_bits
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition: j2kenc.c:223
ff_iamf_sound_system_map
const struct IAMFSoundSystemMap ff_iamf_sound_system_map[13]
Definition: iamf.c:48
AVIAMFParamDefinition::type
enum AVIAMFParamDefinitionType type
Parameters type.
Definition: iamf.h:204
AVPacket::data
uint8_t * data
Definition: packet.h:524
put_bits64
static void put_bits64(PutBitContext *s, int n, uint64_t value)
Write up to 64 bits into a bitstream.
Definition: put_bits.h:334
AVCodecParameters::seek_preroll
int seek_preroll
Audio only.
Definition: codec_par.h:214
b
#define b
Definition: input.c:41
put_bytes_count
static int put_bytes_count(const PutBitContext *s, int round_up)
Definition: put_bits.h:100
AVIAMFSubmixLayout::layout_type
enum AVIAMFSubmixLayoutType layout_type
Definition: iamf.h:504
IAMFParamDefinition::param
AVIAMFParamDefinition * param
Definition: iamf.h:123
AVIAMFParamDefinition
Parameters as defined in section 3.6.1 of IAMF.
Definition: iamf.h:184
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:460
add_param_definition
static int add_param_definition(IAMFContext *iamf, AVIAMFParamDefinition *param, const IAMFAudioElement *audio_element, void *log_ctx)
Definition: iamf_writer.c:128
AV_CODEC_ID_FLAC
@ AV_CODEC_ID_FLAC
Definition: codec_id.h:452
AVChannelLayout::order
enum AVChannelOrder order
Channel order used in this layout.
Definition: channel_layout.h:308
av_popcount
#define av_popcount
Definition: common.h:153
ff_iamf_get_param_definition
static IAMFParamDefinition * ff_iamf_get_param_definition(const IAMFContext *iamf, unsigned int parameter_id)
Definition: iamf.h:183
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:313
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:1374
IAMFMixPresentation::cmix
const AVIAMFMixPresentation * cmix
Definition: iamf.h:108
av_memdup
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition: mem.c:304
write_parameter_block
static int write_parameter_block(const IAMFContext *iamf, AVIOContext *pb, const AVIAMFParamDefinition *param, void *log_ctx)
Definition: iamf_writer.c:856
AVIAMFSubmixLayout::digital_peak
AVRational digital_peak
The digital (sampled) peak value of the audio signal, as defined in ITU-1770-4.
Definition: iamf.h:522
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:381
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:335
fill_codec_config
static int fill_codec_config(IAMFContext *iamf, const AVStreamGroup *stg, IAMFCodecConfig *codec_config)
Definition: iamf_writer.c:75
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:324
AVIAMFSubmixLayout::integrated_loudness
AVRational integrated_loudness
The program integrated loudness information, as defined in ITU-1770-4.
Definition: iamf.h:517
IAMFCodecConfig::extradata
uint8_t * extradata
Definition: iamf.h:74
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:329
IAMFParamDefinition
Definition: iamf.h:121
fail
#define fail()
Definition: checkasm.h:179
IAMFCodecConfig::codec_tag
uint32_t codec_tag
Definition: iamf.h:69
GetBitContext
Definition: get_bits.h:108
AVIAMFSubmixLayout
Submix layout as defined in section 3.7.6 of IAMF.
Definition: iamf.h:501
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:125
AVStreamGroup::params
union AVStreamGroup::@305 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:379
AVIAMFReconGain
Recon Gain Info Parameter Data as defined in section 3.8.3 of IAMF.
Definition: iamf.h:139
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:172
rescale_rational
static int rescale_rational(AVRational q, int b)
Definition: iamf_writer.c:480
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:481
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
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:545
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:1362
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition: avformat.h:1083
AV_IAMF_ANIMATION_TYPE_BEZIER
@ AV_IAMF_ANIMATION_TYPE_BEZIER
Definition: iamf.h:60
update_extradata
static int update_extradata(IAMFCodecConfig *codec_config)
Definition: iamf_writer.c:34
ff_iamf_add_audio_element
int ff_iamf_add_audio_element(IAMFContext *iamf, const AVStreamGroup *stg, void *log_ctx)
Definition: iamf_writer.c:171
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:530
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:251
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
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:469
AVStreamGroup::index
unsigned int index
Group index in AVFormatContext.
Definition: avformat.h:1101
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
get_bits.h
AVIAMFLayer::ch_layout
AVChannelLayout ch_layout
Definition: iamf.h:288
ffio_write_leb
void ffio_write_leb(AVIOContext *s, unsigned val)
Definition: aviobuf.c:944
IAMFContext::nb_mix_presentations
int nb_mix_presentations
Definition: iamf.h:134
PutBitContext
Definition: put_bits.h:50
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:119
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:766
IAMFSoundSystemMap::layout
AVChannelLayout layout
Definition: iamf.h:163
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:148
av_clip_int16
#define av_clip_int16
Definition: common.h:114
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:222
get_audio_element
static IAMFAudioElement * get_audio_element(const IAMFContext *c, unsigned int audio_substream_id)
Definition: iamf_writer.c:1016
ff_iamf_get_codec_config
static IAMFCodecConfig * ff_iamf_get_codec_config(const IAMFContext *c, unsigned int codec_config_id)
Definition: iamf.h:170
AVIAMFLayer
A layer defining a Channel Layout in the Audio Element.
Definition: iamf.h:285
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:326
avio_w8
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:179
AV_IAMF_ANIMATION_TYPE_LINEAR
@ AV_IAMF_ANIMATION_TYPE_LINEAR
Definition: iamf.h:59
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:301
AVIAMFSubmixElement::audio_element_id
unsigned int audio_element_id
The id of the Audio Element this submix element references.
Definition: iamf.h:443
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:543
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:442
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:147
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:340
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:127
AVPacket::size
int size
Definition: packet.h:525
IAMFCodecConfig
Definition: iamf.h:66
IAMFCodecConfig::extradata_size
int extradata_size
Definition: iamf.h:73
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:981
AVStreamGroup::iamf_audio_element
struct AVIAMFAudioElement * iamf_audio_element
Definition: avformat.h:1123
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:687
AV_CODEC_ID_OPUS
@ AV_CODEC_ID_OPUS
Definition: codec_id.h:500
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:485
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:201
avio_wb32
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:365
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:401
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:229
AVIAMFAudioElement
Information on how to combine one or more audio streams, as defined in section 3.6 of IAMF.
Definition: iamf.h:347
avio_wl32
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:357
AVIAMFMixGain
Mix Gain Parameter Data as defined in section 3.8.1 of IAMF.
Definition: iamf.h:68
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition: avformat.h:1082
AVStreamGroup::streams
AVStream ** streams
A list of streams in the group.
Definition: avformat.h:1156
AVStreamGroup::iamf_mix_presentation
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition: avformat.h:1124
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:801
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:453
IAMFContext::param_definitions
IAMFParamDefinition ** param_definitions
Definition: iamf.h:135
IAMFContext::nb_audio_elements
int nb_audio_elements
Definition: iamf.h:132
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVIAMFParamDefinition::parameter_id
unsigned int parameter_id
Identifier for the paremeter substream.
Definition: iamf.h:209
avio_internal.h
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
IAMFCodecConfig::seek_preroll
int seek_preroll
Definition: iamf.h:71
AVIAMFMixPresentation
Information on how to render and mix one or more AVIAMFAudioElement to generate the final audio outpu...
Definition: iamf.h:600
param_definition
static int param_definition(const IAMFContext *iamf, const IAMFParamDefinition *param_def, AVIOContext *dyn_bc, void *log_ctx)
Definition: iamf_writer.c:543
IAMFContext::codec_configs
IAMFCodecConfig ** codec_configs
Definition: iamf.h:129
AV_CODEC_ID_PCM_S32BE
@ AV_CODEC_ID_PCM_S32BE
Definition: codec_id.h:337
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
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:199
AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
@ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE
Definition: iamf.h:337
AV_WB8
#define AV_WB8(p, d)
Definition: intreadwrite.h:394
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:1031
ff_iamf_write_descriptors
int ff_iamf_write_descriptors(const IAMFContext *iamf, AVIOContext *pb, void *log_ctx)
Definition: iamf_writer.c:823
AVIAMFSubmix::nb_layouts
unsigned int nb_layouts
Number of layouts in the submix.
Definition: iamf.h:574
ambisonics_config
static int ambisonics_config(const IAMFAudioElement *audio_element, AVIOContext *dyn_bc)
Definition: iamf_writer.c:523
tag
uint32_t tag
Definition: movenc.c:1787
ffio_free_dyn_buf
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition: aviobuf.c:1435
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:755
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:743
ff_iamf_free_audio_element
void ff_iamf_free_audio_element(IAMFAudioElement **paudio_element)
Definition: iamf.c:70
avformat.h
IAMF_OBU_IA_AUDIO_FRAME_ID0
@ IAMF_OBU_IA_AUDIO_FRAME_ID0
Definition: iamf.h:44
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
AVStreamGroup
Definition: avformat.h:1090
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:125
AVStreamGroup::nb_streams
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition: avformat.h:1143
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:590
AVIAMFSubmixLayout::album_anchored_loudness
AVRational album_anchored_loudness
The Album loudness information, as defined in ITU-1770-4.
Definition: iamf.h:534
AVIAMFSubmixLayout::true_peak
AVRational true_peak
The true peak of the audio signal, as defined in ITU-1770-4.
Definition: iamf.h:526
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 and 3....
Definition: iamf.h:512
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
Recommmends skipping the specified number of samples.
Definition: packet.h:157
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:164
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:105
AVIAMFSubmix::nb_elements
unsigned int nb_elements
Number of elements in the submix.
Definition: iamf.h:559
AV_CODEC_ID_PCM_S32LE
@ AV_CODEC_ID_PCM_S32LE
Definition: codec_id.h:336
AVIAMFAudioElement::demixing_info
AVIAMFParamDefinition * demixing_info
Demixing information used to reconstruct a scalable channel audio representation.
Definition: iamf.h:367
AVIAMFDemixingInfo::dmixp_mode
unsigned int dmixp_mode
Pre-defined combination of demixing parameters.
Definition: iamf.h:131
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:582
AVStreamGroup::type
enum AVStreamGroupParamsType type
Group type.
Definition: avformat.h:1117
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:319
flush_put_bits
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:143
avio_wb24
void avio_wb24(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:455
AVIAMFLayer::flags
unsigned int flags
A bitmask which may contain a combination of AV_IAMF_LAYER_FLAG_* flags.
Definition: iamf.h:293
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVDictionaryEntry
Definition: dict.h:89
AVIAMFLayer::output_gain
AVRational output_gain
Output gain as defined in section 3.6.2 of IAMF.
Definition: iamf.h:307
AV_IAMF_AMBISONICS_MODE_PROJECTION
@ AV_IAMF_AMBISONICS_MODE_PROJECTION
Definition: iamf.h:265
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:501
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
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:452
AVIAMFParamDefinition::parameter_rate
unsigned int parameter_rate
Sample rate for the paremeter substream.
Definition: iamf.h:213
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:437
avio_wb16
void avio_wb16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:443
AV_IAMF_AUDIO_ELEMENT_TYPE_CHANNEL
@ AV_IAMF_AUDIO_ELEMENT_TYPE_CHANNEL
Definition: iamf.h:336
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:374
avio_put_str
int avio_put_str(AVIOContext *s, const char *str)
Write a NULL-terminated string.
Definition: aviobuf.c:373
put_bits.h
AVIAMFMixPresentation::submixes
AVIAMFSubmix ** submixes
Array of submixes.
Definition: iamf.h:609
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:157
AV_CODEC_ID_PCM_S24BE
@ AV_CODEC_ID_PCM_S24BE
Definition: codec_id.h:341
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:308
AVChannelCustom::id
enum AVChannel id
Definition: channel_layout.h:268
av_dict_iterate
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition: dict.c:44
AV_IAMF_PARAMETER_DEFINITION_DEMIXING
@ AV_IAMF_PARAMETER_DEFINITION_DEMIXING
Subblocks are of struct type AVIAMFDemixingInfo.
Definition: iamf.h:168
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:584
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:316