History

avutil: introduce an Immersive Audio Model and Formats API

James Almer committed 2 years ago

Commit d2af93b1 parent be8a4f85 files · +1194 −1Browse files

Unified · Split

5 files
  1. doc/APIchanges +3 −0
  2. libavutil/Makefile +2 −0
  3. libavutil/iamf.c +563 −0
  4. libavutil/iamf.h +625 −0
  5. libavutil/version.h +1 −1
doc/APIchanges+3−0
@@ -2,6 +2,9 @@ The last version increases of all libraries were on 2023-02-09 · 1 unmodified line
2 2
3API changes, most recent first:3API changes, most recent first:
4 4
52023-12-18 - xxxxxxxxxxx - lavu 58.35.100 - iamf.h
6 Add a new API to support Immersive Audio Model and Formats.
7
52023-12-xx - xxxxxxxxxxx - lavu 58.33.100 - imgutils.h82023-12-xx - xxxxxxxxxxx - lavu 58.33.100 - imgutils.h
6 Add av_image_fill_color().9 Add av_image_fill_color().
7 10
libavutil/Makefile+2−0
@@ -51,6 +51,7 @@ HEADERS = adler32.h \ · 50 unmodified lines
51 hwcontext_videotoolbox.h \51 hwcontext_videotoolbox.h \
52 hwcontext_vdpau.h \52 hwcontext_vdpau.h \
53 hwcontext_vulkan.h \53 hwcontext_vulkan.h \
54 iamf.h \
54 imgutils.h \55 imgutils.h \
55 intfloat.h \56 intfloat.h \
56 intreadwrite.h \57 intreadwrite.h \
@@ -140,6 +141,7 @@ OBJS = adler32.o \ · 83 unmodified lines
140 hdr_dynamic_vivid_metadata.o \141 hdr_dynamic_vivid_metadata.o \
141 hmac.o \142 hmac.o \
142 hwcontext.o \143 hwcontext.o \
144 iamf.o \
143 imgutils.o \145 imgutils.o \
144 integer.o \146 integer.o \
145 intmath.o \147 intmath.o \
libavutil/iamf.c+563−0
@@ -0,0 +1,563 @@
1/*
2 * Immersive Audio Model and Formats helper functions and defines
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <limits.h>
22#include <stddef.h>
23#include <stdint.h>
24
25#include "avassert.h"
26#include "error.h"
27#include "iamf.h"
28#include "log.h"
29#include "mem.h"
30#include "opt.h"
31
32#define IAMF_ADD_FUNC_TEMPLATE(parent_type, parent_name, child_type, child_name, suffix) \
33child_type *av_iamf_ ## parent_name ## _add_ ## child_name(parent_type *parent_name) \
34{ \
35 child_type **child_name ## suffix, *child_name; \
36 \
37 if (parent_name->nb_## child_name ## suffix == UINT_MAX) \
38 return NULL; \
39 \
40 child_name ## suffix = av_realloc_array(parent_name->child_name ## suffix, \
41 parent_name->nb_## child_name ## suffix + 1, \
42 sizeof(*parent_name->child_name ## suffix)); \
43 if (!child_name ## suffix) \
44 return NULL; \
45 \
46 parent_name->child_name ## suffix = child_name ## suffix; \
47 \
48 child_name = parent_name->child_name ## suffix[parent_name->nb_## child_name ## suffix] \
49 = av_mallocz(sizeof(*child_name)); \
50 if (!child_name) \
51 return NULL; \
52 \
53 child_name->av_class = &child_name ## _class; \
54 av_opt_set_defaults(child_name); \
55 parent_name->nb_## child_name ## suffix++; \
56 \
57 return child_name; \
58}
59
60#define FLAGS AV_OPT_FLAG_ENCODING_PARAM
61
62//
63// Param Definition
64//
65#define OFFSET(x) offsetof(AVIAMFMixGain, x)
66static const AVOption mix_gain_options[] = {
67 { "subblock_duration", "set subblock_duration", OFFSET(subblock_duration), AV_OPT_TYPE_INT64, {.i64 = 1 }, 1, UINT_MAX, FLAGS },
68 { "animation_type", "set animation_type", OFFSET(animation_type), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 2, FLAGS },
69 { "start_point_value", "set start_point_value", OFFSET(animation_type), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, -128.0, 128.0, FLAGS },
70 { "end_point_value", "set end_point_value", OFFSET(animation_type), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, -128.0, 128.0, FLAGS },
71 { "control_point_value", "set control_point_value", OFFSET(animation_type), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, -128.0, 128.0, FLAGS },
72 { "control_point_relative_time", "set control_point_relative_time", OFFSET(animation_type), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0.0, 1.0, FLAGS },
73 { NULL },
74};
75
76static const AVClass mix_gain_class = {
77 .class_name = "AVIAMFSubmixElement",
78 .item_name = av_default_item_name,
79 .version = LIBAVUTIL_VERSION_INT,
80 .option = mix_gain_options,
81};
82
83#undef OFFSET
84#define OFFSET(x) offsetof(AVIAMFDemixingInfo, x)
85static const AVOption demixing_info_options[] = {
86 { "subblock_duration", "set subblock_duration", OFFSET(subblock_duration), AV_OPT_TYPE_INT64, {.i64 = 1 }, 1, UINT_MAX, FLAGS },
87 { "dmixp_mode", "set dmixp_mode", OFFSET(dmixp_mode), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 6, FLAGS },
88 { NULL },
89};
90
91static const AVClass demixing_info_class = {
92 .class_name = "AVIAMFDemixingInfo",
93 .item_name = av_default_item_name,
94 .version = LIBAVUTIL_VERSION_INT,
95 .option = demixing_info_options,
96};
97
98#undef OFFSET
99#define OFFSET(x) offsetof(AVIAMFReconGain, x)
100static const AVOption recon_gain_options[] = {
101 { "subblock_duration", "set subblock_duration", OFFSET(subblock_duration), AV_OPT_TYPE_INT64, {.i64 = 1 }, 1, UINT_MAX, FLAGS },
102 { NULL },
103};
104
105static const AVClass recon_gain_class = {
106 .class_name = "AVIAMFReconGain",
107 .item_name = av_default_item_name,
108 .version = LIBAVUTIL_VERSION_INT,
109 .option = recon_gain_options,
110};
111
112#undef OFFSET
113#define OFFSET(x) offsetof(AVIAMFParamDefinition, x)
114static const AVOption param_definition_options[] = {
115 { "parameter_id", "set parameter_id", OFFSET(parameter_id), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, UINT_MAX, FLAGS },
116 { "parameter_rate", "set parameter_rate", OFFSET(parameter_rate), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, UINT_MAX, FLAGS },
117 { "duration", "set duration", OFFSET(duration), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, UINT_MAX, FLAGS },
118 { "constant_subblock_duration", "set constant_subblock_duration", OFFSET(constant_subblock_duration), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, UINT_MAX, FLAGS },
119 { NULL },
120};
121
122static const AVClass *param_definition_child_iterate(void **opaque)
123{
124 uintptr_t i = (uintptr_t)*opaque;
125 const AVClass *ret = NULL;
126
127 switch(i) {
128 case AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN:
129 ret = &mix_gain_class;
130 break;
131 case AV_IAMF_PARAMETER_DEFINITION_DEMIXING:
132 ret = &demixing_info_class;
133 break;
134 case AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN:
135 ret = &recon_gain_class;
136 break;
137 default:
138 break;
139 }
140
141 if (ret)
142 *opaque = (void*)(i + 1);
143 return ret;
144}
145
146static const AVClass param_definition_class = {
147 .class_name = "AVIAMFParamDefinition",
148 .item_name = av_default_item_name,
149 .version = LIBAVUTIL_VERSION_INT,
150 .option = param_definition_options,
151 .child_class_iterate = param_definition_child_iterate,
152};
153
154const AVClass *av_iamf_param_definition_get_class(void)
155{
156 return &param_definition_class;
157}
158
159AVIAMFParamDefinition *av_iamf_param_definition_alloc(enum AVIAMFParamDefinitionType type,
160 unsigned int nb_subblocks, size_t *out_size)
161{
162
163 struct MixGainStruct {
164 AVIAMFParamDefinition p;
165 AVIAMFMixGain m;
166 };
167 struct DemixStruct {
168 AVIAMFParamDefinition p;
169 AVIAMFDemixingInfo d;
170 };
171 struct ReconGainStruct {
172 AVIAMFParamDefinition p;
173 AVIAMFReconGain r;
174 };
175 size_t subblocks_offset, subblock_size;
176 size_t size;
177 AVIAMFParamDefinition *par;
178
179 switch (type) {
180 case AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN:
181 subblocks_offset = offsetof(struct MixGainStruct, m);
182 subblock_size = sizeof(AVIAMFMixGain);
183 break;
184 case AV_IAMF_PARAMETER_DEFINITION_DEMIXING:
185 subblocks_offset = offsetof(struct DemixStruct, d);
186 subblock_size = sizeof(AVIAMFDemixingInfo);
187 break;
188 case AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN:
189 subblocks_offset = offsetof(struct ReconGainStruct, r);
190 subblock_size = sizeof(AVIAMFReconGain);
191 break;
192 default:
193 return NULL;
194 }
195
196 size = subblocks_offset;
197 if (nb_subblocks > (SIZE_MAX - size) / subblock_size)
198 return NULL;
199 size += subblock_size * nb_subblocks;
200
201 par = av_mallocz(size);
202 if (!par)
203 return NULL;
204
205 par->av_class = &param_definition_class;
206 av_opt_set_defaults(par);
207
208 par->type = type;
209 par->nb_subblocks = nb_subblocks;
210 par->subblock_size = subblock_size;
211 par->subblocks_offset = subblocks_offset;
212
213 for (int i = 0; i < nb_subblocks; i++) {
214 void *subblock = av_iamf_param_definition_get_subblock(par, i);
215
216 switch (type) {
217 case AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN:
218 ((AVIAMFMixGain *)subblock)->av_class = &mix_gain_class;
219 break;
220 case AV_IAMF_PARAMETER_DEFINITION_DEMIXING:
221 ((AVIAMFDemixingInfo *)subblock)->av_class = &demixing_info_class;
222 break;
223 case AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN:
224 ((AVIAMFReconGain *)subblock)->av_class = &recon_gain_class;
225 break;
226 default:
227 av_assert0(0);
228 }
229
230 av_opt_set_defaults(subblock);
231 }
232
233 if (out_size)
234 *out_size = size;
235
236 return par;
237}
238
239//
240// Audio Element
241//
242#undef OFFSET
243#define OFFSET(x) offsetof(AVIAMFLayer, x)
244static const AVOption layer_options[] = {
245 { "ch_layout", "set ch_layout", OFFSET(ch_layout), AV_OPT_TYPE_CHLAYOUT, {.str = NULL }, 0, 0, FLAGS },
246 { "flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS,
247 {.i64 = 0 }, 0, AV_IAMF_LAYER_FLAG_RECON_GAIN, FLAGS, "flags" },
248 {"recon_gain", "Recon gain is present", 0, AV_OPT_TYPE_CONST,
249 {.i64 = AV_IAMF_LAYER_FLAG_RECON_GAIN }, INT_MIN, INT_MAX, FLAGS, "flags"},
250 { "output_gain_flags", "set output_gain_flags", OFFSET(output_gain_flags), AV_OPT_TYPE_FLAGS,
251 {.i64 = 0 }, 0, (1 << 6) - 1, FLAGS, "output_gain_flags" },
252 {"FL", "Left channel", 0, AV_OPT_TYPE_CONST,
253 {.i64 = 1 << 5 }, INT_MIN, INT_MAX, FLAGS, "output_gain_flags"},
254 {"FR", "Right channel", 0, AV_OPT_TYPE_CONST,
255 {.i64 = 1 << 4 }, INT_MIN, INT_MAX, FLAGS, "output_gain_flags"},
256 {"BL", "Left surround channel", 0, AV_OPT_TYPE_CONST,
257 {.i64 = 1 << 3 }, INT_MIN, INT_MAX, FLAGS, "output_gain_flags"},
258 {"BR", "Right surround channel", 0, AV_OPT_TYPE_CONST,
259 {.i64 = 1 << 2 }, INT_MIN, INT_MAX, FLAGS, "output_gain_flags"},
260 {"TFL", "Left top front channel", 0, AV_OPT_TYPE_CONST,
261 {.i64 = 1 << 1 }, INT_MIN, INT_MAX, FLAGS, "output_gain_flags"},
262 {"TFR", "Right top front channel", 0, AV_OPT_TYPE_CONST,
263 {.i64 = 1 << 0 }, INT_MIN, INT_MAX, FLAGS, "output_gain_flags"},
264 { "output_gain", "set output_gain", OFFSET(output_gain), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, -128.0, 128.0, FLAGS },
265 { "ambisonics_mode", "set ambisonics_mode", OFFSET(ambisonics_mode), AV_OPT_TYPE_INT,
266 { .i64 = AV_IAMF_AMBISONICS_MODE_MONO },
267 AV_IAMF_AMBISONICS_MODE_MONO, AV_IAMF_AMBISONICS_MODE_PROJECTION, FLAGS, "ambisonics_mode" },
268 { "mono", NULL, 0, AV_OPT_TYPE_CONST,
269 { .i64 = AV_IAMF_AMBISONICS_MODE_MONO }, .unit = "ambisonics_mode" },
270 { "projection", NULL, 0, AV_OPT_TYPE_CONST,
271 { .i64 = AV_IAMF_AMBISONICS_MODE_PROJECTION }, .unit = "ambisonics_mode" },
272 { NULL },
273};
274
275static const AVClass layer_class = {
276 .class_name = "AVIAMFLayer",
277 .item_name = av_default_item_name,
278 .version = LIBAVUTIL_VERSION_INT,
279 .option = layer_options,
280};
281
282#undef OFFSET
283#define OFFSET(x) offsetof(AVIAMFAudioElement, x)
284static const AVOption audio_element_options[] = {
285 { "audio_element_type", "set audio_element_type", OFFSET(audio_element_type), AV_OPT_TYPE_INT,
286 {.i64 = AV_IAMF_AUDIO_ELEMENT_TYPE_CHANNEL },
287 AV_IAMF_AUDIO_ELEMENT_TYPE_CHANNEL, AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE, FLAGS, "audio_element_type" },
288 { "channel", NULL, 0, AV_OPT_TYPE_CONST,
289 { .i64 = AV_IAMF_AUDIO_ELEMENT_TYPE_CHANNEL }, .unit = "audio_element_type" },
290 { "scene", NULL, 0, AV_OPT_TYPE_CONST,
291 { .i64 = AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE }, .unit = "audio_element_type" },
292 { "default_w", "set default_w", OFFSET(default_w), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 10, FLAGS },
293 { NULL },
294};
295
296static const AVClass *audio_element_child_iterate(void **opaque)
297{
298 uintptr_t i = (uintptr_t)*opaque;
299 const AVClass *ret = NULL;
300
301 if (i)
302 ret = &layer_class;
303
304 if (ret)
305 *opaque = (void*)(i + 1);
306 return ret;
307}
308
309static const AVClass audio_element_class = {
310 .class_name = "AVIAMFAudioElement",
311 .item_name = av_default_item_name,
312 .version = LIBAVUTIL_VERSION_INT,
313 .option = audio_element_options,
314 .child_class_iterate = audio_element_child_iterate,
315};
316
317const AVClass *av_iamf_audio_element_get_class(void)
318{
319 return &audio_element_class;
320}
321
322AVIAMFAudioElement *av_iamf_audio_element_alloc(void)
323{
324 AVIAMFAudioElement *audio_element = av_mallocz(sizeof(*audio_element));
325
326 if (audio_element) {
327 audio_element->av_class = &audio_element_class;
328 av_opt_set_defaults(audio_element);
329 }
330
331 return audio_element;
332}
333
334IAMF_ADD_FUNC_TEMPLATE(AVIAMFAudioElement, audio_element, AVIAMFLayer, layer, s)
335
336void av_iamf_audio_element_free(AVIAMFAudioElement **paudio_element)
337{
338 AVIAMFAudioElement *audio_element = *paudio_element;
339
340 if (!audio_element)
341 return;
342
343 for (int i = 0; i < audio_element->nb_layers; i++) {
344 AVIAMFLayer *layer = audio_element->layers[i];
345 av_opt_free(layer);
346 av_free(layer->demixing_matrix);
347 av_free(layer);
348 }
349 av_free(audio_element->layers);
350
351 av_free(audio_element->demixing_info);
352 av_free(audio_element->recon_gain_info);
353 av_freep(paudio_element);
354}
355
356//
357// Mix Presentation
358//
359#undef OFFSET
360#define OFFSET(x) offsetof(AVIAMFSubmixElement, x)
361static const AVOption submix_element_options[] = {
362 { "headphones_rendering_mode", "Headphones rendering mode", OFFSET(headphones_rendering_mode), AV_OPT_TYPE_INT,
363 { .i64 = AV_IAMF_HEADPHONES_MODE_STEREO },
364 AV_IAMF_HEADPHONES_MODE_STEREO, AV_IAMF_HEADPHONES_MODE_BINAURAL, FLAGS, "headphones_rendering_mode" },
365 { "stereo", NULL, 0, AV_OPT_TYPE_CONST,
366 { .i64 = AV_IAMF_HEADPHONES_MODE_STEREO }, .unit = "headphones_rendering_mode" },
367 { "binaural", NULL, 0, AV_OPT_TYPE_CONST,
368 { .i64 = AV_IAMF_HEADPHONES_MODE_BINAURAL }, .unit = "headphones_rendering_mode" },
369 { "default_mix_gain", "Default mix gain", OFFSET(default_mix_gain), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, -128.0, 128.0, FLAGS },
370 { "annotations", "Annotations", OFFSET(annotations), AV_OPT_TYPE_DICT, { .str = NULL }, 0, 0, FLAGS },
371 { NULL },
372};
373
374static void *submix_element_child_next(void *obj, void *prev)
375{
376 AVIAMFSubmixElement *submix_element = obj;
377 if (!prev)
378 return submix_element->element_mix_config;
379
380 return NULL;
381}
382
383static const AVClass *submix_element_child_iterate(void **opaque)
384{
385 uintptr_t i = (uintptr_t)*opaque;
386 const AVClass *ret = NULL;
387
388 if (i)
389 ret = &param_definition_class;
390
391 if (ret)
392 *opaque = (void*)(i + 1);
393 return ret;
394}
395
396static const AVClass element_class = {
397 .class_name = "AVIAMFSubmixElement",
398 .item_name = av_default_item_name,
399 .version = LIBAVUTIL_VERSION_INT,
400 .option = submix_element_options,
401 .child_next = submix_element_child_next,
402 .child_class_iterate = submix_element_child_iterate,
403};
404
405IAMF_ADD_FUNC_TEMPLATE(AVIAMFSubmix, submix, AVIAMFSubmixElement, element, s)
406
407#undef OFFSET
408#define OFFSET(x) offsetof(AVIAMFSubmixLayout, x)
409static const AVOption submix_layout_options[] = {
410 { "layout_type", "Layout type", OFFSET(layout_type), AV_OPT_TYPE_INT,
411 { .i64 = AV_IAMF_SUBMIX_LAYOUT_TYPE_LOUDSPEAKERS },
412 AV_IAMF_SUBMIX_LAYOUT_TYPE_LOUDSPEAKERS, AV_IAMF_SUBMIX_LAYOUT_TYPE_BINAURAL, FLAGS, "layout_type" },
413 { "loudspeakers", NULL, 0, AV_OPT_TYPE_CONST,
414 { .i64 = AV_IAMF_SUBMIX_LAYOUT_TYPE_LOUDSPEAKERS }, .unit = "layout_type" },
415 { "binaural", NULL, 0, AV_OPT_TYPE_CONST,
416 { .i64 = AV_IAMF_SUBMIX_LAYOUT_TYPE_BINAURAL }, .unit = "layout_type" },
417 { "sound_system", "Sound System", OFFSET(sound_system), AV_OPT_TYPE_CHLAYOUT, { .str = NULL }, 0, 0, FLAGS },
418 { "integrated_loudness", "Integrated loudness", OFFSET(integrated_loudness), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, -128.0, 128.0, FLAGS },
419 { "digital_peak", "Digital peak", OFFSET(digital_peak), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, -128.0, 128.0, FLAGS },
420 { "true_peak", "True peak", OFFSET(true_peak), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, -128.0, 128.0, FLAGS },
421 { "dialog_anchored_loudness", "Anchored loudness (Dialog)", OFFSET(dialogue_anchored_loudness), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, -128.0, 128.0, FLAGS },
422 { "album_anchored_loudness", "Anchored loudness (Album)", OFFSET(album_anchored_loudness), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, -128.0, 128.0, FLAGS },
423 { NULL },
424};
425
426static const AVClass layout_class = {
427 .class_name = "AVIAMFSubmixLayout",
428 .item_name = av_default_item_name,
429 .version = LIBAVUTIL_VERSION_INT,
430 .option = submix_layout_options,
431};
432
433IAMF_ADD_FUNC_TEMPLATE(AVIAMFSubmix, submix, AVIAMFSubmixLayout, layout, s)
434
435#undef OFFSET
436#define OFFSET(x) offsetof(AVIAMFSubmix, x)
437static const AVOption submix_presentation_options[] = {
438 { "default_mix_gain", "Default mix gain", OFFSET(default_mix_gain), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, -128.0, 128.0, FLAGS },
439 { NULL },
440};
441
442static void *submix_presentation_child_next(void *obj, void *prev)
443{
444 AVIAMFSubmix *sub_mix = obj;
445 if (!prev)
446 return sub_mix->output_mix_config;
447
448 return NULL;
449}
450
451static const AVClass *submix_presentation_child_iterate(void **opaque)
452{
453 uintptr_t i = (uintptr_t)*opaque;
454 const AVClass *ret = NULL;
455
456 switch(i) {
457 case 0:
458 ret = &element_class;
459 break;
460 case 1:
461 ret = &layout_class;
462 break;
463 case 2:
464 ret = &param_definition_class;
465 break;
466 default:
467 break;
468 }
469
470 if (ret)
471 *opaque = (void*)(i + 1);
472 return ret;
473}
474
475static const AVClass submix_class = {
476 .class_name = "AVIAMFSubmix",
477 .item_name = av_default_item_name,
478 .version = LIBAVUTIL_VERSION_INT,
479 .option = submix_presentation_options,
480 .child_next = submix_presentation_child_next,
481 .child_class_iterate = submix_presentation_child_iterate,
482};
483
484#undef OFFSET
485#define OFFSET(x) offsetof(AVIAMFMixPresentation, x)
486static const AVOption mix_presentation_options[] = {
487 { "annotations", "set annotations", OFFSET(annotations), AV_OPT_TYPE_DICT, {.str = NULL }, 0, 0, FLAGS },
488 { NULL },
489};
490
491#undef OFFSET
492#undef FLAGS
493
494static const AVClass *mix_presentation_child_iterate(void **opaque)
495{
496 uintptr_t i = (uintptr_t)*opaque;
497 const AVClass *ret = NULL;
498
499 if (i)
500 ret = &submix_class;
501
502 if (ret)
503 *opaque = (void*)(i + 1);
504 return ret;
505}
506
507static const AVClass mix_presentation_class = {
508 .class_name = "AVIAMFMixPresentation",
509 .item_name = av_default_item_name,
510 .version = LIBAVUTIL_VERSION_INT,
511 .option = mix_presentation_options,
512 .child_class_iterate = mix_presentation_child_iterate,
513};
514
515const AVClass *av_iamf_mix_presentation_get_class(void)
516{
517 return &mix_presentation_class;
518}
519
520AVIAMFMixPresentation *av_iamf_mix_presentation_alloc(void)
521{
522 AVIAMFMixPresentation *mix_presentation = av_mallocz(sizeof(*mix_presentation));
523
524 if (mix_presentation) {
525 mix_presentation->av_class = &mix_presentation_class;
526 av_opt_set_defaults(mix_presentation);
527 }
528
529 return mix_presentation;
530}
531
532IAMF_ADD_FUNC_TEMPLATE(AVIAMFMixPresentation, mix_presentation, AVIAMFSubmix, submix, es)
533
534void av_iamf_mix_presentation_free(AVIAMFMixPresentation **pmix_presentation)
535{
536 AVIAMFMixPresentation *mix_presentation = *pmix_presentation;
537
538 if (!mix_presentation)
539 return;
540
541 for (int i = 0; i < mix_presentation->nb_submixes; i++) {
542 AVIAMFSubmix *sub_mix = mix_presentation->submixes[i];
543 for (int j = 0; j < sub_mix->nb_elements; j++) {
544 AVIAMFSubmixElement *submix_element = sub_mix->elements[j];
545 av_opt_free(submix_element);
546 av_free(submix_element->element_mix_config);
547 av_free(submix_element);
548 }
549 av_free(sub_mix->elements);
550 for (int j = 0; j < sub_mix->nb_layouts; j++) {
551 AVIAMFSubmixLayout *submix_layout = sub_mix->layouts[j];
552 av_opt_free(submix_layout);
553 av_free(submix_layout);
554 }
555 av_free(sub_mix->layouts);
556 av_free(sub_mix->output_mix_config);
557 av_free(sub_mix);
558 }
559 av_opt_free(mix_presentation);
560 av_free(mix_presentation->submixes);
561
562 av_freep(pmix_presentation);
563}
libavutil/iamf.h+625−0
@@ -0,0 +1,625 @@
1/*
2 * Immersive Audio Model and Formats helper functions and defines
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#ifndef AVUTIL_IAMF_H
22#define AVUTIL_IAMF_H
23
24/**
25 * @file
26 * Immersive Audio Model and Formats API header
27 * @see <a href="https://aomediacodec.github.io/iamf/">Immersive Audio Model and Formats</a>
28 */
29
30#include <stdint.h>
31#include <stddef.h>
32
33#include "attributes.h"
34#include "avassert.h"
35#include "channel_layout.h"
36#include "dict.h"
37#include "rational.h"
38
39/**
40 * @defgroup lavf_iamf_params Parameter Definition
41 * @{
42 * Parameters as defined in section 3.6.1 and 3.8 of IAMF.
43 * @}
44 * @defgroup lavf_iamf_audio Audio Element
45 * @{
46 * Audio Elements as defined in section 3.6 of IAMF.
47 * @}
48 * @defgroup lavf_iamf_mix Mix Presentation
49 * @{
50 * Mix Presentations as defined in section 3.7 of IAMF.
51 * @}
52 *
53 * @}
54 * @addtogroup lavf_iamf_params
55 * @{
56 */
57enum AVIAMFAnimationType {
58 AV_IAMF_ANIMATION_TYPE_STEP,
59 AV_IAMF_ANIMATION_TYPE_LINEAR,
60 AV_IAMF_ANIMATION_TYPE_BEZIER,
61};
62
63/**
64 * Mix Gain Parameter Data as defined in section 3.8.1 of IAMF.
65 */
66typedef struct AVIAMFMixGain {
67 const AVClass *av_class;
68
69 /**
70 * Duration for the given subblock, in units of
71 * 1 / @ref AVIAMFParamDefinition.parameter_rate "parameter_rate".
72 * It must not be 0.
73 */
74 unsigned int subblock_duration;
75 /**
76 * The type of animation applied to the parameter values.
77 */
78 enum AVIAMFAnimationType animation_type;
79 /**
80 * Parameter value that is applied at the start of the subblock.
81 * Applies to all defined Animation Types.
82 *
83 * Valid range of values is -128.0 to 128.0
84 */
85 AVRational start_point_value;
86 /**
87 * Parameter value that is applied at the end of the subblock.
88 * Applies only to AV_IAMF_ANIMATION_TYPE_LINEAR and
89 * AV_IAMF_ANIMATION_TYPE_BEZIER Animation Types.
90 *
91 * Valid range of values is -128.0 to 128.0
92 */
93 AVRational end_point_value;
94 /**
95 * Parameter value of the middle control point of a quadratic Bezier
96 * curve, i.e., its y-axis value.
97 * Applies only to AV_IAMF_ANIMATION_TYPE_BEZIER Animation Type.
98 *
99 * Valid range of values is -128.0 to 128.0
100 */
101 AVRational control_point_value;
102 /**
103 * Parameter value of the time of the middle control point of a
104 * quadratic Bezier curve, i.e., its x-axis value.
105 * Applies only to AV_IAMF_ANIMATION_TYPE_BEZIER Animation Type.
106 *
107 * Valid range of values is 0.0 to 1.0
108 */
109 AVRational control_point_relative_time;
110} AVIAMFMixGain;
111
112/**
113 * Demixing Info Parameter Data as defined in section 3.8.2 of IAMF.
114 */
115typedef struct AVIAMFDemixingInfo {
116 const AVClass *av_class;
117
118 /**
119 * Duration for the given subblock, in units of
120 * 1 / @ref AVIAMFParamDefinition.parameter_rate "parameter_rate".
121 * It must not be 0.
122 */
123 unsigned int subblock_duration;
124 /**
125 * Pre-defined combination of demixing parameters.
126 */
127 unsigned int dmixp_mode;
128} AVIAMFDemixingInfo;
129
130/**
131 * Recon Gain Info Parameter Data as defined in section 3.8.3 of IAMF.
132 */
133typedef struct AVIAMFReconGain {
134 const AVClass *av_class;
135
136 /**
137 * Duration for the given subblock, in units of
138 * 1 / @ref AVIAMFParamDefinition.parameter_rate "parameter_rate".
139 * It must not be 0.
140 */
141 unsigned int subblock_duration;
142
143 /**
144 * Array of gain values to be applied to each channel for each layer
145 * defined in the Audio Element referencing the parent Parameter Definition.
146 * Values for layers where the AV_IAMF_LAYER_FLAG_RECON_GAIN flag is not set
147 * are undefined.
148 *
149 * Channel order is: FL, C, FR, SL, SR, TFL, TFR, BL, BR, TBL, TBR, LFE
150 */
151 uint8_t recon_gain[6][12];
152} AVIAMFReconGain;
153
154enum AVIAMFParamDefinitionType {
155 /**
156 * Subblocks are of struct type AVIAMFMixGain
157 */
158 AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN,
159 /**
160 * Subblocks are of struct type AVIAMFDemixingInfo
161 */
162 AV_IAMF_PARAMETER_DEFINITION_DEMIXING,
163 /**
164 * Subblocks are of struct type AVIAMFReconGain
165 */
166 AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN,
167};
168
169/**
170 * Parameters as defined in section 3.6.1 of IAMF.
171 *
172 * The struct is allocated by av_iamf_param_definition_alloc() along with an
173 * array of subblocks, its type depending on the value of type.
174 * This array is placed subblocks_offset bytes after the start of this struct.
175 */
176typedef struct AVIAMFParamDefinition {
177 const AVClass *av_class;
178
179 /**
180 * Offset in bytes from the start of this struct, at which the subblocks
181 * array is located.
182 */
183 size_t subblocks_offset;
184 /**
185 * Size in bytes of each element in the subblocks array.
186 */
187 size_t subblock_size;
188 /**
189 * Number of subblocks in the array.
190 */
191 unsigned int nb_subblocks;
192
193 /**
194 * Parameters type. Determines the type of the subblock elements.
195 */
196 enum AVIAMFParamDefinitionType type;
197
198 /**
199 * Identifier for the paremeter substream.
200 */
201 unsigned int parameter_id;
202 /**
203 * Sample rate for the paremeter substream. It must not be 0.
204 */
205 unsigned int parameter_rate;
206
207 /**
208 * The accumulated duration of all blocks in this parameter definition,
209 * in units of 1 / @ref parameter_rate.
210 *
211 * May be 0, in which case all duration values should be specified in
212 * another parameter definition referencing the same parameter_id.
213 */
214 unsigned int duration;
215 /**
216 * The duration of every subblock in the case where all subblocks, with
217 * the optional exception of the last subblock, have equal durations.
218 *
219 * Must be 0 if subblocks have different durations.
220 */
221 unsigned int constant_subblock_duration;
222} AVIAMFParamDefinition;
223
224const AVClass *av_iamf_param_definition_get_class(void);
225
226/**
227 * Allocates memory for AVIAMFParamDefinition, plus an array of {@code nb_subblocks}
228 * amount of subblocks of the given type and initializes the variables. Can be
229 * freed with a normal av_free() call.
230 *
231 * @param size if non-NULL, the size in bytes of the resulting data array is written here.
232 */
233AVIAMFParamDefinition *av_iamf_param_definition_alloc(enum AVIAMFParamDefinitionType type,
234 unsigned int nb_subblocks, size_t *size);
235
236/**
237 * Get the subblock at the specified {@code idx}. Must be between 0 and nb_subblocks - 1.
238 *
239 * The @ref AVIAMFParamDefinition.type "param definition type" defines
240 * the struct type of the returned pointer.
241 */
242static av_always_inline void*
243av_iamf_param_definition_get_subblock(const AVIAMFParamDefinition *par, unsigned int idx)
244{
245 av_assert0(idx < par->nb_subblocks);
246 return (void *)((uint8_t *)par + par->subblocks_offset + idx * par->subblock_size);
247}
248
249/**
250 * @}
251 * @addtogroup lavf_iamf_audio
252 * @{
253 */
254
255enum AVIAMFAmbisonicsMode {
256 AV_IAMF_AMBISONICS_MODE_MONO,
257 AV_IAMF_AMBISONICS_MODE_PROJECTION,
258};
259
260/**
261 * Recon gain information for the layer is present in AVIAMFReconGain
262 */
263#define AV_IAMF_LAYER_FLAG_RECON_GAIN (1 << 0)
264
265/**
266 * A layer defining a Channel Layout in the Audio Element.
267 *
268 * When @ref AVIAMFAudioElement.audio_element_type "the parent's Audio Element type"
269 * is AV_IAMF_AUDIO_ELEMENT_TYPE_CHANNEL, this corresponds to an Scalable Channel
270 * Layout layer as defined in section 3.6.2 of IAMF.
271 * For AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE, it is an Ambisonics channel
272 * layout as defined in section 3.6.3 of IAMF.
273 */
274typedef struct AVIAMFLayer {
275 const AVClass *av_class;
276
277 AVChannelLayout ch_layout;
278
279 /**
280 * A bitmask which may contain a combination of AV_IAMF_LAYER_FLAG_* flags.
281 */
282 unsigned int flags;
283 /**
284 * Output gain channel flags as defined in section 3.6.2 of IAMF.
285 *
286 * This field is defined only if @ref AVIAMFAudioElement.audio_element_type
287 * "the parent's Audio Element type" is AV_IAMF_AUDIO_ELEMENT_TYPE_CHANNEL,
288 * must be 0 otherwise.
289 */
290 unsigned int output_gain_flags;
291 /**
292 * Output gain as defined in section 3.6.2 of IAMF.
293 *
294 * Must be 0 if @ref output_gain_flags is 0.
295 */
296 AVRational output_gain;
297 /**
298 * Ambisonics mode as defined in section 3.6.3 of IAMF.
299 *
300 * This field is defined only if @ref AVIAMFAudioElement.audio_element_type
301 * "the parent's Audio Element type" is AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE.
302 *
303 * If AV_IAMF_AMBISONICS_MODE_MONO, channel_mapping is defined implicitly
304 * (Ambisonic Order) or explicitly (Custom Order with ambi channels) in
305 * @ref ch_layout.
306 * If AV_IAMF_AMBISONICS_MODE_PROJECTION, @ref demixing_matrix must be set.
307 */
308 enum AVIAMFAmbisonicsMode ambisonics_mode;
309
310 /**
311 * Demixing matrix as defined in section 3.6.3 of IAMF.
312 *
313 * The length of the array is ch_layout.nb_channels multiplied by the sum of
314 * the amount of streams in the group plus the amount of streams in the group
315 * that are stereo.
316 *
317 * May be set only if @ref ambisonics_mode == AV_IAMF_AMBISONICS_MODE_PROJECTION,
318 * must be NULL otherwise.
319 */
320 AVRational *demixing_matrix;
321} AVIAMFLayer;
322
323
324enum AVIAMFAudioElementType {
325 AV_IAMF_AUDIO_ELEMENT_TYPE_CHANNEL,
326 AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE,
327};
328
329typedef struct AVIAMFAudioElement {
330 const AVClass *av_class;
331
332 AVIAMFLayer **layers;
333 /**
334 * Number of layers, or channel groups, in the Audio Element.
335 * There may be 6 layers at most, and for @ref audio_element_type
336 * AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE, there may be exactly 1.
337 *
338 * Set by av_iamf_audio_element_add_layer(), must not be
339 * modified by any other code.
340 */
341 unsigned int nb_layers;
342
343 /**
344 * Demixing information used to reconstruct a scalable channel audio
345 * representation.
346 * The @ref AVIAMFParamDefinition.type "type" must be
347 * AV_IAMF_PARAMETER_DEFINITION_DEMIXING.
348 */
349 AVIAMFParamDefinition *demixing_info;
350 /**
351 * Recon gain information used to reconstruct a scalable channel audio
352 * representation.
353 * The @ref AVIAMFParamDefinition.type "type" must be
354 * AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN.
355 */
356 AVIAMFParamDefinition *recon_gain_info;
357
358 /**
359 * Audio element type as defined in section 3.6 of IAMF.
360 */
361 enum AVIAMFAudioElementType audio_element_type;
362
363 /**
364 * Default weight value as defined in section 3.6 of IAMF.
365 */
366 unsigned int default_w;
367} AVIAMFAudioElement;
368
369const AVClass *av_iamf_audio_element_get_class(void);
370
371/**
372 * Allocates a AVIAMFAudioElement, and initializes its fields with default values.
373 * No layers are allocated. Must be freed with av_iamf_audio_element_free().
374 *
375 * @see av_iamf_audio_element_add_layer()
376 */
377AVIAMFAudioElement *av_iamf_audio_element_alloc(void);
378
379/**
380 * Allocate a layer and add it to a given AVIAMFAudioElement.
381 * It is freed by av_iamf_audio_element_free() alongside the rest of the parent
382 * AVIAMFAudioElement.
383 *
384 * @return a pointer to the allocated layer.
385 */
386AVIAMFLayer *av_iamf_audio_element_add_layer(AVIAMFAudioElement *audio_element);
387
388void av_iamf_audio_element_free(AVIAMFAudioElement **audio_element);
389
390/**
391 * @}
392 * @addtogroup lavf_iamf_mix
393 * @{
394 */
395
396enum AVIAMFHeadphonesMode {
397 /**
398 * The referenced Audio Element shall be rendered to stereo loudspeakers.
399 */
400 AV_IAMF_HEADPHONES_MODE_STEREO,
401 /**
402 * The referenced Audio Element shall be rendered with a binaural renderer.
403 */
404 AV_IAMF_HEADPHONES_MODE_BINAURAL,
405};
406
407typedef struct AVIAMFSubmixElement {
408 const AVClass *av_class;
409
410 /**
411 * The id of the Audio Element this submix element references.
412 */
413 unsigned int audio_element_id;
414
415 /**
416 * Information required required for applying any processing to the
417 * referenced and rendered Audio Element before being summed with other
418 * processed Audio Elements.
419 * The @ref AVIAMFParamDefinition.type "type" must be
420 * AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN.
421 */
422 AVIAMFParamDefinition *element_mix_config;
423
424 /**
425 * Default mix gain value to apply when there are no AVIAMFParamDefinition
426 * with @ref element_mix_config "element_mix_config's"
427 * @ref AVIAMFParamDefinition.parameter_id "parameter_id" available for a
428 * given audio frame.
429 */
430 AVRational default_mix_gain;
431
432 /**
433 * A value that indicates whether the referenced channel-based Audio Element
434 * shall be rendered to stereo loudspeakers or spatialized with a binaural
435 * renderer when played back on headphones.
436 * If the Audio Element is not of @ref AVIAMFAudioElement.audio_element_type
437 * "type" AV_IAMF_AUDIO_ELEMENT_TYPE_CHANNEL, then this field is undefined.
438 */
439 enum AVIAMFHeadphonesMode headphones_rendering_mode;
440
441 /**
442 * A dictionary of strings describing the submix in different languages.
443 * Must have the same amount of entries as
444 * @ref AVIAMFMixPresentation.annotations "the mix's annotations", stored
445 * in the same order, and with the same key strings.
446 *
447 * @ref AVDictionaryEntry.key "key" is a string conforming to BCP-47 that
448 * specifies the language for the string stored in
449 * @ref AVDictionaryEntry.value "value".
450 */
451 AVDictionary *annotations;
452} AVIAMFSubmixElement;
453
454enum AVIAMFSubmixLayoutType {
455 /**
456 * The layout follows the loudspeaker sound system convention of ITU-2051-3.
457 */
458 AV_IAMF_SUBMIX_LAYOUT_TYPE_LOUDSPEAKERS = 2,
459 /**
460 * The layout is binaural.
461 */
462 AV_IAMF_SUBMIX_LAYOUT_TYPE_BINAURAL = 3,
463};
464
465typedef struct AVIAMFSubmixLayout {
466 const AVClass *av_class;
467
468 enum AVIAMFSubmixLayoutType layout_type;
469
470 /**
471 * Channel layout matching one of Sound Systems A to J of ITU-2051-3, plus
472 * 7.1.2ch and 3.1.2ch
473 * If layout_type is not AV_IAMF_SUBMIX_LAYOUT_TYPE_LOUDSPEAKERS, this field
474 * is undefined.
475 */
476 AVChannelLayout sound_system;
477 /**
478 * The program integrated loudness information, as defined in
479 * ITU-1770-4.
480 */
481 AVRational integrated_loudness;
482 /**
483 * The digital (sampled) peak value of the audio signal, as defined
484 * in ITU-1770-4.
485 */
486 AVRational digital_peak;
487 /**
488 * The true peak of the audio signal, as defined in ITU-1770-4.
489 */
490 AVRational true_peak;
491 /**
492 * The Dialogue loudness information, as defined in ITU-1770-4.
493 */
494 AVRational dialogue_anchored_loudness;
495 /**
496 * The Album loudness information, as defined in ITU-1770-4.
497 */
498 AVRational album_anchored_loudness;
499} AVIAMFSubmixLayout;
500
501typedef struct AVIAMFSubmix {
502 const AVClass *av_class;
503
504 /**
505 * Array of submix elements.
506 *
507 * Set by av_iamf_submix_add_element(), must not be modified by any
508 * other code.
509 */
510 AVIAMFSubmixElement **elements;
511 /**
512 * Number of elements in the submix.
513 *
514 * Set by av_iamf_submix_add_element(), must not be modified by any
515 * other code.
516 */
517 unsigned int nb_elements;
518
519 /**
520 * Array of submix layouts.
521 *
522 * Set by av_iamf_submix_add_layout(), must not be modified by any
523 * other code.
524 */
525 AVIAMFSubmixLayout **layouts;
526 /**
527 * Number of layouts in the submix.
528 *
529 * Set by av_iamf_submix_add_layout(), must not be modified by any
530 * other code.
531 */
532 unsigned int nb_layouts;
533
534 /**
535 * Information required for post-processing the mixed audio signal to
536 * generate the audio signal for playback.
537 * The @ref AVIAMFParamDefinition.type "type" must be
538 * AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN.
539 */
540 AVIAMFParamDefinition *output_mix_config;
541
542 /**
543 * Default mix gain value to apply when there are no AVIAMFParamDefinition
544 * with @ref output_mix_config "output_mix_config's"
545 * @ref AVIAMFParamDefinition.parameter_id "parameter_id" available for a
546 * given audio frame.
547 */
548 AVRational default_mix_gain;
549} AVIAMFSubmix;
550
551typedef struct AVIAMFMixPresentation {
552 const AVClass *av_class;
553
554 /**
555 * Array of submixes.
556 *
557 * Set by av_iamf_mix_presentation_add_submix(), must not be modified
558 * by any other code.
559 */
560 AVIAMFSubmix **submixes;
561 /**
562 * Number of submixes in the presentation.
563 *
564 * Set by av_iamf_mix_presentation_add_submix(), must not be modified
565 * by any other code.
566 */
567 unsigned int nb_submixes;
568
569 /**
570 * A dictionary of strings describing the mix in different languages.
571 * Must have the same amount of entries as every
572 * @ref AVIAMFSubmixElement.annotations "Submix element annotations",
573 * stored in the same order, and with the same key strings.
574 *
575 * @ref AVDictionaryEntry.key "key" is a string conforming to BCP-47
576 * that specifies the language for the string stored in
577 * @ref AVDictionaryEntry.value "value".
578 */
579 AVDictionary *annotations;
580} AVIAMFMixPresentation;
581
582const AVClass *av_iamf_mix_presentation_get_class(void);
583
584/**
585 * Allocates a AVIAMFMixPresentation, and initializes its fields with default
586 * values. No submixes are allocated.
587 * Must be freed with av_iamf_mix_presentation_free().
588 *
589 * @see av_iamf_mix_presentation_add_submix()
590 */
591AVIAMFMixPresentation *av_iamf_mix_presentation_alloc(void);
592
593/**
594 * Allocate a submix and add it to a given AVIAMFMixPresentation.
595 * It is freed by av_iamf_mix_presentation_free() alongside the rest of the
596 * parent AVIAMFMixPresentation.
597 *
598 * @return a pointer to the allocated submix.
599 */
600AVIAMFSubmix *av_iamf_mix_presentation_add_submix(AVIAMFMixPresentation *mix_presentation);
601
602/**
603 * Allocate a submix element and add it to a given AVIAMFSubmix.
604 * It is freed by av_iamf_mix_presentation_free() alongside the rest of the
605 * parent AVIAMFSubmix.
606 *
607 * @return a pointer to the allocated submix.
608 */
609AVIAMFSubmixElement *av_iamf_submix_add_element(AVIAMFSubmix *submix);
610
611/**
612 * Allocate a submix layout and add it to a given AVIAMFSubmix.
613 * It is freed by av_iamf_mix_presentation_free() alongside the rest of the
614 * parent AVIAMFSubmix.
615 *
616 * @return a pointer to the allocated submix.
617 */
618AVIAMFSubmixLayout *av_iamf_submix_add_layout(AVIAMFSubmix *submix);
619
620void av_iamf_mix_presentation_free(AVIAMFMixPresentation **mix_presentation);
621/**
622 * @}
623 */
624
625#endif /* AVUTIL_IAMF_H */
libavutil/version.h+1−1
@@ -79,7 +79,7 @@ · 78 unmodified lines
79 */79 */
80 80
81#define LIBAVUTIL_VERSION_MAJOR 5881#define LIBAVUTIL_VERSION_MAJOR 58
82#define LIBAVUTIL_VERSION_MINOR 3482#define LIBAVUTIL_VERSION_MINOR 35
83#define LIBAVUTIL_VERSION_MICRO 10083#define LIBAVUTIL_VERSION_MICRO 100
84 84
85#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \85#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t