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  for (int i = 0; i < audio_element->nb_substreams; i++) {
279  for (int j = i + 1; j < audio_element->nb_substreams; j++)
280  if (audio_element->substreams[i].audio_substream_id ==
281  audio_element->substreams[j].audio_substream_id) {
282  av_log(log_ctx, AV_LOG_ERROR, "Duplicate id %u in streams %u and %u from stream group %u\n",
283  audio_element->substreams[i].audio_substream_id, i, j, stg->index);
284  ret = AVERROR(EINVAL);
285  goto fail;
286  }
287  }
288 
289  if (iamf_audio_element->demixing_info) {
290  AVIAMFParamDefinition *param = iamf_audio_element->demixing_info;
292 
293  if (param->nb_subblocks != 1) {
294  av_log(log_ctx, AV_LOG_ERROR, "nb_subblocks in demixing_info for stream group %u is not 1\n", stg->index);
295  ret = AVERROR(EINVAL);
296  goto fail;
297  }
298 
299  if (!param_definition) {
300  ret = add_param_definition(iamf, param, audio_element, log_ctx);
301  if (ret < 0)
302  goto fail;
303  }
304  }
305  if (iamf_audio_element->recon_gain_info) {
306  AVIAMFParamDefinition *param = iamf_audio_element->recon_gain_info;
308 
309  if (param->nb_subblocks != 1) {
310  av_log(log_ctx, AV_LOG_ERROR, "nb_subblocks in recon_gain_info for stream group %u is not 1\n", stg->index);
311  ret = AVERROR(EINVAL);
312  goto fail;
313  }
314 
315  if (!param_definition) {
316  ret = add_param_definition(iamf, param, audio_element, log_ctx);
317  if (ret < 0)
318  goto fail;
319  }
320  }
321 
322  tmp = av_realloc_array(iamf->audio_elements, iamf->nb_audio_elements + 1, sizeof(*iamf->audio_elements));
323  if (!tmp) {
324  ret = AVERROR(ENOMEM);
325  goto fail;
326  }
327 
328  iamf->audio_elements = tmp;
329  iamf->audio_elements[iamf->nb_audio_elements++] = audio_element;
330 
331  return 0;
332 fail:
333  ff_iamf_free_audio_element(&audio_element);
334  return ret;
335 }
336 
337 int ff_iamf_add_mix_presentation(IAMFContext *iamf, const AVStreamGroup *stg, void *log_ctx)
338 {
339  IAMFMixPresentation **tmp, *mix_presentation;
340  int ret;
341 
343  return AVERROR(EINVAL);
344 
345  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
346  if (stg->id == iamf->mix_presentations[i]->mix_presentation_id) {
347  av_log(log_ctx, AV_LOG_ERROR, "Duplicate Mix Presentation id %"PRId64"\n", stg->id);
348  return AVERROR(EINVAL);
349  }
350  }
351 
352  mix_presentation = av_mallocz(sizeof(*mix_presentation));
353  if (!mix_presentation)
354  return AVERROR(ENOMEM);
355 
356  mix_presentation->cmix = stg->params.iamf_mix_presentation;
357  mix_presentation->mix_presentation_id = stg->id;
358 
359  for (int i = 0; i < mix_presentation->cmix->nb_submixes; i++) {
360  const AVIAMFSubmix *submix = mix_presentation->cmix->submixes[i];
361  AVIAMFParamDefinition *param = submix->output_mix_config;
363 
364  if (!param) {
365  av_log(log_ctx, AV_LOG_ERROR, "output_mix_config is not present in submix %u from "
366  "Mix Presentation ID %"PRId64"\n", i, stg->id);
367  ret = AVERROR(EINVAL);
368  goto fail;
369  }
370 
372  if (!param_definition) {
373  ret = add_param_definition(iamf, param, NULL, log_ctx);
374  if (ret < 0)
375  goto fail;
376  }
377 
378  for (int j = 0; j < submix->nb_elements; j++) {
379  const AVIAMFSubmixElement *element = submix->elements[j];
380  param = element->element_mix_config;
381 
382  if (!param) {
383  av_log(log_ctx, AV_LOG_ERROR, "element_mix_config is not present for element %u in submix %u from "
384  "Mix Presentation ID %"PRId64"\n", j, i, stg->id);
385  ret = AVERROR(EINVAL);
386  goto fail;
387  }
389  if (!param_definition) {
390  ret = add_param_definition(iamf, param, NULL, log_ctx);
391  if (ret < 0)
392  goto fail;
393  }
394  }
395  }
396 
398  if (!tmp) {
399  ret = AVERROR(ENOMEM);
400  goto fail;
401  }
402 
403  iamf->mix_presentations = tmp;
404  iamf->mix_presentations[iamf->nb_mix_presentations++] = mix_presentation;
405 
406  return 0;
407 fail:
408  ff_iamf_free_mix_presentation(&mix_presentation);
409  return ret;
410 }
411 
412 static int iamf_write_codec_config(const IAMFContext *iamf,
413  const IAMFCodecConfig *codec_config,
414  AVIOContext *pb)
415 {
417  AVIOContext *dyn_bc;
418  uint8_t *dyn_buf = NULL;
419  PutBitContext pbc;
420  int dyn_size;
421 
422  int ret = avio_open_dyn_buf(&dyn_bc);
423  if (ret < 0)
424  return ret;
425 
426  ffio_write_leb(dyn_bc, codec_config->codec_config_id);
427  avio_wl32(dyn_bc, codec_config->codec_tag);
428 
429  ffio_write_leb(dyn_bc, codec_config->nb_samples);
430  avio_wb16(dyn_bc, codec_config->seek_preroll);
431 
432  switch(codec_config->codec_id) {
433  case AV_CODEC_ID_OPUS:
434  avio_write(dyn_bc, codec_config->extradata, codec_config->extradata_size);
435  break;
436  case AV_CODEC_ID_AAC:
437  return AVERROR_PATCHWELCOME;
438  case AV_CODEC_ID_FLAC:
439  avio_w8(dyn_bc, 0x80);
440  avio_wb24(dyn_bc, codec_config->extradata_size);
441  avio_write(dyn_bc, codec_config->extradata, codec_config->extradata_size);
442  break;
444  avio_w8(dyn_bc, 0);
445  avio_w8(dyn_bc, 16);
446  avio_wb32(dyn_bc, codec_config->sample_rate);
447  break;
449  avio_w8(dyn_bc, 0);
450  avio_w8(dyn_bc, 24);
451  avio_wb32(dyn_bc, codec_config->sample_rate);
452  break;
454  avio_w8(dyn_bc, 0);
455  avio_w8(dyn_bc, 32);
456  avio_wb32(dyn_bc, codec_config->sample_rate);
457  break;
459  avio_w8(dyn_bc, 1);
460  avio_w8(dyn_bc, 16);
461  avio_wb32(dyn_bc, codec_config->sample_rate);
462  break;
464  avio_w8(dyn_bc, 1);
465  avio_w8(dyn_bc, 24);
466  avio_wb32(dyn_bc, codec_config->sample_rate);
467  break;
469  avio_w8(dyn_bc, 1);
470  avio_w8(dyn_bc, 32);
471  avio_wb32(dyn_bc, codec_config->sample_rate);
472  break;
473  default:
474  break;
475  }
476 
477  init_put_bits(&pbc, header, sizeof(header));
479  put_bits(&pbc, 3, 0);
480  flush_put_bits(&pbc);
481 
482  dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
483  avio_write(pb, header, put_bytes_count(&pbc, 1));
484  ffio_write_leb(pb, dyn_size);
485  avio_write(pb, dyn_buf, dyn_size);
486  ffio_free_dyn_buf(&dyn_bc);
487 
488  return 0;
489 }
490 
491 static inline int rescale_rational(AVRational q, int b)
492 {
493  return av_clip_int16(av_rescale(q.num, b, q.den));
494 }
495 
496 static int scalable_channel_layout_config(const IAMFAudioElement *audio_element,
497  AVIOContext *dyn_bc)
498 {
499  const AVIAMFAudioElement *element = audio_element->celement;
501  PutBitContext pb;
502 
503  init_put_bits(&pb, header, sizeof(header));
504  put_bits(&pb, 3, element->nb_layers);
505  put_bits(&pb, 5, 0);
506  flush_put_bits(&pb);
507  avio_write(dyn_bc, header, put_bytes_count(&pb, 1));
508  for (int i = 0; i < element->nb_layers; i++) {
509  const AVIAMFLayer *layer = element->layers[i];
510  int layout;
513  break;
514  }
515  init_put_bits(&pb, header, sizeof(header));
516  put_bits(&pb, 4, layout);
517  put_bits(&pb, 1, !!layer->output_gain_flags);
518  put_bits(&pb, 1, !!(layer->flags & AV_IAMF_LAYER_FLAG_RECON_GAIN));
519  put_bits(&pb, 2, 0); // reserved
520  put_bits(&pb, 8, audio_element->layers[i].substream_count);
521  put_bits(&pb, 8, audio_element->layers[i].coupled_substream_count);
522  if (layer->output_gain_flags) {
523  put_bits(&pb, 6, layer->output_gain_flags);
524  put_bits(&pb, 2, 0);
525  put_bits(&pb, 16, rescale_rational(layer->output_gain, 1 << 8));
526  }
527  flush_put_bits(&pb);
528  avio_write(dyn_bc, header, put_bytes_count(&pb, 1));
529  }
530 
531  return 0;
532 }
533 
534 static int ambisonics_config(const IAMFAudioElement *audio_element,
535  AVIOContext *dyn_bc)
536 {
537  const AVIAMFAudioElement *element = audio_element->celement;
538  const AVIAMFLayer *layer = element->layers[0];
539 
540  ffio_write_leb(dyn_bc, 0); // ambisonics_mode
541  ffio_write_leb(dyn_bc, layer->ch_layout.nb_channels); // output_channel_count
542  ffio_write_leb(dyn_bc, audio_element->nb_substreams); // substream_count
543 
545  for (int i = 0; i < layer->ch_layout.nb_channels; i++)
546  avio_w8(dyn_bc, i);
547  else
548  for (int i = 0; i < layer->ch_layout.nb_channels; i++)
549  avio_w8(dyn_bc, layer->ch_layout.u.map[i].id);
550 
551  return 0;
552 }
553 
554 static int param_definition(const IAMFContext *iamf,
555  const IAMFParamDefinition *param_def,
556  AVIOContext *dyn_bc, void *log_ctx)
557 {
558  const AVIAMFParamDefinition *param = param_def->param;
559 
560  ffio_write_leb(dyn_bc, param->parameter_id);
561  ffio_write_leb(dyn_bc, param->parameter_rate);
562  avio_w8(dyn_bc, param->duration ? 0 : 1 << 7);
563  if (param->duration) {
564  ffio_write_leb(dyn_bc, param->duration);
566  if (param->constant_subblock_duration == 0) {
567  ffio_write_leb(dyn_bc, param->nb_subblocks);
568  for (int i = 0; i < param->nb_subblocks; i++) {
569  const void *subblock = av_iamf_param_definition_get_subblock(param, i);
570 
571  switch (param->type) {
573  const AVIAMFMixGain *mix = subblock;
574  ffio_write_leb(dyn_bc, mix->subblock_duration);
575  break;
576  }
578  const AVIAMFDemixingInfo *demix = subblock;
579  ffio_write_leb(dyn_bc, demix->subblock_duration);
580  break;
581  }
583  const AVIAMFReconGain *recon = subblock;
584  ffio_write_leb(dyn_bc, recon->subblock_duration);
585  break;
586  }
587  }
588  }
589  }
590  }
591 
592  return 0;
593 }
594 
595 static int iamf_write_audio_element(const IAMFContext *iamf,
596  const IAMFAudioElement *audio_element,
597  AVIOContext *pb, void *log_ctx)
598 {
599  const AVIAMFAudioElement *element = audio_element->celement;
600  const IAMFCodecConfig *codec_config = iamf->codec_configs[audio_element->codec_config_id];
602  AVIOContext *dyn_bc;
603  uint8_t *dyn_buf = NULL;
604  PutBitContext pbc;
605  int param_definition_types = AV_IAMF_PARAMETER_DEFINITION_DEMIXING, dyn_size;
606 
607  int ret = avio_open_dyn_buf(&dyn_bc);
608  if (ret < 0)
609  return ret;
610 
611  ffio_write_leb(dyn_bc, audio_element->audio_element_id);
612 
613  init_put_bits(&pbc, header, sizeof(header));
614  put_bits(&pbc, 3, element->audio_element_type);
615  put_bits(&pbc, 5, 0);
616  flush_put_bits(&pbc);
617  avio_write(dyn_bc, header, put_bytes_count(&pbc, 1));
618 
619  ffio_write_leb(dyn_bc, audio_element->codec_config_id);
620  ffio_write_leb(dyn_bc, audio_element->nb_substreams);
621 
622  for (int i = 0; i < audio_element->nb_substreams; i++)
623  ffio_write_leb(dyn_bc, audio_element->substreams[i].audio_substream_id);
624 
625  if (element->nb_layers == 1)
626  param_definition_types &= ~AV_IAMF_PARAMETER_DEFINITION_DEMIXING;
627  if (element->nb_layers > 1)
628  param_definition_types |= AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN;
629  if (codec_config->codec_tag == MKTAG('f','L','a','C') ||
630  codec_config->codec_tag == MKTAG('i','p','c','m'))
631  param_definition_types &= ~AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN;
632 
633  ffio_write_leb(dyn_bc, av_popcount(param_definition_types)); // num_parameters
634 
635  if (param_definition_types & 1) {
636  const AVIAMFParamDefinition *param = element->demixing_info;
637  const IAMFParamDefinition *param_def;
638  const AVIAMFDemixingInfo *demix;
639 
640  if (!param) {
641  av_log(log_ctx, AV_LOG_ERROR, "demixing_info needed but not set in Stream Group #%u\n",
642  audio_element->audio_element_id);
643  return AVERROR(EINVAL);
644  }
645 
646  demix = av_iamf_param_definition_get_subblock(param, 0);
648 
649  param_def = ff_iamf_get_param_definition(iamf, param->parameter_id);
650  ret = param_definition(iamf, param_def, dyn_bc, log_ctx);
651  if (ret < 0)
652  return ret;
653 
654  avio_w8(dyn_bc, demix->dmixp_mode << 5); // dmixp_mode
655  avio_w8(dyn_bc, element->default_w << 4); // default_w
656  }
657  if (param_definition_types & 2) {
658  const AVIAMFParamDefinition *param = element->recon_gain_info;
659  const IAMFParamDefinition *param_def;
660 
661  if (!param) {
662  av_log(log_ctx, AV_LOG_ERROR, "recon_gain_info needed but not set in Stream Group #%u\n",
663  audio_element->audio_element_id);
664  return AVERROR(EINVAL);
665  }
667 
668  param_def = ff_iamf_get_param_definition(iamf, param->parameter_id);
669  ret = param_definition(iamf, param_def, dyn_bc, log_ctx);
670  if (ret < 0)
671  return ret;
672  }
673 
675  ret = scalable_channel_layout_config(audio_element, dyn_bc);
676  if (ret < 0)
677  return ret;
678  } else {
679  ret = ambisonics_config(audio_element, dyn_bc);
680  if (ret < 0)
681  return ret;
682  }
683 
684  init_put_bits(&pbc, header, sizeof(header));
686  put_bits(&pbc, 3, 0);
687  flush_put_bits(&pbc);
688 
689  dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
690  avio_write(pb, header, put_bytes_count(&pbc, 1));
691  ffio_write_leb(pb, dyn_size);
692  avio_write(pb, dyn_buf, dyn_size);
693  ffio_free_dyn_buf(&dyn_bc);
694 
695  return 0;
696 }
697 
699  const IAMFMixPresentation *mix_presentation,
700  AVIOContext *pb, void *log_ctx)
701 {
703  const AVIAMFMixPresentation *mix = mix_presentation->cmix;
704  const AVDictionaryEntry *tag = NULL;
705  PutBitContext pbc;
706  AVIOContext *dyn_bc;
707  uint8_t *dyn_buf = NULL;
708  int dyn_size;
709 
710  int ret = avio_open_dyn_buf(&dyn_bc);
711  if (ret < 0)
712  return ret;
713 
714  ffio_write_leb(dyn_bc, mix_presentation->mix_presentation_id); // mix_presentation_id
715  ffio_write_leb(dyn_bc, av_dict_count(mix->annotations)); // count_label
716 
717  while ((tag = av_dict_iterate(mix->annotations, tag)))
718  avio_put_str(dyn_bc, tag->key);
719  while ((tag = av_dict_iterate(mix->annotations, tag)))
720  avio_put_str(dyn_bc, tag->value);
721 
722  ffio_write_leb(dyn_bc, mix->nb_submixes);
723  for (int i = 0; i < mix->nb_submixes; i++) {
724  const AVIAMFSubmix *sub_mix = mix->submixes[i];
725  const IAMFParamDefinition *param_def;
726 
727  ffio_write_leb(dyn_bc, sub_mix->nb_elements);
728  for (int j = 0; j < sub_mix->nb_elements; j++) {
729  const IAMFAudioElement *audio_element = NULL;
730  const AVIAMFSubmixElement *submix_element = sub_mix->elements[j];
731 
732  for (int k = 0; k < iamf->nb_audio_elements; k++)
733  if (iamf->audio_elements[k]->audio_element_id == submix_element->audio_element_id) {
734  audio_element = iamf->audio_elements[k];
735  break;
736  }
737 
738  av_assert0(audio_element);
739  ffio_write_leb(dyn_bc, submix_element->audio_element_id);
740 
741  if (av_dict_count(submix_element->annotations) != av_dict_count(mix->annotations)) {
742  av_log(log_ctx, AV_LOG_ERROR, "Inconsistent amount of labels in submix %d from Mix Presentation id #%u\n",
743  j, audio_element->audio_element_id);
744  return AVERROR(EINVAL);
745  }
746  while ((tag = av_dict_iterate(submix_element->annotations, tag)))
747  avio_put_str(dyn_bc, tag->value);
748 
749  init_put_bits(&pbc, header, sizeof(header));
750  put_bits(&pbc, 2, submix_element->headphones_rendering_mode);
751  put_bits(&pbc, 6, 0); // reserved
752  flush_put_bits(&pbc);
753  avio_write(dyn_bc, header, put_bytes_count(&pbc, 1));
754  ffio_write_leb(dyn_bc, 0); // rendering_config_extension_size
755 
756  param_def = ff_iamf_get_param_definition(iamf, submix_element->element_mix_config->parameter_id);
757  ret = param_definition(iamf, param_def, dyn_bc, log_ctx);
758  if (ret < 0)
759  return ret;
760 
761  avio_wb16(dyn_bc, rescale_rational(submix_element->default_mix_gain, 1 << 8));
762  }
763 
764  param_def = ff_iamf_get_param_definition(iamf, sub_mix->output_mix_config->parameter_id);
765  ret = param_definition(iamf, param_def, dyn_bc, log_ctx);
766  if (ret < 0)
767  return ret;
768  avio_wb16(dyn_bc, rescale_rational(sub_mix->default_mix_gain, 1 << 8));
769 
770  ffio_write_leb(dyn_bc, sub_mix->nb_layouts); // nb_layouts
771  for (int i = 0; i < sub_mix->nb_layouts; i++) {
772  const AVIAMFSubmixLayout *submix_layout = sub_mix->layouts[i];
773  int layout, info_type;
774  int dialogue = submix_layout->dialogue_anchored_loudness.num &&
775  submix_layout->dialogue_anchored_loudness.den;
776  int album = submix_layout->album_anchored_loudness.num &&
777  submix_layout->album_anchored_loudness.den;
778 
782  break;
783  }
785  av_log(log_ctx, AV_LOG_ERROR, "Invalid Sound System value in a submix\n");
786  return AVERROR(EINVAL);
787  }
788  }
789  init_put_bits(&pbc, header, sizeof(header));
790  put_bits(&pbc, 2, submix_layout->layout_type); // layout_type
792  put_bits(&pbc, 4, ff_iamf_sound_system_map[layout].id); // sound_system
793  put_bits(&pbc, 2, 0); // reserved
794  } else
795  put_bits(&pbc, 6, 0); // reserved
796  flush_put_bits(&pbc);
797  avio_write(dyn_bc, header, put_bytes_count(&pbc, 1));
798 
799  info_type = (submix_layout->true_peak.num && submix_layout->true_peak.den);
800  info_type |= (dialogue || album) << 1;
801  avio_w8(dyn_bc, info_type);
802  avio_wb16(dyn_bc, rescale_rational(submix_layout->integrated_loudness, 1 << 8));
803  avio_wb16(dyn_bc, rescale_rational(submix_layout->digital_peak, 1 << 8));
804  if (info_type & 1)
805  avio_wb16(dyn_bc, rescale_rational(submix_layout->true_peak, 1 << 8));
806  if (info_type & 2) {
807  avio_w8(dyn_bc, dialogue + album); // num_anchored_loudness
808  if (dialogue) {
810  avio_wb16(dyn_bc, rescale_rational(submix_layout->dialogue_anchored_loudness, 1 << 8));
811  }
812  if (album) {
814  avio_wb16(dyn_bc, rescale_rational(submix_layout->album_anchored_loudness, 1 << 8));
815  }
816  }
817  }
818  }
819 
820  init_put_bits(&pbc, header, sizeof(header));
822  put_bits(&pbc, 3, 0);
823  flush_put_bits(&pbc);
824 
825  dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
826  avio_write(pb, header, put_bytes_count(&pbc, 1));
827  ffio_write_leb(pb, dyn_size);
828  avio_write(pb, dyn_buf, dyn_size);
829  ffio_free_dyn_buf(&dyn_bc);
830 
831  return 0;
832 }
833 
834 int ff_iamf_write_descriptors(const IAMFContext *iamf, AVIOContext *pb, void *log_ctx)
835 {
836  int ret;
837 
838  // Sequence Header
840 
841  ffio_write_leb(pb, 6);
842  avio_wb32(pb, MKBETAG('i','a','m','f'));
843  avio_w8(pb, iamf->nb_audio_elements > 1); // primary_profile
844  avio_w8(pb, iamf->nb_audio_elements > 1); // additional_profile
845 
846  for (int i = 0; i < iamf->nb_codec_configs; i++) {
847  ret = iamf_write_codec_config(iamf, iamf->codec_configs[i], pb);
848  if (ret < 0)
849  return ret;
850  }
851 
852  for (int i = 0; i < iamf->nb_audio_elements; i++) {
853  ret = iamf_write_audio_element(iamf, iamf->audio_elements[i], pb, log_ctx);
854  if (ret < 0)
855  return ret;
856  }
857 
858  for (int i = 0; i < iamf->nb_mix_presentations; i++) {
859  ret = iamf_write_mixing_presentation(iamf, iamf->mix_presentations[i], pb, log_ctx);
860  if (ret < 0)
861  return ret;
862  }
863 
864  return 0;
865 }
866 
867 static int write_parameter_block(const IAMFContext *iamf, AVIOContext *pb,
868  const AVIAMFParamDefinition *param, void *log_ctx)
869 {
872  PutBitContext pbc;
873  AVIOContext *dyn_bc;
874  uint8_t *dyn_buf = NULL;
875  int dyn_size, ret;
876 
878  av_log(log_ctx, AV_LOG_DEBUG, "Ignoring side data with unknown type %u\n",
879  param->type);
880  return 0;
881  }
882 
883  if (!param_definition) {
884  av_log(log_ctx, AV_LOG_ERROR, "Non-existent Parameter Definition with ID %u referenced by a packet\n",
885  param->parameter_id);
886  return AVERROR(EINVAL);
887  }
888 
889  if (param->type != param_definition->param->type) {
890  av_log(log_ctx, AV_LOG_ERROR, "Inconsistent values for Parameter Definition "
891  "with ID %u in a packet\n",
892  param->parameter_id);
893  return AVERROR(EINVAL);
894  }
895 
896  ret = avio_open_dyn_buf(&dyn_bc);
897  if (ret < 0)
898  return ret;
899 
900  // Sequence Header
901  init_put_bits(&pbc, header, sizeof(header));
903  put_bits(&pbc, 3, 0);
904  flush_put_bits(&pbc);
905  avio_write(pb, header, put_bytes_count(&pbc, 1));
906 
907  ffio_write_leb(dyn_bc, param->parameter_id);
908  if (!param_definition->mode) {
909  ffio_write_leb(dyn_bc, param->duration);
911  if (param->constant_subblock_duration == 0)
912  ffio_write_leb(dyn_bc, param->nb_subblocks);
913  }
914 
915  for (int i = 0; i < param->nb_subblocks; i++) {
916  const void *subblock = av_iamf_param_definition_get_subblock(param, i);
917 
918  switch (param->type) {
920  const AVIAMFMixGain *mix = subblock;
921  if (!param_definition->mode && param->constant_subblock_duration == 0)
922  ffio_write_leb(dyn_bc, mix->subblock_duration);
923 
924  ffio_write_leb(dyn_bc, mix->animation_type);
925 
926  avio_wb16(dyn_bc, rescale_rational(mix->start_point_value, 1 << 8));
927  if (mix->animation_type >= AV_IAMF_ANIMATION_TYPE_LINEAR)
928  avio_wb16(dyn_bc, rescale_rational(mix->end_point_value, 1 << 8));
929  if (mix->animation_type == AV_IAMF_ANIMATION_TYPE_BEZIER) {
930  avio_wb16(dyn_bc, rescale_rational(mix->control_point_value, 1 << 8));
931  avio_w8(dyn_bc, av_clip_uint8(av_rescale(mix->control_point_relative_time.num, 1 << 8,
932  mix->control_point_relative_time.den)));
933  }
934  break;
935  }
937  const AVIAMFDemixingInfo *demix = subblock;
938  if (!param_definition->mode && param->constant_subblock_duration == 0)
939  ffio_write_leb(dyn_bc, demix->subblock_duration);
940 
941  avio_w8(dyn_bc, demix->dmixp_mode << 5);
942  break;
943  }
945  const AVIAMFReconGain *recon = subblock;
946  const AVIAMFAudioElement *audio_element = param_definition->audio_element->celement;
947 
948  if (!param_definition->mode && param->constant_subblock_duration == 0)
949  ffio_write_leb(dyn_bc, recon->subblock_duration);
950 
951  if (!audio_element) {
952  av_log(log_ctx, AV_LOG_ERROR, "Invalid Parameter Definition with ID %u referenced by a packet\n", param->parameter_id);
953  return AVERROR(EINVAL);
954  }
955 
956  for (int j = 0; j < audio_element->nb_layers; j++) {
957  const AVIAMFLayer *layer = audio_element->layers[j];
958 
959  if (layer->flags & AV_IAMF_LAYER_FLAG_RECON_GAIN) {
960  unsigned int recon_gain_flags = 0;
961  int k = 0;
962 
963  for (; k < 7; k++)
964  recon_gain_flags |= (1 << k) * !!recon->recon_gain[j][k];
965  for (; k < 12; k++)
966  recon_gain_flags |= (2 << k) * !!recon->recon_gain[j][k];
967  if (recon_gain_flags >> 8)
968  recon_gain_flags |= (1 << k);
969 
970  ffio_write_leb(dyn_bc, recon_gain_flags);
971  for (k = 0; k < 12; k++) {
972  if (recon->recon_gain[j][k])
973  avio_w8(dyn_bc, recon->recon_gain[j][k]);
974  }
975  }
976  }
977  break;
978  }
979  default:
980  av_assert0(0);
981  }
982  }
983 
984  dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
985  ffio_write_leb(pb, dyn_size);
986  avio_write(pb, dyn_buf, dyn_size);
987  ffio_free_dyn_buf(&dyn_bc);
988 
989  return 0;
990 }
991 
993  const AVPacket *pkt, void *log_ctx)
994 {
998  NULL);
999  AVIAMFParamDefinition *demix =
1002  NULL);
1003  AVIAMFParamDefinition *recon =
1006  NULL);
1007 
1008  if (mix) {
1009  int ret = write_parameter_block(iamf, pb, mix, log_ctx);
1010  if (ret < 0)
1011  return ret;
1012  }
1013  if (demix) {
1014  int ret = write_parameter_block(iamf, pb, demix, log_ctx);
1015  if (ret < 0)
1016  return ret;
1017  }
1018  if (recon) {
1019  int ret = write_parameter_block(iamf, pb, recon, log_ctx);
1020  if (ret < 0)
1021  return ret;
1022  }
1023 
1024  return 0;
1025 }
1026 
1028  unsigned int audio_substream_id)
1029 {
1030  for (int i = 0; i < c->nb_audio_elements; i++) {
1031  IAMFAudioElement *audio_element = c->audio_elements[i];
1032  for (int j = 0; j < audio_element->nb_substreams; j++) {
1033  IAMFSubStream *substream = &audio_element->substreams[j];
1034  if (substream->audio_substream_id == audio_substream_id)
1035  return audio_element;
1036  }
1037  }
1038 
1039  return NULL;
1040 }
1041 
1043  unsigned audio_substream_id, const AVPacket *pkt)
1044 {
1046  PutBitContext pbc;
1047  AVIOContext *dyn_bc;
1048  const uint8_t *side_data;
1049  uint8_t *dyn_buf = NULL;
1050  unsigned int skip_samples = 0, discard_padding = 0;
1051  size_t side_data_size;
1052  int dyn_size, type = audio_substream_id <= 17 ?
1054  int ret;
1055 
1056  if (!pkt->size) {
1057  const IAMFAudioElement *audio_element;
1058  IAMFCodecConfig *codec_config;
1059  size_t new_extradata_size;
1060  const uint8_t *new_extradata = av_packet_get_side_data(pkt,
1062  &new_extradata_size);
1063 
1064  if (!new_extradata)
1065  return AVERROR_INVALIDDATA;
1066  audio_element = get_audio_element(iamf, audio_substream_id);
1067  if (!audio_element)
1068  return AVERROR(EINVAL);
1069  codec_config = ff_iamf_get_codec_config(iamf, audio_element->codec_config_id);
1070  if (!codec_config)
1071  return AVERROR(EINVAL);
1072 
1073  av_free(codec_config->extradata);
1074  codec_config->extradata = av_memdup(new_extradata, new_extradata_size);
1075  if (!codec_config->extradata) {
1076  codec_config->extradata_size = 0;
1077  return AVERROR(ENOMEM);
1078  }
1079  codec_config->extradata_size = new_extradata_size;
1080 
1081  return update_extradata(codec_config);
1082  }
1083 
1085  &side_data_size);
1086 
1087  if (side_data && side_data_size >= 10) {
1088  skip_samples = AV_RL32(side_data);
1089  discard_padding = AV_RL32(side_data + 4);
1090  }
1091 
1092  ret = avio_open_dyn_buf(&dyn_bc);
1093  if (ret < 0)
1094  return ret;
1095 
1096  init_put_bits(&pbc, header, sizeof(header));
1097  put_bits(&pbc, 5, type);
1098  put_bits(&pbc, 1, 0); // obu_redundant_copy
1099  put_bits(&pbc, 1, skip_samples || discard_padding);
1100  put_bits(&pbc, 1, 0); // obu_extension_flag
1101  flush_put_bits(&pbc);
1102  avio_write(pb, header, put_bytes_count(&pbc, 1));
1103 
1104  if (skip_samples || discard_padding) {
1105  ffio_write_leb(dyn_bc, discard_padding);
1106  ffio_write_leb(dyn_bc, skip_samples);
1107  }
1108 
1109  if (audio_substream_id > 17)
1110  ffio_write_leb(dyn_bc, audio_substream_id);
1111 
1112  dyn_size = avio_get_dyn_buf(dyn_bc, &dyn_buf);
1113  ffio_write_leb(pb, dyn_size + pkt->size);
1114  avio_write(pb, dyn_buf, dyn_size);
1115  ffio_free_dyn_buf(&dyn_bc);
1116  avio_write(pb, pkt->data, pkt->size);
1117 
1118  return 0;
1119 }
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
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:867
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
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
AVStreamGroup::params
union AVStreamGroup::@317 params
Group type-specific parameters.
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:491
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:1027
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:337
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:992
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:698
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:496
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:412
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:554
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:1042
ff_iamf_write_descriptors
int ff_iamf_write_descriptors(const IAMFContext *iamf, AVIOContext *pb, void *log_ctx)
Definition: iamf_writer.c:834
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:534
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
AVChannelLayout::u
union AVChannelLayout::@372 u
Details about which channels are present in this layout.
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:595
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