Unified · Split
| @@ -2,6 +2,9 @@ The last version increases of all libraries were on 2023-02-09 · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | API changes, most recent first: |
| 4 | 4 | |
| 5 | +2023-12-18 - xxxxxxxxxxx - lavu 58.35.100 - iamf.h | |
| 6 | + Add a new API to support Immersive Audio Model and Formats. | |
| 7 | + | |
| 5 | 8 | 2023-12-xx - xxxxxxxxxxx - lavu 58.33.100 - imgutils.h |
| 6 | 9 | Add av_image_fill_color(). |
| 7 | 10 | |
| @@ -51,6 +51,7 @@ HEADERS = adler32.h \ · 50 unmodified lines | ||
| 51 | 51 | hwcontext_videotoolbox.h \ |
| 52 | 52 | hwcontext_vdpau.h \ |
| 53 | 53 | hwcontext_vulkan.h \ |
| 54 | + iamf.h \ | |
| 54 | 55 | imgutils.h \ |
| 55 | 56 | intfloat.h \ |
| 56 | 57 | intreadwrite.h \ |
| @@ -140,6 +141,7 @@ OBJS = adler32.o \ · 83 unmodified lines | ||
| 140 | 141 | hdr_dynamic_vivid_metadata.o \ |
| 141 | 142 | hmac.o \ |
| 142 | 143 | hwcontext.o \ |
| 144 | + iamf.o \ | |
| 143 | 145 | imgutils.o \ |
| 144 | 146 | integer.o \ |
| 145 | 147 | intmath.o \ |
| @@ -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 ¶m_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 = ¶m_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 = ¶m_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 = ¶m_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 | +} | |
| @@ -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 */ | |
| @@ -79,7 +79,7 @@ · 78 unmodified lines | ||
| 79 | 79 | */ |
| 80 | 80 | |
| 81 | 81 | #define LIBAVUTIL_VERSION_MAJOR 58 |
| 82 | −#define LIBAVUTIL_VERSION_MINOR 34 | |
| 82 | +#define LIBAVUTIL_VERSION_MINOR 35 | |
| 83 | 83 | #define LIBAVUTIL_VERSION_MICRO 100 |
| 84 | 84 | |
| 85 | 85 | #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ |