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