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
22
33 API changes, most recent first:
44
5+2023-12-18 - xxxxxxxxxxx - lavu 58.35.100 - iamf.h
6+ Add a new API to support Immersive Audio Model and Formats.
7+
58 2023-12-xx - xxxxxxxxxxx - lavu 58.33.100 - imgutils.h
69 Add av_image_fill_color().
710
libavutil/Makefile+2−0
@@ -51,6 +51,7 @@ HEADERS = adler32.h \ · 50 unmodified lines
5151 hwcontext_videotoolbox.h \
5252 hwcontext_vdpau.h \
5353 hwcontext_vulkan.h \
54+ iamf.h \
5455 imgutils.h \
5556 intfloat.h \
5657 intreadwrite.h \
@@ -140,6 +141,7 @@ OBJS = adler32.o \ · 83 unmodified lines
140141 hdr_dynamic_vivid_metadata.o \
141142 hmac.o \
142143 hwcontext.o \
144+ iamf.o \
143145 imgutils.o \
144146 integer.o \
145147 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) \
33+child_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)
66+static 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+
76+static 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)
85+static 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+
91+static 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)
100+static 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+
105+static 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)
114+static 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+
122+static 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+
146+static 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+
154+const AVClass *av_iamf_param_definition_get_class(void)
155+{
156+ return &param_definition_class;
157+}
158+
159+AVIAMFParamDefinition *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)
244+static 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+
275+static 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)
284+static 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+
296+static 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+
309+static 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+
317+const AVClass *av_iamf_audio_element_get_class(void)
318+{
319+ return &audio_element_class;
320+}
321+
322+AVIAMFAudioElement *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+
334+IAMF_ADD_FUNC_TEMPLATE(AVIAMFAudioElement, audio_element, AVIAMFLayer, layer, s)
335+
336+void 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)
361+static 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+
374+static 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+
383+static 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+
396+static 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+
405+IAMF_ADD_FUNC_TEMPLATE(AVIAMFSubmix, submix, AVIAMFSubmixElement, element, s)
406+
407+#undef OFFSET
408+#define OFFSET(x) offsetof(AVIAMFSubmixLayout, x)
409+static 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+
426+static 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+
433+IAMF_ADD_FUNC_TEMPLATE(AVIAMFSubmix, submix, AVIAMFSubmixLayout, layout, s)
434+
435+#undef OFFSET
436+#define OFFSET(x) offsetof(AVIAMFSubmix, x)
437+static 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+
442+static 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+
451+static 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+
475+static 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)
486+static 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+
494+static 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+
507+static 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+
515+const AVClass *av_iamf_mix_presentation_get_class(void)
516+{
517+ return &mix_presentation_class;
518+}
519+
520+AVIAMFMixPresentation *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+
532+IAMF_ADD_FUNC_TEMPLATE(AVIAMFMixPresentation, mix_presentation, AVIAMFSubmix, submix, es)
533+
534+void 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+ */
57+enum 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+ */
66+typedef 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+ */
115+typedef 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+ */
133+typedef 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+
154+enum 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+ */
176+typedef 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+
224+const 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+ */
233+AVIAMFParamDefinition *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+ */
242+static av_always_inline void*
243+av_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+
255+enum 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+ */
274+typedef 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+
324+enum AVIAMFAudioElementType {
325+ AV_IAMF_AUDIO_ELEMENT_TYPE_CHANNEL,
326+ AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE,
327+};
328+
329+typedef 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+
369+const 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+ */
377+AVIAMFAudioElement *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+ */
386+AVIAMFLayer *av_iamf_audio_element_add_layer(AVIAMFAudioElement *audio_element);
387+
388+void av_iamf_audio_element_free(AVIAMFAudioElement **audio_element);
389+
390+/**
391+ * @}
392+ * @addtogroup lavf_iamf_mix
393+ * @{
394+ */
395+
396+enum 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+
407+typedef 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+
454+enum 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+
465+typedef 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+
501+typedef 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+
551+typedef 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+
582+const 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+ */
591+AVIAMFMixPresentation *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+ */
600+AVIAMFSubmix *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+ */
609+AVIAMFSubmixElement *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+ */
618+AVIAMFSubmixLayout *av_iamf_submix_add_layout(AVIAMFSubmix *submix);
619+
620+void 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
7979 */
8080
8181 #define LIBAVUTIL_VERSION_MAJOR 58
82−#define LIBAVUTIL_VERSION_MINOR 34
82+#define LIBAVUTIL_VERSION_MINOR 35
8383 #define LIBAVUTIL_VERSION_MICRO 100
8484
8585 #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