channel_layout.c (35054B)
1 /* 2 * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> 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 /** 22 * @file 23 * audio channel layout utility functions 24 */ 25 26 #include <stdint.h> 27 #include <stdlib.h> 28 #include <string.h> 29 30 #include "avassert.h" 31 #include "channel_layout.h" 32 #include "bprint.h" 33 #include "common.h" 34 #include "error.h" 35 #include "macros.h" 36 #include "mem.h" 37 #include "opt.h" 38 39 #define CHAN_IS_AMBI(x) ((x) >= AV_CHAN_AMBISONIC_BASE &&\ 40 (x) <= AV_CHAN_AMBISONIC_END) 41 42 struct channel_name { 43 const char *name; 44 const char *description; 45 }; 46 47 static const struct channel_name channel_names[] = { 48 [AV_CHAN_FRONT_LEFT ] = { "FL", "front left" }, 49 [AV_CHAN_FRONT_RIGHT ] = { "FR", "front right" }, 50 [AV_CHAN_FRONT_CENTER ] = { "FC", "front center" }, 51 [AV_CHAN_LOW_FREQUENCY ] = { "LFE", "low frequency" }, 52 [AV_CHAN_BACK_LEFT ] = { "BL", "back left" }, 53 [AV_CHAN_BACK_RIGHT ] = { "BR", "back right" }, 54 [AV_CHAN_FRONT_LEFT_OF_CENTER ] = { "FLC", "front left-of-center" }, 55 [AV_CHAN_FRONT_RIGHT_OF_CENTER] = { "FRC", "front right-of-center" }, 56 [AV_CHAN_BACK_CENTER ] = { "BC", "back center" }, 57 [AV_CHAN_SIDE_LEFT ] = { "SL", "side left" }, 58 [AV_CHAN_SIDE_RIGHT ] = { "SR", "side right" }, 59 [AV_CHAN_TOP_CENTER ] = { "TC", "top center" }, 60 [AV_CHAN_TOP_FRONT_LEFT ] = { "TFL", "top front left" }, 61 [AV_CHAN_TOP_FRONT_CENTER ] = { "TFC", "top front center" }, 62 [AV_CHAN_TOP_FRONT_RIGHT ] = { "TFR", "top front right" }, 63 [AV_CHAN_TOP_BACK_LEFT ] = { "TBL", "top back left" }, 64 [AV_CHAN_TOP_BACK_CENTER ] = { "TBC", "top back center" }, 65 [AV_CHAN_TOP_BACK_RIGHT ] = { "TBR", "top back right" }, 66 [AV_CHAN_STEREO_LEFT ] = { "DL", "downmix left" }, 67 [AV_CHAN_STEREO_RIGHT ] = { "DR", "downmix right" }, 68 [AV_CHAN_WIDE_LEFT ] = { "WL", "wide left" }, 69 [AV_CHAN_WIDE_RIGHT ] = { "WR", "wide right" }, 70 [AV_CHAN_SURROUND_DIRECT_LEFT ] = { "SDL", "surround direct left" }, 71 [AV_CHAN_SURROUND_DIRECT_RIGHT] = { "SDR", "surround direct right" }, 72 [AV_CHAN_LOW_FREQUENCY_2 ] = { "LFE2", "low frequency 2" }, 73 [AV_CHAN_TOP_SIDE_LEFT ] = { "TSL", "top side left" }, 74 [AV_CHAN_TOP_SIDE_RIGHT ] = { "TSR", "top side right" }, 75 [AV_CHAN_BOTTOM_FRONT_CENTER ] = { "BFC", "bottom front center" }, 76 [AV_CHAN_BOTTOM_FRONT_LEFT ] = { "BFL", "bottom front left" }, 77 [AV_CHAN_BOTTOM_FRONT_RIGHT ] = { "BFR", "bottom front right" }, 78 [AV_CHAN_SIDE_SURROUND_LEFT ] = { "SSL", "side surround left" }, 79 [AV_CHAN_SIDE_SURROUND_RIGHT ] = { "SSR", "side surround right" }, 80 [AV_CHAN_TOP_SURROUND_LEFT ] = { "TTL", "top surround left" }, 81 [AV_CHAN_TOP_SURROUND_RIGHT ] = { "TTR", "top surround right" }, 82 [AV_CHAN_BINAURAL_LEFT ] = { "BIL", "binaural left" }, 83 [AV_CHAN_BINAURAL_RIGHT ] = { "BIR", "binaural right" }, 84 }; 85 86 void av_channel_name_bprint(AVBPrint *bp, enum AVChannel channel_id) 87 { 88 if (channel_id >= AV_CHAN_AMBISONIC_BASE && 89 channel_id <= AV_CHAN_AMBISONIC_END) 90 av_bprintf(bp, "AMBI%d", channel_id - AV_CHAN_AMBISONIC_BASE); 91 else if ((unsigned)channel_id < FF_ARRAY_ELEMS(channel_names) && 92 channel_names[channel_id].name) 93 av_bprintf(bp, "%s", channel_names[channel_id].name); 94 else if (channel_id == AV_CHAN_NONE) 95 av_bprintf(bp, "NONE"); 96 else if (channel_id == AV_CHAN_UNKNOWN) 97 av_bprintf(bp, "UNK"); 98 else if (channel_id == AV_CHAN_UNUSED) 99 av_bprintf(bp, "UNSD"); 100 else 101 av_bprintf(bp, "USR%d", channel_id); 102 } 103 104 int av_channel_name(char *buf, size_t buf_size, enum AVChannel channel_id) 105 { 106 AVBPrint bp; 107 108 if (!buf && buf_size) 109 return AVERROR(EINVAL); 110 111 av_bprint_init_for_buffer(&bp, buf, buf_size); 112 av_channel_name_bprint(&bp, channel_id); 113 114 if (bp.len >= INT_MAX) 115 return AVERROR(ERANGE); 116 return bp.len + 1; 117 } 118 119 void av_channel_description_bprint(AVBPrint *bp, enum AVChannel channel_id) 120 { 121 if (channel_id >= AV_CHAN_AMBISONIC_BASE && 122 channel_id <= AV_CHAN_AMBISONIC_END) 123 av_bprintf(bp, "ambisonic ACN %d", channel_id - AV_CHAN_AMBISONIC_BASE); 124 else if ((unsigned)channel_id < FF_ARRAY_ELEMS(channel_names) && 125 channel_names[channel_id].description) 126 av_bprintf(bp, "%s", channel_names[channel_id].description); 127 else if (channel_id == AV_CHAN_NONE) 128 av_bprintf(bp, "none"); 129 else if (channel_id == AV_CHAN_UNKNOWN) 130 av_bprintf(bp, "unknown"); 131 else if (channel_id == AV_CHAN_UNUSED) 132 av_bprintf(bp, "unused"); 133 else 134 av_bprintf(bp, "user %d", channel_id); 135 } 136 137 int av_channel_description(char *buf, size_t buf_size, enum AVChannel channel_id) 138 { 139 AVBPrint bp; 140 141 if (!buf && buf_size) 142 return AVERROR(EINVAL); 143 144 av_bprint_init_for_buffer(&bp, buf, buf_size); 145 av_channel_description_bprint(&bp, channel_id); 146 147 if (bp.len >= INT_MAX) 148 return AVERROR(ERANGE); 149 return bp.len + 1; 150 } 151 152 enum AVChannel av_channel_from_string(const char *str) 153 { 154 int i; 155 char *endptr = (char *)str; 156 enum AVChannel id = AV_CHAN_NONE; 157 158 if (!strncmp(str, "AMBI", 4)) { 159 i = strtol(str + 4, NULL, 0); 160 if (i < 0 || i > AV_CHAN_AMBISONIC_END - AV_CHAN_AMBISONIC_BASE) 161 return AV_CHAN_NONE; 162 return AV_CHAN_AMBISONIC_BASE + i; 163 } 164 165 for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++) { 166 if (channel_names[i].name && !strcmp(str, channel_names[i].name)) 167 return i; 168 } 169 if (!strcmp(str, "UNK")) 170 return AV_CHAN_UNKNOWN; 171 if (!strcmp(str, "UNSD")) 172 return AV_CHAN_UNUSED; 173 174 if (!strncmp(str, "USR", 3)) { 175 const char *p = str + 3; 176 id = strtol(p, &endptr, 0); 177 } 178 if (id >= 0 && !*endptr) 179 return id; 180 181 return AV_CHAN_NONE; 182 } 183 184 struct channel_layout_name { 185 const char *name; 186 AVChannelLayout layout; 187 }; 188 189 static const struct channel_layout_name channel_layout_map[] = { 190 { "mono", AV_CHANNEL_LAYOUT_MONO }, 191 { "stereo", AV_CHANNEL_LAYOUT_STEREO }, 192 { "2.1", AV_CHANNEL_LAYOUT_2POINT1 }, 193 { "3.0", AV_CHANNEL_LAYOUT_SURROUND }, 194 { "3.0(back)", AV_CHANNEL_LAYOUT_2_1 }, 195 { "4.0", AV_CHANNEL_LAYOUT_4POINT0 }, 196 { "quad", AV_CHANNEL_LAYOUT_QUAD }, 197 { "quad(side)", AV_CHANNEL_LAYOUT_2_2 }, 198 { "3.1", AV_CHANNEL_LAYOUT_3POINT1 }, 199 { "5.0", AV_CHANNEL_LAYOUT_5POINT0_BACK }, 200 { "5.0(side)", AV_CHANNEL_LAYOUT_5POINT0 }, 201 { "4.1", AV_CHANNEL_LAYOUT_4POINT1 }, 202 { "5.1", AV_CHANNEL_LAYOUT_5POINT1_BACK }, 203 { "5.1(side)", AV_CHANNEL_LAYOUT_5POINT1 }, 204 { "6.0", AV_CHANNEL_LAYOUT_6POINT0 }, 205 { "6.0(front)", AV_CHANNEL_LAYOUT_6POINT0_FRONT }, 206 { "3.1.2", AV_CHANNEL_LAYOUT_3POINT1POINT2 }, 207 { "hexagonal", AV_CHANNEL_LAYOUT_HEXAGONAL }, 208 { "6.1", AV_CHANNEL_LAYOUT_6POINT1 }, 209 { "6.1(back)", AV_CHANNEL_LAYOUT_6POINT1_BACK }, 210 { "6.1(front)", AV_CHANNEL_LAYOUT_6POINT1_FRONT }, 211 { "7.0", AV_CHANNEL_LAYOUT_7POINT0 }, 212 { "7.0(front)", AV_CHANNEL_LAYOUT_7POINT0_FRONT }, 213 { "7.1", AV_CHANNEL_LAYOUT_7POINT1 }, 214 { "7.1(wide)", AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK }, 215 { "7.1(wide-side)", AV_CHANNEL_LAYOUT_7POINT1_WIDE }, 216 { "5.1.2", AV_CHANNEL_LAYOUT_5POINT1POINT2 }, 217 { "5.1.2(back)", AV_CHANNEL_LAYOUT_5POINT1POINT2_BACK }, 218 { "octagonal", AV_CHANNEL_LAYOUT_OCTAGONAL }, 219 { "cube", AV_CHANNEL_LAYOUT_CUBE }, 220 { "5.1.4", AV_CHANNEL_LAYOUT_5POINT1POINT4_BACK }, 221 { "7.1.2", AV_CHANNEL_LAYOUT_7POINT1POINT2 }, 222 { "7.1.4", AV_CHANNEL_LAYOUT_7POINT1POINT4_BACK }, 223 { "7.2.3", AV_CHANNEL_LAYOUT_7POINT2POINT3 }, 224 { "9.1.4", AV_CHANNEL_LAYOUT_9POINT1POINT4_BACK }, 225 { "9.1.6", AV_CHANNEL_LAYOUT_9POINT1POINT6 }, 226 { "hexadecagonal", AV_CHANNEL_LAYOUT_HEXADECAGONAL }, 227 { "binaural", AV_CHANNEL_LAYOUT_BINAURAL }, 228 { "downmix", AV_CHANNEL_LAYOUT_STEREO_DOWNMIX, }, 229 { "22.2", AV_CHANNEL_LAYOUT_22POINT2, }, 230 }; 231 232 int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels) 233 { 234 AVChannelCustom *map; 235 236 if (nb_channels <= 0) 237 return AVERROR(EINVAL); 238 239 map = av_calloc(nb_channels, sizeof(*channel_layout->u.map)); 240 if (!map) 241 return AVERROR(ENOMEM); 242 for (int i = 0; i < nb_channels; i++) 243 map[i].id = AV_CHAN_UNKNOWN; 244 245 channel_layout->order = AV_CHANNEL_ORDER_CUSTOM; 246 channel_layout->nb_channels = nb_channels; 247 channel_layout->u.map = map; 248 249 return 0; 250 } 251 252 int av_channel_layout_from_mask(AVChannelLayout *channel_layout, 253 uint64_t mask) 254 { 255 if (!mask) 256 return AVERROR(EINVAL); 257 258 channel_layout->order = AV_CHANNEL_ORDER_NATIVE; 259 channel_layout->nb_channels = av_popcount64(mask); 260 channel_layout->u.mask = mask; 261 262 return 0; 263 } 264 265 static int parse_channel_list(AVChannelLayout *ch_layout, const char *str) 266 { 267 int ret; 268 int nb_channels = 0; 269 AVChannelCustom *map = NULL; 270 AVChannelCustom custom = {0}; 271 272 while (*str) { 273 char *channel, *chname; 274 int ret = av_opt_get_key_value(&str, "@", "+", AV_OPT_FLAG_IMPLICIT_KEY, &channel, &chname); 275 if (ret < 0) { 276 av_freep(&map); 277 return ret; 278 } 279 if (*str) 280 str++; // skip separator 281 if (!channel) { 282 channel = chname; 283 chname = NULL; 284 } 285 av_strlcpy(custom.name, chname ? chname : "", sizeof(custom.name)); 286 custom.id = av_channel_from_string(channel); 287 av_free(channel); 288 av_free(chname); 289 if (custom.id == AV_CHAN_NONE) { 290 av_freep(&map); 291 return AVERROR(EINVAL); 292 } 293 294 av_dynarray2_add((void **)&map, &nb_channels, sizeof(custom), (void *)&custom); 295 if (!map) 296 return AVERROR(ENOMEM); 297 } 298 299 if (!nb_channels) 300 return AVERROR(EINVAL); 301 302 ch_layout->order = AV_CHANNEL_ORDER_CUSTOM; 303 ch_layout->u.map = map; 304 ch_layout->nb_channels = nb_channels; 305 306 ret = av_channel_layout_retype(ch_layout, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL); 307 av_assert0(ret == 0); 308 309 return 0; 310 } 311 312 int av_channel_layout_from_string(AVChannelLayout *channel_layout, 313 const char *str) 314 { 315 int i, matches, ret; 316 int channels = 0, nb_channels = 0; 317 char *chlist, *end; 318 uint64_t mask = 0; 319 320 /* channel layout names */ 321 for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) { 322 if (channel_layout_map[i].name && !strcmp(str, channel_layout_map[i].name)) { 323 *channel_layout = channel_layout_map[i].layout; 324 return 0; 325 } 326 } 327 328 /* This function is a channel layout initializer, so we have to 329 * zero-initialize before we start setting fields individually. */ 330 memset(channel_layout, 0, sizeof(*channel_layout)); 331 332 /* ambisonic */ 333 if (!strncmp(str, "ambisonic ", 10)) { 334 const char *p = str + 10; 335 char *endptr; 336 AVChannelLayout extra = {0}; 337 int order; 338 339 order = strtol(p, &endptr, 0); 340 if (order < 0 || order + 1 > INT_MAX / (order + 1) || 341 (*endptr && *endptr != '+')) 342 return AVERROR(EINVAL); 343 344 channel_layout->order = AV_CHANNEL_ORDER_AMBISONIC; 345 channel_layout->nb_channels = (order + 1) * (order + 1); 346 347 if (*endptr) { 348 int ret = av_channel_layout_from_string(&extra, endptr + 1); 349 if (ret < 0) 350 return ret; 351 if (extra.nb_channels >= INT_MAX - channel_layout->nb_channels) { 352 av_channel_layout_uninit(&extra); 353 return AVERROR(EINVAL); 354 } 355 356 if (extra.order == AV_CHANNEL_ORDER_NATIVE) { 357 channel_layout->u.mask = extra.u.mask; 358 } else { 359 channel_layout->order = AV_CHANNEL_ORDER_CUSTOM; 360 channel_layout->u.map = 361 av_calloc(channel_layout->nb_channels + extra.nb_channels, 362 sizeof(*channel_layout->u.map)); 363 if (!channel_layout->u.map) { 364 av_channel_layout_uninit(&extra); 365 return AVERROR(ENOMEM); 366 } 367 368 for (i = 0; i < channel_layout->nb_channels; i++) 369 channel_layout->u.map[i].id = AV_CHAN_AMBISONIC_BASE + i; 370 for (i = 0; i < extra.nb_channels; i++) { 371 enum AVChannel ch = av_channel_layout_channel_from_index(&extra, i); 372 if (CHAN_IS_AMBI(ch)) { 373 av_channel_layout_uninit(channel_layout); 374 av_channel_layout_uninit(&extra); 375 return AVERROR(EINVAL); 376 } 377 channel_layout->u.map[channel_layout->nb_channels + i].id = ch; 378 if (extra.order == AV_CHANNEL_ORDER_CUSTOM && 379 extra.u.map[i].name[0]) 380 av_strlcpy(channel_layout->u.map[channel_layout->nb_channels + i].name, 381 extra.u.map[i].name, 382 sizeof(channel_layout->u.map[channel_layout->nb_channels + i].name)); 383 } 384 } 385 channel_layout->nb_channels += extra.nb_channels; 386 av_channel_layout_uninit(&extra); 387 } 388 389 return 0; 390 } 391 392 chlist = av_strdup(str); 393 if (!chlist) 394 return AVERROR(ENOMEM); 395 396 /* channel names */ 397 matches = av_sscanf(str, "%d channels (%[^)]", &nb_channels, chlist); 398 ret = parse_channel_list(channel_layout, chlist); 399 av_freep(&chlist); 400 if (ret < 0 && ret != AVERROR(EINVAL)) 401 return ret; 402 403 if (ret >= 0) { 404 end = strchr(str, ')'); 405 if (matches == 2 && (nb_channels != channel_layout->nb_channels || !end || *++end)) { 406 av_channel_layout_uninit(channel_layout); 407 return AVERROR(EINVAL); 408 } 409 return 0; 410 } 411 412 errno = 0; 413 mask = strtoull(str, &end, 0); 414 415 /* channel layout mask */ 416 if (!errno && !*end && !strchr(str, '-') && mask) { 417 av_channel_layout_from_mask(channel_layout, mask); 418 return 0; 419 } 420 421 errno = 0; 422 channels = strtol(str, &end, 10); 423 424 /* number of channels */ 425 if (!errno && !strcmp(end, "c") && channels > 0) { 426 av_channel_layout_default(channel_layout, channels); 427 if (channel_layout->order == AV_CHANNEL_ORDER_NATIVE) 428 return 0; 429 } 430 431 /* number of unordered channels */ 432 if (!errno && (!strcmp(end, "C") || !strcmp(end, " channels")) 433 && channels > 0) { 434 channel_layout->order = AV_CHANNEL_ORDER_UNSPEC; 435 channel_layout->nb_channels = channels; 436 return 0; 437 } 438 439 return AVERROR(EINVAL); 440 } 441 442 void av_channel_layout_uninit(AVChannelLayout *channel_layout) 443 { 444 if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) 445 av_freep(&channel_layout->u.map); 446 memset(channel_layout, 0, sizeof(*channel_layout)); 447 } 448 449 int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src) 450 { 451 av_channel_layout_uninit(dst); 452 *dst = *src; 453 if (src->order == AV_CHANNEL_ORDER_CUSTOM) { 454 dst->u.map = av_malloc_array(src->nb_channels, sizeof(*dst->u.map)); 455 if (!dst->u.map) 456 return AVERROR(ENOMEM); 457 memcpy(dst->u.map, src->u.map, src->nb_channels * sizeof(*src->u.map)); 458 } 459 return 0; 460 } 461 462 static int64_t masked_description(const AVChannelLayout *channel_layout, int start_channel) 463 { 464 uint64_t mask = 0; 465 for (int i = start_channel; i < channel_layout->nb_channels; i++) { 466 enum AVChannel ch = channel_layout->u.map[i].id; 467 if (ch >= 0 && ch < 63 && mask < (1ULL << ch)) 468 mask |= (1ULL << ch); 469 else 470 return AVERROR(EINVAL); 471 } 472 return mask; 473 } 474 475 static int has_channel_names(const AVChannelLayout *channel_layout) 476 { 477 if (channel_layout->order != AV_CHANNEL_ORDER_CUSTOM) 478 return 0; 479 for (int i = 0; i < channel_layout->nb_channels; i++) 480 if (channel_layout->u.map[i].name[0]) 481 return 1; 482 return 0; 483 } 484 485 int av_channel_layout_ambisonic_order(const AVChannelLayout *channel_layout) 486 { 487 int i, highest_ambi, order; 488 489 if (channel_layout->order != AV_CHANNEL_ORDER_AMBISONIC && 490 channel_layout->order != AV_CHANNEL_ORDER_CUSTOM) 491 return AVERROR(EINVAL); 492 493 highest_ambi = -1; 494 if (channel_layout->order == AV_CHANNEL_ORDER_AMBISONIC) 495 highest_ambi = channel_layout->nb_channels - av_popcount64(channel_layout->u.mask) - 1; 496 else { 497 const AVChannelCustom *map = channel_layout->u.map; 498 av_assert0(channel_layout->order == AV_CHANNEL_ORDER_CUSTOM); 499 500 for (i = 0; i < channel_layout->nb_channels; i++) { 501 int is_ambi = CHAN_IS_AMBI(map[i].id); 502 503 /* ambisonic following non-ambisonic */ 504 if (i > 0 && is_ambi && !CHAN_IS_AMBI(map[i - 1].id)) 505 return AVERROR(EINVAL); 506 507 /* non-default ordering */ 508 if (is_ambi && map[i].id - AV_CHAN_AMBISONIC_BASE != i) 509 return AVERROR(EINVAL); 510 511 if (CHAN_IS_AMBI(map[i].id)) 512 highest_ambi = i; 513 } 514 } 515 /* no ambisonic channels*/ 516 if (highest_ambi < 0) 517 return AVERROR(EINVAL); 518 519 order = floor(sqrt(highest_ambi)); 520 /* incomplete order - some harmonics are missing */ 521 if ((order + 1) * (order + 1) != highest_ambi + 1) 522 return AVERROR(EINVAL); 523 524 return order; 525 } 526 527 static enum AVChannelOrder canonical_order(AVChannelLayout *channel_layout) 528 { 529 int has_known_channel = 0; 530 int order; 531 532 if (channel_layout->order != AV_CHANNEL_ORDER_CUSTOM) 533 return channel_layout->order; 534 535 if (has_channel_names(channel_layout)) 536 return AV_CHANNEL_ORDER_CUSTOM; 537 538 for (int i = 0; i < channel_layout->nb_channels && !has_known_channel; i++) 539 if (channel_layout->u.map[i].id != AV_CHAN_UNKNOWN) 540 has_known_channel = 1; 541 if (!has_known_channel) 542 return AV_CHANNEL_ORDER_UNSPEC; 543 544 if (masked_description(channel_layout, 0) > 0) 545 return AV_CHANNEL_ORDER_NATIVE; 546 547 order = av_channel_layout_ambisonic_order(channel_layout); 548 if (order >= 0 && masked_description(channel_layout, (order + 1) * (order + 1)) >= 0) 549 return AV_CHANNEL_ORDER_AMBISONIC; 550 551 return AV_CHANNEL_ORDER_CUSTOM; 552 } 553 554 /** 555 * If the custom layout is n-th order standard-order ambisonic, with optional 556 * extra non-diegetic channels at the end, write its string description in bp. 557 * Return a negative error code otherwise. 558 */ 559 static int try_describe_ambisonic(AVBPrint *bp, const AVChannelLayout *channel_layout) 560 { 561 int nb_ambi_channels; 562 int order = av_channel_layout_ambisonic_order(channel_layout); 563 if (order < 0) 564 return order; 565 566 av_bprintf(bp, "ambisonic %d", order); 567 568 /* extra channels present */ 569 nb_ambi_channels = (order + 1) * (order + 1); 570 if (nb_ambi_channels < channel_layout->nb_channels) { 571 AVChannelLayout extra = { 0 }; 572 573 if (channel_layout->order == AV_CHANNEL_ORDER_AMBISONIC) { 574 extra.order = AV_CHANNEL_ORDER_NATIVE; 575 extra.nb_channels = av_popcount64(channel_layout->u.mask); 576 extra.u.mask = channel_layout->u.mask; 577 } else { 578 int64_t mask; 579 if (!has_channel_names(channel_layout) && 580 (mask = masked_description(channel_layout, nb_ambi_channels)) > 0) { 581 extra.order = AV_CHANNEL_ORDER_NATIVE; 582 extra.nb_channels = av_popcount64(mask); 583 extra.u.mask = mask; 584 } else { 585 extra.order = AV_CHANNEL_ORDER_CUSTOM; 586 extra.nb_channels = channel_layout->nb_channels - nb_ambi_channels; 587 extra.u.map = channel_layout->u.map + nb_ambi_channels; 588 } 589 } 590 591 av_bprint_chars(bp, '+', 1); 592 av_channel_layout_describe_bprint(&extra, bp); 593 /* Not calling uninit here on extra because we don't own the u.map pointer */ 594 } 595 596 return 0; 597 } 598 599 int av_channel_layout_describe_bprint(const AVChannelLayout *channel_layout, 600 AVBPrint *bp) 601 { 602 int i; 603 604 switch (channel_layout->order) { 605 case AV_CHANNEL_ORDER_NATIVE: 606 for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) 607 if (channel_layout->u.mask == channel_layout_map[i].layout.u.mask) { 608 av_bprintf(bp, "%s", channel_layout_map[i].name); 609 return 0; 610 } 611 // fall-through 612 case AV_CHANNEL_ORDER_CUSTOM: 613 if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) { 614 int64_t mask; 615 int res = try_describe_ambisonic(bp, channel_layout); 616 if (res >= 0) 617 return 0; 618 if (!has_channel_names(channel_layout) && 619 (mask = masked_description(channel_layout, 0)) > 0) { 620 AVChannelLayout native = { .order = AV_CHANNEL_ORDER_NATIVE, 621 .nb_channels = av_popcount64(mask), 622 .u.mask = mask }; 623 return av_channel_layout_describe_bprint(&native, bp); 624 } 625 } 626 if (channel_layout->nb_channels) 627 av_bprintf(bp, "%d channels (", channel_layout->nb_channels); 628 for (i = 0; i < channel_layout->nb_channels; i++) { 629 enum AVChannel ch = av_channel_layout_channel_from_index(channel_layout, i); 630 631 if (i) 632 av_bprintf(bp, "+"); 633 av_channel_name_bprint(bp, ch); 634 if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM && 635 channel_layout->u.map[i].name[0]) 636 av_bprintf(bp, "@%s", channel_layout->u.map[i].name); 637 } 638 if (channel_layout->nb_channels) { 639 av_bprintf(bp, ")"); 640 return 0; 641 } 642 // fall-through 643 case AV_CHANNEL_ORDER_UNSPEC: 644 av_bprintf(bp, "%d channels", channel_layout->nb_channels); 645 return 0; 646 case AV_CHANNEL_ORDER_AMBISONIC: 647 return try_describe_ambisonic(bp, channel_layout); 648 default: 649 return AVERROR(EINVAL); 650 } 651 } 652 653 int av_channel_layout_describe(const AVChannelLayout *channel_layout, 654 char *buf, size_t buf_size) 655 { 656 AVBPrint bp; 657 int ret; 658 659 if (!buf && buf_size) 660 return AVERROR(EINVAL); 661 662 av_bprint_init_for_buffer(&bp, buf, buf_size); 663 ret = av_channel_layout_describe_bprint(channel_layout, &bp); 664 if (ret < 0) 665 return ret; 666 667 if (bp.len >= INT_MAX) 668 return AVERROR(ERANGE); 669 return bp.len + 1; 670 } 671 672 enum AVChannel 673 av_channel_layout_channel_from_index(const AVChannelLayout *channel_layout, 674 unsigned int idx) 675 { 676 int i; 677 678 if (idx >= channel_layout->nb_channels) 679 return AV_CHAN_NONE; 680 681 switch (channel_layout->order) { 682 case AV_CHANNEL_ORDER_CUSTOM: 683 return channel_layout->u.map[idx].id; 684 case AV_CHANNEL_ORDER_AMBISONIC: { 685 int ambi_channels = channel_layout->nb_channels - av_popcount64(channel_layout->u.mask); 686 if (idx < ambi_channels) 687 return AV_CHAN_AMBISONIC_BASE + idx; 688 idx -= ambi_channels; 689 } 690 // fall-through 691 case AV_CHANNEL_ORDER_NATIVE: 692 for (i = 0; i < 64; i++) { 693 if ((1ULL << i) & channel_layout->u.mask && !idx--) 694 return i; 695 } 696 default: 697 return AV_CHAN_NONE; 698 } 699 } 700 701 enum AVChannel 702 av_channel_layout_channel_from_string(const AVChannelLayout *channel_layout, 703 const char *str) 704 { 705 int index = av_channel_layout_index_from_string(channel_layout, str); 706 707 if (index < 0) 708 return AV_CHAN_NONE; 709 710 return av_channel_layout_channel_from_index(channel_layout, index); 711 } 712 713 int av_channel_layout_index_from_channel(const AVChannelLayout *channel_layout, 714 enum AVChannel channel) 715 { 716 int i; 717 718 if (channel == AV_CHAN_NONE) 719 return AVERROR(EINVAL); 720 721 switch (channel_layout->order) { 722 case AV_CHANNEL_ORDER_CUSTOM: 723 for (i = 0; i < channel_layout->nb_channels; i++) 724 if (channel_layout->u.map[i].id == channel) 725 return i; 726 return AVERROR(EINVAL); 727 case AV_CHANNEL_ORDER_AMBISONIC: 728 case AV_CHANNEL_ORDER_NATIVE: { 729 uint64_t mask = channel_layout->u.mask; 730 int ambi_channels = channel_layout->nb_channels - av_popcount64(mask); 731 if (channel_layout->order == AV_CHANNEL_ORDER_AMBISONIC && 732 channel >= AV_CHAN_AMBISONIC_BASE) { 733 if (channel - AV_CHAN_AMBISONIC_BASE >= ambi_channels) 734 return AVERROR(EINVAL); 735 return channel - AV_CHAN_AMBISONIC_BASE; 736 } 737 if ((unsigned)channel > 63 || !(mask & (1ULL << channel))) 738 return AVERROR(EINVAL); 739 mask &= (1ULL << channel) - 1; 740 return av_popcount64(mask) + ambi_channels; 741 } 742 default: 743 return AVERROR(EINVAL); 744 } 745 } 746 747 int av_channel_layout_index_from_string(const AVChannelLayout *channel_layout, 748 const char *str) 749 { 750 char *chname; 751 enum AVChannel ch = AV_CHAN_NONE; 752 753 switch (channel_layout->order) { 754 case AV_CHANNEL_ORDER_CUSTOM: 755 chname = strstr(str, "@"); 756 if (chname) { 757 char buf[16]; 758 chname++; 759 av_strlcpy(buf, str, FFMIN(sizeof(buf), chname - str)); 760 if (!*chname) 761 chname = NULL; 762 ch = av_channel_from_string(buf); 763 if (ch == AV_CHAN_NONE && *buf) 764 return AVERROR(EINVAL); 765 } 766 for (int i = 0; chname && i < channel_layout->nb_channels; i++) { 767 if (!strcmp(chname, channel_layout->u.map[i].name) && 768 (ch == AV_CHAN_NONE || ch == channel_layout->u.map[i].id)) 769 return i; 770 } 771 // fall-through 772 case AV_CHANNEL_ORDER_AMBISONIC: 773 case AV_CHANNEL_ORDER_NATIVE: 774 ch = av_channel_from_string(str); 775 if (ch == AV_CHAN_NONE) 776 return AVERROR(EINVAL); 777 return av_channel_layout_index_from_channel(channel_layout, ch); 778 } 779 780 return AVERROR(EINVAL); 781 } 782 783 int av_channel_layout_check(const AVChannelLayout *channel_layout) 784 { 785 if (channel_layout->nb_channels <= 0) 786 return 0; 787 788 switch (channel_layout->order) { 789 case AV_CHANNEL_ORDER_NATIVE: 790 return av_popcount64(channel_layout->u.mask) == channel_layout->nb_channels; 791 case AV_CHANNEL_ORDER_CUSTOM: 792 if (!channel_layout->u.map) 793 return 0; 794 for (int i = 0; i < channel_layout->nb_channels; i++) { 795 if (channel_layout->u.map[i].id == AV_CHAN_NONE) 796 return 0; 797 } 798 return 1; 799 case AV_CHANNEL_ORDER_AMBISONIC: 800 /* If non-diegetic channels are present, ensure they are taken into account */ 801 return av_popcount64(channel_layout->u.mask) < channel_layout->nb_channels; 802 case AV_CHANNEL_ORDER_UNSPEC: 803 return 1; 804 default: 805 return 0; 806 } 807 } 808 809 int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout *chl1) 810 { 811 int i; 812 813 /* different channel counts -> not equal */ 814 if (chl->nb_channels != chl1->nb_channels) 815 return 1; 816 817 /* if only one is unspecified -> not equal */ 818 if ((chl->order == AV_CHANNEL_ORDER_UNSPEC) != 819 (chl1->order == AV_CHANNEL_ORDER_UNSPEC)) 820 return 1; 821 /* both are unspecified -> equal */ 822 else if (chl->order == AV_CHANNEL_ORDER_UNSPEC) 823 return 0; 824 825 /* can compare masks directly */ 826 if ((chl->order == AV_CHANNEL_ORDER_NATIVE || 827 chl->order == AV_CHANNEL_ORDER_AMBISONIC) && 828 chl->order == chl1->order) 829 return chl->u.mask != chl1->u.mask; 830 831 /* compare channel by channel */ 832 for (i = 0; i < chl->nb_channels; i++) 833 if (av_channel_layout_channel_from_index(chl, i) != 834 av_channel_layout_channel_from_index(chl1, i)) 835 return 1; 836 return 0; 837 } 838 839 void av_channel_layout_default(AVChannelLayout *ch_layout, int nb_channels) 840 { 841 int i; 842 for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) 843 if (nb_channels == channel_layout_map[i].layout.nb_channels) { 844 *ch_layout = channel_layout_map[i].layout; 845 return; 846 } 847 848 ch_layout->order = AV_CHANNEL_ORDER_UNSPEC; 849 ch_layout->nb_channels = nb_channels; 850 } 851 852 const AVChannelLayout *av_channel_layout_standard(void **opaque) 853 { 854 uintptr_t i = (uintptr_t)*opaque; 855 const AVChannelLayout *ch_layout = NULL; 856 857 if (i < FF_ARRAY_ELEMS(channel_layout_map)) { 858 ch_layout = &channel_layout_map[i].layout; 859 *opaque = (void*)(i + 1); 860 } 861 862 return ch_layout; 863 } 864 865 uint64_t av_channel_layout_subset(const AVChannelLayout *channel_layout, 866 uint64_t mask) 867 { 868 uint64_t ret = 0; 869 int i; 870 871 switch (channel_layout->order) { 872 case AV_CHANNEL_ORDER_NATIVE: 873 case AV_CHANNEL_ORDER_AMBISONIC: 874 return channel_layout->u.mask & mask; 875 case AV_CHANNEL_ORDER_CUSTOM: 876 for (i = 0; i < 64; i++) 877 if (mask & (1ULL << i) && av_channel_layout_index_from_channel(channel_layout, i) >= 0) 878 ret |= (1ULL << i); 879 break; 880 } 881 882 return ret; 883 } 884 885 int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags) 886 { 887 int allow_lossy = !(flags & AV_CHANNEL_LAYOUT_RETYPE_FLAG_LOSSLESS); 888 int lossy; 889 890 if (!av_channel_layout_check(channel_layout)) 891 return AVERROR(EINVAL); 892 893 if (flags & AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL) 894 order = canonical_order(channel_layout); 895 896 if (channel_layout->order == order) 897 return 0; 898 899 switch (order) { 900 case AV_CHANNEL_ORDER_UNSPEC: { 901 int nb_channels = channel_layout->nb_channels; 902 if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) { 903 lossy = 0; 904 for (int i = 0; i < nb_channels; i++) { 905 if (channel_layout->u.map[i].id != AV_CHAN_UNKNOWN || channel_layout->u.map[i].name[0]) { 906 lossy = 1; 907 break; 908 } 909 } 910 } else { 911 lossy = 1; 912 } 913 if (!lossy || allow_lossy) { 914 void *opaque = channel_layout->opaque; 915 av_channel_layout_uninit(channel_layout); 916 channel_layout->order = AV_CHANNEL_ORDER_UNSPEC; 917 channel_layout->nb_channels = nb_channels; 918 channel_layout->opaque = opaque; 919 return lossy; 920 } 921 return AVERROR(ENOSYS); 922 } 923 case AV_CHANNEL_ORDER_NATIVE: 924 if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) { 925 int64_t mask = masked_description(channel_layout, 0); 926 if (mask < 0) 927 return AVERROR(ENOSYS); 928 lossy = has_channel_names(channel_layout); 929 if (!lossy || allow_lossy) { 930 void *opaque = channel_layout->opaque; 931 av_channel_layout_uninit(channel_layout); 932 av_channel_layout_from_mask(channel_layout, mask); 933 channel_layout->opaque = opaque; 934 return lossy; 935 } 936 } 937 return AVERROR(ENOSYS); 938 case AV_CHANNEL_ORDER_CUSTOM: { 939 AVChannelLayout custom = { 0 }; 940 int ret = av_channel_layout_custom_init(&custom, channel_layout->nb_channels); 941 void *opaque = channel_layout->opaque; 942 if (ret < 0) 943 return ret; 944 if (channel_layout->order != AV_CHANNEL_ORDER_UNSPEC) 945 for (int i = 0; i < channel_layout->nb_channels; i++) 946 custom.u.map[i].id = av_channel_layout_channel_from_index(channel_layout, i); 947 av_channel_layout_uninit(channel_layout); 948 *channel_layout = custom; 949 channel_layout->opaque = opaque; 950 return 0; 951 } 952 case AV_CHANNEL_ORDER_AMBISONIC: 953 if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) { 954 int64_t mask; 955 int nb_channels = channel_layout->nb_channels; 956 int order = av_channel_layout_ambisonic_order(channel_layout); 957 if (order < 0) 958 return AVERROR(ENOSYS); 959 mask = masked_description(channel_layout, (order + 1) * (order + 1)); 960 if (mask < 0) 961 return AVERROR(ENOSYS); 962 lossy = has_channel_names(channel_layout); 963 if (!lossy || allow_lossy) { 964 void *opaque = channel_layout->opaque; 965 av_channel_layout_uninit(channel_layout); 966 channel_layout->order = AV_CHANNEL_ORDER_AMBISONIC; 967 channel_layout->nb_channels = nb_channels; 968 channel_layout->u.mask = mask; 969 channel_layout->opaque = opaque; 970 return lossy; 971 } 972 } 973 return AVERROR(ENOSYS); 974 default: 975 return AVERROR(EINVAL); 976 } 977 }