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