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