FFmpeg
channel_layout.c
Go to the documentation of this file.
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 
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 
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 
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  if (bp.len >= INT_MAX)
112  return AVERROR(ERANGE);
113  return bp.len + 1;
114 }
115 
116 void av_channel_description_bprint(AVBPrint *bp, enum AVChannel channel_id)
117 {
118  if (channel_id >= AV_CHAN_AMBISONIC_BASE &&
119  channel_id <= AV_CHAN_AMBISONIC_END)
120  av_bprintf(bp, "ambisonic ACN %d", channel_id - AV_CHAN_AMBISONIC_BASE);
121  else if ((unsigned)channel_id < FF_ARRAY_ELEMS(channel_names) &&
122  channel_names[channel_id].description)
123  av_bprintf(bp, "%s", channel_names[channel_id].description);
124  else if (channel_id == AV_CHAN_NONE)
125  av_bprintf(bp, "none");
126  else
127  av_bprintf(bp, "user %d", channel_id);
128 }
129 
130 int av_channel_description(char *buf, size_t buf_size, enum AVChannel channel_id)
131 {
132  AVBPrint bp;
133 
134  if (!buf && buf_size)
135  return AVERROR(EINVAL);
136 
137  av_bprint_init_for_buffer(&bp, buf, buf_size);
138  av_channel_description_bprint(&bp, channel_id);
139 
140  if (bp.len >= INT_MAX)
141  return AVERROR(ERANGE);
142  return bp.len + 1;
143 }
144 
145 enum AVChannel av_channel_from_string(const char *str)
146 {
147  int i;
148  char *endptr = (char *)str;
149  enum AVChannel id = AV_CHAN_NONE;
150 
151  if (!strncmp(str, "AMBI", 4)) {
152  i = strtol(str + 4, NULL, 0);
154  return AV_CHAN_NONE;
155  return AV_CHAN_AMBISONIC_BASE + i;
156  }
157 
158  for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++) {
159  if (channel_names[i].name && !strcmp(str, channel_names[i].name))
160  return i;
161  }
162  if (!strncmp(str, "USR", 3)) {
163  const char *p = str + 3;
164  id = strtol(p, &endptr, 0);
165  }
166  if (id >= 0 && !*endptr)
167  return id;
168 
169  return AV_CHAN_NONE;
170 }
171 
173  const char *name;
175 };
176 
177 static const struct channel_layout_name channel_layout_map[] = {
178  { "mono", AV_CHANNEL_LAYOUT_MONO },
179  { "stereo", AV_CHANNEL_LAYOUT_STEREO },
180  { "2.1", AV_CHANNEL_LAYOUT_2POINT1 },
181  { "3.0", AV_CHANNEL_LAYOUT_SURROUND },
182  { "3.0(back)", AV_CHANNEL_LAYOUT_2_1 },
183  { "4.0", AV_CHANNEL_LAYOUT_4POINT0 },
184  { "quad", AV_CHANNEL_LAYOUT_QUAD },
185  { "quad(side)", AV_CHANNEL_LAYOUT_2_2 },
186  { "3.1", AV_CHANNEL_LAYOUT_3POINT1 },
188  { "5.0(side)", AV_CHANNEL_LAYOUT_5POINT0 },
189  { "4.1", AV_CHANNEL_LAYOUT_4POINT1 },
191  { "5.1(side)", AV_CHANNEL_LAYOUT_5POINT1 },
192  { "6.0", AV_CHANNEL_LAYOUT_6POINT0 },
193  { "6.0(front)", AV_CHANNEL_LAYOUT_6POINT0_FRONT },
194  { "3.1.2", AV_CHANNEL_LAYOUT_3POINT1POINT2 },
195  { "hexagonal", AV_CHANNEL_LAYOUT_HEXAGONAL },
196  { "6.1", AV_CHANNEL_LAYOUT_6POINT1 },
197  { "6.1(back)", AV_CHANNEL_LAYOUT_6POINT1_BACK },
198  { "6.1(front)", AV_CHANNEL_LAYOUT_6POINT1_FRONT },
199  { "7.0", AV_CHANNEL_LAYOUT_7POINT0 },
200  { "7.0(front)", AV_CHANNEL_LAYOUT_7POINT0_FRONT },
201  { "7.1", AV_CHANNEL_LAYOUT_7POINT1 },
202  { "7.1(wide)", AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK },
203  { "7.1(wide-side)", AV_CHANNEL_LAYOUT_7POINT1_WIDE },
205  { "octagonal", AV_CHANNEL_LAYOUT_OCTAGONAL },
206  { "cube", AV_CHANNEL_LAYOUT_CUBE },
208  { "7.1.2", AV_CHANNEL_LAYOUT_7POINT1POINT2 },
210  { "7.2.3", AV_CHANNEL_LAYOUT_7POINT2POINT3 },
212  { "hexadecagonal", AV_CHANNEL_LAYOUT_HEXADECAGONAL },
213  { "downmix", AV_CHANNEL_LAYOUT_STEREO_DOWNMIX, },
214  { "22.2", AV_CHANNEL_LAYOUT_22POINT2, },
215 };
216 
217 #if FF_API_OLD_CHANNEL_LAYOUT
219 static uint64_t get_channel_layout_single(const char *name, int name_len)
220 {
221  int i;
222  char *end;
223  int64_t layout;
224 
225  for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) {
226  if (strlen(channel_layout_map[i].name) == name_len &&
227  !memcmp(channel_layout_map[i].name, name, name_len))
228  return channel_layout_map[i].layout.u.mask;
229  }
230  for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++)
231  if (channel_names[i].name &&
232  strlen(channel_names[i].name) == name_len &&
233  !memcmp(channel_names[i].name, name, name_len))
234  return (int64_t)1 << i;
235 
236  errno = 0;
237  i = strtol(name, &end, 10);
238 
239  if (!errno && (end + 1 - name == name_len && *end == 'c'))
241 
242  errno = 0;
243  layout = strtoll(name, &end, 0);
244  if (!errno && end - name == name_len)
245  return FFMAX(layout, 0);
246  return 0;
247 }
248 
249 uint64_t av_get_channel_layout(const char *name)
250 {
251  const char *n, *e;
252  const char *name_end = name + strlen(name);
253  int64_t layout = 0, layout_single;
254 
255  for (n = name; n < name_end; n = e + 1) {
256  for (e = n; e < name_end && *e != '+' && *e != '|'; e++);
257  layout_single = get_channel_layout_single(n, e - n);
258  if (!layout_single)
259  return 0;
260  layout |= layout_single;
261  }
262  return layout;
263 }
264 
265 int av_get_extended_channel_layout(const char *name, uint64_t* channel_layout, int* nb_channels)
266 {
267  int nb = 0;
268  char *end;
269  uint64_t layout = av_get_channel_layout(name);
270 
271  if (layout) {
272  *channel_layout = layout;
274  return 0;
275  }
276 
277  nb = strtol(name, &end, 10);
278  if (!errno && *end == 'C' && *(end + 1) == '\0' && nb > 0 && nb < 64) {
279  *channel_layout = 0;
280  *nb_channels = nb;
281  return 0;
282  }
283 
284  return AVERROR(EINVAL);
285 }
286 
287 void av_bprint_channel_layout(struct AVBPrint *bp,
288  int nb_channels, uint64_t channel_layout)
289 {
290  int i;
291 
292  if (nb_channels <= 0)
293  nb_channels = av_get_channel_layout_nb_channels(channel_layout);
294 
295  for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
296  if (nb_channels == channel_layout_map[i].layout.nb_channels &&
297  channel_layout == channel_layout_map[i].layout.u.mask) {
298  av_bprintf(bp, "%s", channel_layout_map[i].name);
299  return;
300  }
301 
302  av_bprintf(bp, "%d channels", nb_channels);
303  if (channel_layout) {
304  int i, ch;
305  av_bprintf(bp, " (");
306  for (i = 0, ch = 0; i < 64; i++) {
307  if ((channel_layout & (UINT64_C(1) << i))) {
308  const char *name = get_channel_name(i);
309  if (name) {
310  if (ch > 0)
311  av_bprintf(bp, "+");
312  av_bprintf(bp, "%s", name);
313  }
314  ch++;
315  }
316  }
317  av_bprintf(bp, ")");
318  }
319 }
320 
321 void av_get_channel_layout_string(char *buf, int buf_size,
322  int nb_channels, uint64_t channel_layout)
323 {
324  AVBPrint bp;
325 
326  av_bprint_init_for_buffer(&bp, buf, buf_size);
327  av_bprint_channel_layout(&bp, nb_channels, channel_layout);
328 }
329 
330 int av_get_channel_layout_nb_channels(uint64_t channel_layout)
331 {
332  return av_popcount64(channel_layout);
333 }
334 
335 int64_t av_get_default_channel_layout(int nb_channels) {
336  int i;
337  for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
338  if (nb_channels == channel_layout_map[i].layout.nb_channels)
339  return channel_layout_map[i].layout.u.mask;
340  return 0;
341 }
342 
343 int av_get_channel_layout_channel_index(uint64_t channel_layout,
344  uint64_t channel)
345 {
346  if (!(channel_layout & channel) ||
348  return AVERROR(EINVAL);
349  channel_layout &= channel - 1;
350  return av_get_channel_layout_nb_channels(channel_layout);
351 }
352 
353 const char *av_get_channel_name(uint64_t channel)
354 {
355  int i;
357  return NULL;
358  for (i = 0; i < 64; i++)
359  if ((1ULL<<i) & channel)
360  return get_channel_name(i);
361  return NULL;
362 }
363 
364 const char *av_get_channel_description(uint64_t channel)
365 {
366  int i;
368  return NULL;
369  for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++)
370  if ((1ULL<<i) & channel)
371  return channel_names[i].description;
372  return NULL;
373 }
374 
375 uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
376 {
377  int i;
378 
379  if (av_get_channel_layout_nb_channels(channel_layout) <= index)
380  return 0;
381 
382  for (i = 0; i < 64; i++) {
383  if ((1ULL << i) & channel_layout && !index--)
384  return 1ULL << i;
385  }
386  return 0;
387 }
388 
390  const char **name)
391 {
393  return AVERROR_EOF;
396  return 0;
397 }
399 #endif
400 
401 int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels)
402 {
404 
405  if (nb_channels <= 0)
406  return AVERROR(EINVAL);
407 
408  map = av_calloc(nb_channels, sizeof(*channel_layout->u.map));
409  if (!map)
410  return AVERROR(ENOMEM);
411  for (int i = 0; i < nb_channels; i++)
412  map[i].id = AV_CHAN_UNKNOWN;
413 
414  channel_layout->order = AV_CHANNEL_ORDER_CUSTOM;
415  channel_layout->nb_channels = nb_channels;
416  channel_layout->u.map = map;
417 
418  return 0;
419 }
420 
422  uint64_t mask)
423 {
424  if (!mask)
425  return AVERROR(EINVAL);
426 
427  channel_layout->order = AV_CHANNEL_ORDER_NATIVE;
428  channel_layout->nb_channels = av_popcount64(mask);
429  channel_layout->u.mask = mask;
430 
431  return 0;
432 }
433 
435  const char *str)
436 {
437  int i;
438  int channels = 0, nb_channels = 0, native = 1;
439  enum AVChannel highest_channel = AV_CHAN_NONE;
440  const char *dup;
441  char *chlist, *end;
442  uint64_t mask = 0;
443 
444  /* channel layout names */
445  for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) {
446  if (channel_layout_map[i].name && !strcmp(str, channel_layout_map[i].name)) {
447  *channel_layout = channel_layout_map[i].layout;
448  return 0;
449  }
450  }
451 
452  /* ambisonic */
453  if (!strncmp(str, "ambisonic ", 10)) {
454  const char *p = str + 10;
455  char *endptr;
456  AVChannelLayout extra = {0};
457  int order;
458 
459  order = strtol(p, &endptr, 0);
460  if (order < 0 || order + 1 > INT_MAX / (order + 1) ||
461  (*endptr && *endptr != '+'))
462  return AVERROR(EINVAL);
463 
464  channel_layout->order = AV_CHANNEL_ORDER_AMBISONIC;
465  channel_layout->nb_channels = (order + 1) * (order + 1);
466 
467  if (*endptr) {
468  int ret = av_channel_layout_from_string(&extra, endptr + 1);
469  if (ret < 0)
470  return ret;
471  if (extra.nb_channels >= INT_MAX - channel_layout->nb_channels) {
472  av_channel_layout_uninit(&extra);
473  return AVERROR(EINVAL);
474  }
475 
476  if (extra.order == AV_CHANNEL_ORDER_NATIVE) {
477  channel_layout->u.mask = extra.u.mask;
478  } else {
479  channel_layout->order = AV_CHANNEL_ORDER_CUSTOM;
480  channel_layout->u.map =
481  av_calloc(channel_layout->nb_channels + extra.nb_channels,
482  sizeof(*channel_layout->u.map));
483  if (!channel_layout->u.map) {
484  av_channel_layout_uninit(&extra);
485  return AVERROR(ENOMEM);
486  }
487 
488  for (i = 0; i < channel_layout->nb_channels; i++)
489  channel_layout->u.map[i].id = AV_CHAN_AMBISONIC_BASE + i;
490  for (i = 0; i < extra.nb_channels; i++) {
492  if (CHAN_IS_AMBI(ch)) {
493  av_channel_layout_uninit(&extra);
494  return AVERROR(EINVAL);
495  }
496  channel_layout->u.map[channel_layout->nb_channels + i].id = ch;
497  if (extra.order == AV_CHANNEL_ORDER_CUSTOM &&
498  extra.u.map[i].name[0])
499  av_strlcpy(channel_layout->u.map[channel_layout->nb_channels + i].name,
500  extra.u.map[i].name,
501  sizeof(channel_layout->u.map[channel_layout->nb_channels + i].name));
502  }
503  }
504  channel_layout->nb_channels += extra.nb_channels;
505  av_channel_layout_uninit(&extra);
506  }
507 
508  return 0;
509  }
510 
511  chlist = av_strdup(str);
512  if (!chlist)
513  return AVERROR(ENOMEM);
514 
515  /* channel names */
516  av_sscanf(str, "%d channels (%[^)]", &nb_channels, chlist);
517  end = strchr(str, ')');
518 
519  dup = chlist;
520  while (*dup) {
521  char *channel, *chname;
522  int ret = av_opt_get_key_value(&dup, "@", "+", AV_OPT_FLAG_IMPLICIT_KEY, &channel, &chname);
523  if (ret < 0) {
524  av_free(chlist);
525  return ret;
526  }
527  if (*dup)
528  dup++; // skip separator
529  if (channel && !*channel)
530  av_freep(&channel);
531  for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++) {
532  if (channel_names[i].name && !strcmp(channel ? channel : chname, channel_names[i].name)) {
533  if (channel || i < highest_channel || mask & (1ULL << i))
534  native = 0; // Not a native layout, use a custom one
535  highest_channel = i;
536  mask |= 1ULL << i;
537  break;
538  }
539  }
540 
541  if (!channel && i >= FF_ARRAY_ELEMS(channel_names)) {
542  char *endptr = chname;
543  enum AVChannel id = AV_CHAN_NONE;
544 
545  if (!strncmp(chname, "USR", 3)) {
546  const char *p = chname + 3;
547  id = strtol(p, &endptr, 0);
548  }
549  if (id < 0 || *endptr) {
550  native = 0; // Unknown channel name
551  channels = 0;
552  mask = 0;
553  av_free(chname);
554  break;
555  }
556  if (id > 63)
557  native = 0; // Not a native layout, use a custom one
558  else {
559  if (id < highest_channel || mask & (1ULL << id))
560  native = 0; // Not a native layout, use a custom one
561  highest_channel = id;
562  mask |= 1ULL << id;
563  }
564  }
565  channels++;
566  av_free(channel);
567  av_free(chname);
568  }
569 
570  if (mask && native) {
571  av_free(chlist);
572  if (nb_channels && ((nb_channels != channels) || (!end || *++end)))
573  return AVERROR(EINVAL);
574  av_channel_layout_from_mask(channel_layout, mask);
575  return 0;
576  }
577 
578  /* custom layout of channel names */
579  if (channels && !native) {
580  int idx = 0;
581 
582  if (nb_channels && ((nb_channels != channels) || (!end || *++end))) {
583  av_free(chlist);
584  return AVERROR(EINVAL);
585  }
586 
587  channel_layout->u.map = av_calloc(channels, sizeof(*channel_layout->u.map));
588  if (!channel_layout->u.map) {
589  av_free(chlist);
590  return AVERROR(ENOMEM);
591  }
592 
593  channel_layout->order = AV_CHANNEL_ORDER_CUSTOM;
594  channel_layout->nb_channels = channels;
595 
596  dup = chlist;
597  while (*dup) {
598  char *channel, *chname;
599  int ret = av_opt_get_key_value(&dup, "@", "+", AV_OPT_FLAG_IMPLICIT_KEY, &channel, &chname);
600  if (ret < 0) {
601  av_freep(&channel_layout->u.map);
602  av_free(chlist);
603  return ret;
604  }
605  if (*dup)
606  dup++; // skip separator
607  for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++) {
608  if (channel_names[i].name && !strcmp(channel ? channel : chname, channel_names[i].name)) {
609  channel_layout->u.map[idx].id = i;
610  if (channel)
611  av_strlcpy(channel_layout->u.map[idx].name, chname, sizeof(channel_layout->u.map[idx].name));
612  idx++;
613  break;
614  }
615  }
616  if (i >= FF_ARRAY_ELEMS(channel_names)) {
617  const char *p = (channel ? channel : chname) + 3;
618  channel_layout->u.map[idx].id = strtol(p, NULL, 0);
619  if (channel)
620  av_strlcpy(channel_layout->u.map[idx].name, chname, sizeof(channel_layout->u.map[idx].name));
621  idx++;
622  }
623  av_free(channel);
624  av_free(chname);
625  }
626  av_free(chlist);
627 
628  return 0;
629  }
630  av_freep(&chlist);
631 
632  errno = 0;
633  mask = strtoull(str, &end, 0);
634 
635  /* channel layout mask */
636  if (!errno && !*end && !strchr(str, '-') && mask) {
637  av_channel_layout_from_mask(channel_layout, mask);
638  return 0;
639  }
640 
641  errno = 0;
642  channels = strtol(str, &end, 10);
643 
644  /* number of channels */
645  if (!errno && !strcmp(end, "c") && channels > 0) {
646  av_channel_layout_default(channel_layout, channels);
647  if (channel_layout->order == AV_CHANNEL_ORDER_NATIVE)
648  return 0;
649  }
650 
651  /* number of unordered channels */
652  if (!errno && (!strcmp(end, "C") || !strcmp(end, " channels"))
653  && channels > 0) {
654  channel_layout->order = AV_CHANNEL_ORDER_UNSPEC;
655  channel_layout->nb_channels = channels;
656  return 0;
657  }
658 
659  return AVERROR(EINVAL);
660 }
661 
663 {
664  if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM)
665  av_freep(&channel_layout->u.map);
666  memset(channel_layout, 0, sizeof(*channel_layout));
667 }
668 
670 {
672  *dst = *src;
673  if (src->order == AV_CHANNEL_ORDER_CUSTOM) {
674  dst->u.map = av_malloc_array(src->nb_channels, sizeof(*dst->u.map));
675  if (!dst->u.map)
676  return AVERROR(ENOMEM);
677  memcpy(dst->u.map, src->u.map, src->nb_channels * sizeof(*src->u.map));
678  }
679  return 0;
680 }
681 
682 static int64_t masked_description(const AVChannelLayout *channel_layout, int start_channel)
683 {
684  uint64_t mask = 0;
685  for (int i = start_channel; i < channel_layout->nb_channels; i++) {
686  enum AVChannel ch = channel_layout->u.map[i].id;
687  if (ch >= 0 && ch < 63 && mask < (1ULL << ch))
688  mask |= (1ULL << ch);
689  else
690  return AVERROR(EINVAL);
691  }
692  return mask;
693 }
694 
695 static int has_channel_names(const AVChannelLayout *channel_layout)
696 {
697  if (channel_layout->order != AV_CHANNEL_ORDER_CUSTOM)
698  return 0;
699  for (int i = 0; i < channel_layout->nb_channels; i++)
700  if (channel_layout->u.map[i].name[0])
701  return 1;
702  return 0;
703 }
704 
705 /**
706  * If the layout is n-th order standard-order ambisonic, with optional
707  * extra non-diegetic channels at the end, return the order.
708  * Return a negative error code otherwise.
709  */
710 static int ambisonic_order(const AVChannelLayout *channel_layout)
711 {
712  int i, highest_ambi, order;
713 
714  highest_ambi = -1;
715  if (channel_layout->order == AV_CHANNEL_ORDER_AMBISONIC)
716  highest_ambi = channel_layout->nb_channels - av_popcount64(channel_layout->u.mask) - 1;
717  else {
718  const AVChannelCustom *map = channel_layout->u.map;
719  av_assert0(channel_layout->order == AV_CHANNEL_ORDER_CUSTOM);
720 
721  for (i = 0; i < channel_layout->nb_channels; i++) {
722  int is_ambi = CHAN_IS_AMBI(map[i].id);
723 
724  /* ambisonic following non-ambisonic */
725  if (i > 0 && is_ambi && !CHAN_IS_AMBI(map[i - 1].id))
726  return AVERROR(EINVAL);
727 
728  /* non-default ordering */
729  if (is_ambi && map[i].id - AV_CHAN_AMBISONIC_BASE != i)
730  return AVERROR(EINVAL);
731 
732  if (CHAN_IS_AMBI(map[i].id))
733  highest_ambi = i;
734  }
735  }
736  /* no ambisonic channels*/
737  if (highest_ambi < 0)
738  return AVERROR(EINVAL);
739 
740  order = floor(sqrt(highest_ambi));
741  /* incomplete order - some harmonics are missing */
742  if ((order + 1) * (order + 1) != highest_ambi + 1)
743  return AVERROR(EINVAL);
744 
745  return order;
746 }
747 
748 /**
749  * If the custom layout is n-th order standard-order ambisonic, with optional
750  * extra non-diegetic channels at the end, write its string description in bp.
751  * Return a negative error code otherwise.
752  */
753 static int try_describe_ambisonic(AVBPrint *bp, const AVChannelLayout *channel_layout)
754 {
755  int nb_ambi_channels;
756  int order = ambisonic_order(channel_layout);
757  if (order < 0)
758  return order;
759 
760  av_bprintf(bp, "ambisonic %d", order);
761 
762  /* extra channels present */
763  nb_ambi_channels = (order + 1) * (order + 1);
764  if (nb_ambi_channels < channel_layout->nb_channels) {
765  AVChannelLayout extra = { 0 };
766 
767  if (channel_layout->order == AV_CHANNEL_ORDER_AMBISONIC) {
769  extra.nb_channels = av_popcount64(channel_layout->u.mask);
770  extra.u.mask = channel_layout->u.mask;
771  } else {
772  int64_t mask;
773  if (!has_channel_names(channel_layout) &&
774  (mask = masked_description(channel_layout, nb_ambi_channels)) > 0) {
776  extra.nb_channels = av_popcount64(mask);
777  extra.u.mask = mask;
778  } else {
780  extra.nb_channels = channel_layout->nb_channels - nb_ambi_channels;
781  extra.u.map = channel_layout->u.map + nb_ambi_channels;
782  }
783  }
784 
785  av_bprint_chars(bp, '+', 1);
787  /* Not calling uninit here on extra because we don't own the u.map pointer */
788  }
789 
790  return 0;
791 }
792 
794  AVBPrint *bp)
795 {
796  int i;
797 
798  switch (channel_layout->order) {
800  for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
801  if (channel_layout->u.mask == channel_layout_map[i].layout.u.mask) {
802  av_bprintf(bp, "%s", channel_layout_map[i].name);
803  return 0;
804  }
805  // fall-through
807  if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) {
808  int64_t mask;
809  int res = try_describe_ambisonic(bp, channel_layout);
810  if (res >= 0)
811  return 0;
812  if (!has_channel_names(channel_layout) &&
813  (mask = masked_description(channel_layout, 0)) > 0) {
815  .nb_channels = av_popcount64(mask),
816  .u.mask = mask };
817  return av_channel_layout_describe_bprint(&native, bp);
818  }
819  }
820  if (channel_layout->nb_channels)
821  av_bprintf(bp, "%d channels (", channel_layout->nb_channels);
822  for (i = 0; i < channel_layout->nb_channels; i++) {
823  enum AVChannel ch = av_channel_layout_channel_from_index(channel_layout, i);
824 
825  if (i)
826  av_bprintf(bp, "+");
827  av_channel_name_bprint(bp, ch);
828  if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM &&
829  channel_layout->u.map[i].name[0])
830  av_bprintf(bp, "@%s", channel_layout->u.map[i].name);
831  }
832  if (channel_layout->nb_channels) {
833  av_bprintf(bp, ")");
834  return 0;
835  }
836  // fall-through
838  av_bprintf(bp, "%d channels", channel_layout->nb_channels);
839  return 0;
841  return try_describe_ambisonic(bp, channel_layout);
842  default:
843  return AVERROR(EINVAL);
844  }
845 }
846 
847 int av_channel_layout_describe(const AVChannelLayout *channel_layout,
848  char *buf, size_t buf_size)
849 {
850  AVBPrint bp;
851  int ret;
852 
853  if (!buf && buf_size)
854  return AVERROR(EINVAL);
855 
856  av_bprint_init_for_buffer(&bp, buf, buf_size);
857  ret = av_channel_layout_describe_bprint(channel_layout, &bp);
858  if (ret < 0)
859  return ret;
860 
861  if (bp.len >= INT_MAX)
862  return AVERROR(ERANGE);
863  return bp.len + 1;
864 }
865 
866 enum AVChannel
868  unsigned int idx)
869 {
870  int i;
871 
872  if (idx >= channel_layout->nb_channels)
873  return AV_CHAN_NONE;
874 
875  switch (channel_layout->order) {
877  return channel_layout->u.map[idx].id;
879  int ambi_channels = channel_layout->nb_channels - av_popcount64(channel_layout->u.mask);
880  if (idx < ambi_channels)
881  return AV_CHAN_AMBISONIC_BASE + idx;
882  idx -= ambi_channels;
883  }
884  // fall-through
886  for (i = 0; i < 64; i++) {
887  if ((1ULL << i) & channel_layout->u.mask && !idx--)
888  return i;
889  }
890  default:
891  return AV_CHAN_NONE;
892  }
893 }
894 
895 enum AVChannel
897  const char *str)
898 {
899  int index = av_channel_layout_index_from_string(channel_layout, str);
900 
901  if (index < 0)
902  return AV_CHAN_NONE;
903 
904  return av_channel_layout_channel_from_index(channel_layout, index);
905 }
906 
908  enum AVChannel channel)
909 {
910  int i;
911 
912  if (channel == AV_CHAN_NONE)
913  return AVERROR(EINVAL);
914 
915  switch (channel_layout->order) {
917  for (i = 0; i < channel_layout->nb_channels; i++)
918  if (channel_layout->u.map[i].id == channel)
919  return i;
920  return AVERROR(EINVAL);
923  uint64_t mask = channel_layout->u.mask;
924  int ambi_channels = channel_layout->nb_channels - av_popcount64(mask);
925  if (channel_layout->order == AV_CHANNEL_ORDER_AMBISONIC &&
927  if (channel - AV_CHAN_AMBISONIC_BASE >= ambi_channels)
928  return AVERROR(EINVAL);
930  }
931  if ((unsigned)channel > 63 || !(mask & (1ULL << channel)))
932  return AVERROR(EINVAL);
933  mask &= (1ULL << channel) - 1;
934  return av_popcount64(mask) + ambi_channels;
935  }
936  default:
937  return AVERROR(EINVAL);
938  }
939 }
940 
942  const char *str)
943 {
944  char *chname;
945  enum AVChannel ch = AV_CHAN_NONE;
946 
947  switch (channel_layout->order) {
949  chname = strstr(str, "@");
950  if (chname) {
951  char buf[16];
952  chname++;
953  av_strlcpy(buf, str, FFMIN(sizeof(buf), chname - str));
954  if (!*chname)
955  chname = NULL;
956  ch = av_channel_from_string(buf);
957  if (ch == AV_CHAN_NONE && *buf)
958  return AVERROR(EINVAL);
959  }
960  for (int i = 0; chname && i < channel_layout->nb_channels; i++) {
961  if (!strcmp(chname, channel_layout->u.map[i].name) &&
962  (ch == AV_CHAN_NONE || ch == channel_layout->u.map[i].id))
963  return i;
964  }
965  // fall-through
968  ch = av_channel_from_string(str);
969  if (ch == AV_CHAN_NONE)
970  return AVERROR(EINVAL);
971  return av_channel_layout_index_from_channel(channel_layout, ch);
972  }
973 
974  return AVERROR(EINVAL);
975 }
976 
977 int av_channel_layout_check(const AVChannelLayout *channel_layout)
978 {
979  if (channel_layout->nb_channels <= 0)
980  return 0;
981 
982  switch (channel_layout->order) {
984  return av_popcount64(channel_layout->u.mask) == channel_layout->nb_channels;
986  if (!channel_layout->u.map)
987  return 0;
988  for (int i = 0; i < channel_layout->nb_channels; i++) {
989  if (channel_layout->u.map[i].id == AV_CHAN_NONE)
990  return 0;
991  }
992  return 1;
994  /* If non-diegetic channels are present, ensure they are taken into account */
995  return av_popcount64(channel_layout->u.mask) < channel_layout->nb_channels;
997  return 1;
998  default:
999  return 0;
1000  }
1001 }
1002 
1004 {
1005  int i;
1006 
1007  /* different channel counts -> not equal */
1008  if (chl->nb_channels != chl1->nb_channels)
1009  return 1;
1010 
1011  /* if only one is unspecified -> not equal */
1012  if ((chl->order == AV_CHANNEL_ORDER_UNSPEC) !=
1013  (chl1->order == AV_CHANNEL_ORDER_UNSPEC))
1014  return 1;
1015  /* both are unspecified -> equal */
1016  else if (chl->order == AV_CHANNEL_ORDER_UNSPEC)
1017  return 0;
1018 
1019  /* can compare masks directly */
1020  if ((chl->order == AV_CHANNEL_ORDER_NATIVE ||
1021  chl->order == AV_CHANNEL_ORDER_AMBISONIC) &&
1022  chl->order == chl1->order)
1023  return chl->u.mask != chl1->u.mask;
1024 
1025  /* compare channel by channel */
1026  for (i = 0; i < chl->nb_channels; i++)
1029  return 1;
1030  return 0;
1031 }
1032 
1033 void av_channel_layout_default(AVChannelLayout *ch_layout, int nb_channels)
1034 {
1035  int i;
1036  for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
1037  if (nb_channels == channel_layout_map[i].layout.nb_channels) {
1038  *ch_layout = channel_layout_map[i].layout;
1039  return;
1040  }
1041 
1042  ch_layout->order = AV_CHANNEL_ORDER_UNSPEC;
1043  ch_layout->nb_channels = nb_channels;
1044 }
1045 
1047 {
1048  uintptr_t i = (uintptr_t)*opaque;
1049  const AVChannelLayout *ch_layout = NULL;
1050 
1052  ch_layout = &channel_layout_map[i].layout;
1053  *opaque = (void*)(i + 1);
1054  }
1055 
1056  return ch_layout;
1057 }
1058 
1059 uint64_t av_channel_layout_subset(const AVChannelLayout *channel_layout,
1060  uint64_t mask)
1061 {
1062  uint64_t ret = 0;
1063  int i;
1064 
1065  switch (channel_layout->order) {
1068  return channel_layout->u.mask & mask;
1070  for (i = 0; i < 64; i++)
1071  if (mask & (1ULL << i) && av_channel_layout_index_from_channel(channel_layout, i) >= 0)
1072  ret |= (1ULL << i);
1073  break;
1074  }
1075 
1076  return ret;
1077 }
1078 
1079 int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
1080 {
1081  int allow_lossy = !(flags & AV_CHANNEL_LAYOUT_RETYPE_FLAG_LOSSLESS);
1082  int lossy;
1083 
1084  if (!av_channel_layout_check(channel_layout))
1085  return AVERROR(EINVAL);
1086 
1087  if (channel_layout->order == order)
1088  return 0;
1089 
1090  switch (order) {
1091  case AV_CHANNEL_ORDER_UNSPEC: {
1092  int nb_channels = channel_layout->nb_channels;
1093  if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) {
1094  lossy = 0;
1095  for (int i = 0; i < nb_channels; i++) {
1096  if (channel_layout->u.map[i].id != AV_CHAN_UNKNOWN || channel_layout->u.map[i].name[0]) {
1097  lossy = 1;
1098  break;
1099  }
1100  }
1101  } else {
1102  lossy = 1;
1103  }
1104  if (!lossy || allow_lossy) {
1105  av_channel_layout_uninit(channel_layout);
1106  channel_layout->order = AV_CHANNEL_ORDER_UNSPEC;
1107  channel_layout->nb_channels = nb_channels;
1108  return lossy;
1109  }
1110  return AVERROR(ENOSYS);
1111  }
1113  if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) {
1114  int64_t mask = masked_description(channel_layout, 0);
1115  if (mask < 0)
1116  return AVERROR(ENOSYS);
1117  lossy = has_channel_names(channel_layout);
1118  if (!lossy || allow_lossy) {
1119  av_channel_layout_uninit(channel_layout);
1120  av_channel_layout_from_mask(channel_layout, mask);
1121  return lossy;
1122  }
1123  }
1124  return AVERROR(ENOSYS);
1125  case AV_CHANNEL_ORDER_CUSTOM: {
1126  AVChannelLayout custom = { 0 };
1127  int ret = av_channel_layout_custom_init(&custom, channel_layout->nb_channels);
1128  if (ret < 0)
1129  return ret;
1130  if (channel_layout->order != AV_CHANNEL_ORDER_UNSPEC)
1131  for (int i = 0; i < channel_layout->nb_channels; i++)
1132  custom.u.map[i].id = av_channel_layout_channel_from_index(channel_layout, i);
1133  av_channel_layout_uninit(channel_layout);
1134  *channel_layout = custom;
1135  return 0;
1136  }
1138  if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) {
1139  int64_t mask;
1140  int nb_channels = channel_layout->nb_channels;
1141  int order = ambisonic_order(channel_layout);
1142  if (order < 0)
1143  return AVERROR(ENOSYS);
1144  mask = masked_description(channel_layout, (order + 1) * (order + 1));
1145  if (mask < 0)
1146  return AVERROR(ENOSYS);
1147  lossy = has_channel_names(channel_layout);
1148  if (!lossy || allow_lossy) {
1149  av_channel_layout_uninit(channel_layout);
1150  channel_layout->order = AV_CHANNEL_ORDER_AMBISONIC;
1151  channel_layout->nb_channels = nb_channels;
1152  channel_layout->u.mask = mask;
1153  return lossy;
1154  }
1155  }
1156  return AVERROR(ENOSYS);
1157  default:
1158  return AVERROR(EINVAL);
1159  }
1160 }
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:73
av_get_channel_layout_string
void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout)
Return a description of a channel layout.
Definition: channel_layout.c:321
AV_OPT_FLAG_IMPLICIT_KEY
@ AV_OPT_FLAG_IMPLICIT_KEY
Accept to parse a value without a key; the key will then be returned as NULL.
Definition: opt.h:536
AVChannelOrder
AVChannelOrder
Definition: channel_layout.h:107
AV_CHANNEL_LAYOUT_STEREO_DOWNMIX
#define AV_CHANNEL_LAYOUT_STEREO_DOWNMIX
Definition: channel_layout.h:423
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
AV_CHANNEL_LAYOUT_OCTAGONAL
#define AV_CHANNEL_LAYOUT_OCTAGONAL
Definition: channel_layout.h:415
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
AV_CHANNEL_LAYOUT_7POINT1POINT4_BACK
#define AV_CHANNEL_LAYOUT_7POINT1POINT4_BACK
Definition: channel_layout.h:419
AV_CHANNEL_LAYOUT_STEREO
#define AV_CHANNEL_LAYOUT_STEREO
Definition: channel_layout.h:389
AV_CHANNEL_LAYOUT_4POINT1
#define AV_CHANNEL_LAYOUT_4POINT1
Definition: channel_layout.h:395
AV_CHANNEL_LAYOUT_HEXAGONAL
#define AV_CHANNEL_LAYOUT_HEXAGONAL
Definition: channel_layout.h:405
av_popcount64
#define av_popcount64
Definition: common.h:155
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AV_CHAN_WIDE_LEFT
@ AV_CHAN_WIDE_LEFT
Definition: channel_layout.h:72
av_get_channel_name
const char * av_get_channel_name(uint64_t channel)
Get the name of a given channel.
Definition: channel_layout.c:353
AVChannelLayout::map
AVChannelCustom * map
This member must be used when the channel order is AV_CHANNEL_ORDER_CUSTOM.
Definition: channel_layout.h:364
ambisonic_order
static int ambisonic_order(const AVChannelLayout *channel_layout)
If the layout is n-th order standard-order ambisonic, with optional extra non-diegetic channels at th...
Definition: channel_layout.c:710
AV_CHANNEL_LAYOUT_2_2
#define AV_CHANNEL_LAYOUT_2_2
Definition: channel_layout.h:396
av_channel_layout_channel_from_index
enum AVChannel av_channel_layout_channel_from_index(const AVChannelLayout *channel_layout, unsigned int idx)
Get the channel with the given index in a channel layout.
Definition: channel_layout.c:867
channel_layout_name::name
const char * name
Definition: channel_layout.c:173
av_get_standard_channel_layout
int av_get_standard_channel_layout(unsigned index, uint64_t *layout, const char **name)
Get the value and name of a standard channel layout.
Definition: channel_layout.c:389
channel_name
Definition: channel_layout.c:41
AVChannelLayout::order
enum AVChannelOrder order
Channel order used in this layout.
Definition: channel_layout.h:318
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVChannelLayout::mask
uint64_t mask
This member must be used for AV_CHANNEL_ORDER_NATIVE, and may be used for AV_CHANNEL_ORDER_AMBISONIC ...
Definition: channel_layout.h:345
av_get_channel_layout_nb_channels
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
Definition: channel_layout.c:330
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:323
AV_CHANNEL_LAYOUT_7POINT2POINT3
#define AV_CHANNEL_LAYOUT_7POINT2POINT3
Definition: channel_layout.h:420
channel_name::description
const char * description
Definition: channel_layout.c:43
av_channel_layout_describe_bprint
int av_channel_layout_describe_bprint(const AVChannelLayout *channel_layout, AVBPrint *bp)
bprint variant of av_channel_layout_describe().
Definition: channel_layout.c:793
av_channel_layout_extract_channel
uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
Get the channel with the given index in channel_layout.
Definition: channel_layout.c:375
AV_CHANNEL_LAYOUT_7POINT1_WIDE
#define AV_CHANNEL_LAYOUT_7POINT1_WIDE
Definition: channel_layout.h:412
AV_CHAN_SURROUND_DIRECT_LEFT
@ AV_CHAN_SURROUND_DIRECT_LEFT
Definition: channel_layout.h:74
av_channel_description_bprint
void av_channel_description_bprint(AVBPrint *bp, enum AVChannel channel_id)
bprint variant of av_channel_description().
Definition: channel_layout.c:116
AV_CHANNEL_LAYOUT_9POINT1POINT4_BACK
#define AV_CHANNEL_LAYOUT_9POINT1POINT4_BACK
Definition: channel_layout.h:421
av_bprint_init_for_buffer
void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size)
Init a print buffer using a pre-existing buffer.
Definition: bprint.c:85
AV_CHANNEL_LAYOUT_7POINT1POINT2
#define AV_CHANNEL_LAYOUT_7POINT1POINT2
Definition: channel_layout.h:418
AV_CHAN_TOP_BACK_RIGHT
@ AV_CHAN_TOP_BACK_RIGHT
Definition: channel_layout.h:67
macros.h
AV_CHANNEL_LAYOUT_2POINT1
#define AV_CHANNEL_LAYOUT_2POINT1
Definition: channel_layout.h:390
channel_name::name
const char * name
Definition: channel_layout.c:42
try_describe_ambisonic
static int try_describe_ambisonic(AVBPrint *bp, const AVChannelLayout *channel_layout)
If the custom layout is n-th order standard-order ambisonic, with optional extra non-diegetic channel...
Definition: channel_layout.c:753
channel_layout_name
Definition: channel_layout.c:172
AV_CHANNEL_LAYOUT_6POINT1_FRONT
#define AV_CHANNEL_LAYOUT_6POINT1_FRONT
Definition: channel_layout.h:408
av_get_channel_layout_channel_index
int av_get_channel_layout_channel_index(uint64_t channel_layout, uint64_t channel)
Get the index of a channel in channel_layout.
Definition: channel_layout.c:343
AV_CHANNEL_LAYOUT_SURROUND
#define AV_CHANNEL_LAYOUT_SURROUND
Definition: channel_layout.h:392
AV_CHAN_STEREO_RIGHT
@ AV_CHAN_STEREO_RIGHT
See above.
Definition: channel_layout.h:71
avassert.h
description
Tag description
Definition: snow.txt:206
AV_CHAN_BOTTOM_FRONT_LEFT
@ AV_CHAN_BOTTOM_FRONT_LEFT
Definition: channel_layout.h:80
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_get_channel_description
const char * av_get_channel_description(uint64_t channel)
Get the description of a given channel.
Definition: channel_layout.c:364
mask
static const uint16_t mask[17]
Definition: lzw.c:38
av_channel_layout_describe
int av_channel_layout_describe(const AVChannelLayout *channel_layout, char *buf, size_t buf_size)
Get a human-readable string describing the channel layout properties.
Definition: channel_layout.c:847
AV_CHANNEL_LAYOUT_4POINT0
#define AV_CHANNEL_LAYOUT_4POINT0
Definition: channel_layout.h:394
AV_CHANNEL_LAYOUT_7POINT1
#define AV_CHANNEL_LAYOUT_7POINT1
Definition: channel_layout.h:411
AVChannelCustom
An AVChannelCustom defines a single channel within a custom order layout.
Definition: channel_layout.h:277
floor
static __device__ float floor(float a)
Definition: cuda_runtime.h:173
AV_CHAN_UNKNOWN
@ AV_CHAN_UNKNOWN
Channel contains data, but its position is unknown.
Definition: channel_layout.h:87
AV_CHANNEL_ORDER_UNSPEC
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
Definition: channel_layout.h:112
av_channel_layout_from_mask
int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
Definition: channel_layout.c:421
AV_CHANNEL_LAYOUT_5POINT0_BACK
#define AV_CHANNEL_LAYOUT_5POINT0_BACK
Definition: channel_layout.h:400
AV_CHAN_SIDE_RIGHT
@ AV_CHAN_SIDE_RIGHT
Definition: channel_layout.h:60
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
av_channel_layout_index_from_string
int av_channel_layout_index_from_string(const AVChannelLayout *channel_layout, const char *str)
Get the index in a channel layout of a channel described by the given string.
Definition: channel_layout.c:941
av_channel_layout_standard
const AVChannelLayout * av_channel_layout_standard(void **opaque)
Iterate over all standard channel layouts.
Definition: channel_layout.c:1046
get_channel_name
static const char * get_channel_name(enum AVChannel channel_id)
Definition: channel_layout.c:79
channels
channels
Definition: aptx.h:31
CHAN_IS_AMBI
#define CHAN_IS_AMBI(x)
Definition: channel_layout.c:38
AV_CHAN_TOP_SIDE_LEFT
@ AV_CHAN_TOP_SIDE_LEFT
Definition: channel_layout.h:77
has_channel_names
static int has_channel_names(const AVChannelLayout *channel_layout)
Definition: channel_layout.c:695
AV_CHAN_TOP_SIDE_RIGHT
@ AV_CHAN_TOP_SIDE_RIGHT
Definition: channel_layout.h:78
AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK
#define AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK
Definition: channel_layout.h:413
AV_CHANNEL_LAYOUT_RETYPE_FLAG_LOSSLESS
#define AV_CHANNEL_LAYOUT_RETYPE_FLAG_LOSSLESS
The conversion must be lossless.
Definition: channel_layout.h:831
av_sscanf
int av_sscanf(const char *string, const char *format,...)
See libc sscanf manual for more information.
Definition: avsscanf.c:962
AV_CHANNEL_ORDER_AMBISONIC
@ AV_CHANNEL_ORDER_AMBISONIC
The audio is represented as the decomposition of the sound field into spherical harmonics.
Definition: channel_layout.h:148
NULL
#define NULL
Definition: coverity.c:32
AV_CHANNEL_LAYOUT_3POINT1POINT2
#define AV_CHANNEL_LAYOUT_3POINT1POINT2
Definition: channel_layout.h:404
channel_layout_name::layout
AVChannelLayout layout
Definition: channel_layout.c:174
AV_CHAN_TOP_BACK_CENTER
@ AV_CHAN_TOP_BACK_CENTER
Definition: channel_layout.h:66
channel_names
static const struct channel_name channel_names[]
Definition: channel_layout.c:46
AV_CHAN_BOTTOM_FRONT_RIGHT
@ AV_CHAN_BOTTOM_FRONT_RIGHT
Definition: channel_layout.h:81
av_get_channel_layout
uint64_t av_get_channel_layout(const char *name)
Return a channel layout id that matches name, or 0 if no match is found.
Definition: channel_layout.c:249
AV_CHAN_TOP_CENTER
@ AV_CHAN_TOP_CENTER
Definition: channel_layout.h:61
index
int index
Definition: gxfenc.c:89
AV_CHAN_FRONT_RIGHT_OF_CENTER
@ AV_CHAN_FRONT_RIGHT_OF_CENTER
Definition: channel_layout.h:57
AV_CHANNEL_LAYOUT_22POINT2
#define AV_CHANNEL_LAYOUT_22POINT2
Definition: channel_layout.h:424
error.h
AV_CHAN_FRONT_RIGHT
@ AV_CHAN_FRONT_RIGHT
Definition: channel_layout.h:51
AV_CHAN_FRONT_CENTER
@ AV_CHAN_FRONT_CENTER
Definition: channel_layout.h:52
channel_layout_map
static const struct channel_layout_name channel_layout_map[]
Definition: channel_layout.c:177
AV_CHANNEL_LAYOUT_5POINT1POINT2_BACK
#define AV_CHANNEL_LAYOUT_5POINT1POINT2_BACK
Definition: channel_layout.h:414
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:313
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
AV_CHAN_LOW_FREQUENCY
@ AV_CHAN_LOW_FREQUENCY
Definition: channel_layout.h:53
AV_CHAN_BACK_RIGHT
@ AV_CHAN_BACK_RIGHT
Definition: channel_layout.h:55
AV_CHAN_SIDE_LEFT
@ AV_CHAN_SIDE_LEFT
Definition: channel_layout.h:59
AV_CHAN_AMBISONIC_END
@ AV_CHAN_AMBISONIC_END
Definition: channel_layout.h:104
AV_CHANNEL_LAYOUT_6POINT0
#define AV_CHANNEL_LAYOUT_6POINT0
Definition: channel_layout.h:402
av_channel_description
int av_channel_description(char *buf, size_t buf_size, enum AVChannel channel_id)
Get a human readable string describing a given channel.
Definition: channel_layout.c:130
av_channel_layout_retype
int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
Change the AVChannelOrder of a channel layout.
Definition: channel_layout.c:1079
AV_CHAN_TOP_FRONT_RIGHT
@ AV_CHAN_TOP_FRONT_RIGHT
Definition: channel_layout.h:64
AV_CHANNEL_ORDER_NATIVE
@ AV_CHANNEL_ORDER_NATIVE
The native channel order, i.e.
Definition: channel_layout.h:118
AV_CHAN_FRONT_LEFT_OF_CENTER
@ AV_CHAN_FRONT_LEFT_OF_CENTER
Definition: channel_layout.h:56
av_channel_layout_compare
int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout *chl1)
Check whether two channel layouts are semantically the same, i.e.
Definition: channel_layout.c:1003
av_channel_layout_custom_init
FF_ENABLE_DEPRECATION_WARNINGS int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels)
Initialize a custom channel layout with the specified number of channels.
Definition: channel_layout.c:401
AV_CHANNEL_LAYOUT_HEXADECAGONAL
#define AV_CHANNEL_LAYOUT_HEXADECAGONAL
Definition: channel_layout.h:422
av_channel_layout_default
void av_channel_layout_default(AVChannelLayout *ch_layout, int nb_channels)
Get the default channel layout for a given number of channels.
Definition: channel_layout.c:1033
layout
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel layout
Definition: filter_design.txt:18
AV_CHANNEL_LAYOUT_6POINT1_BACK
#define AV_CHANNEL_LAYOUT_6POINT1_BACK
Definition: channel_layout.h:407
AVChannel
AVChannel
Definition: channel_layout.h:47
av_channel_layout_from_string
int av_channel_layout_from_string(AVChannelLayout *channel_layout, const char *str)
Initialize a channel layout from a given string description.
Definition: channel_layout.c:434
AV_CHANNEL_LAYOUT_CUBE
#define AV_CHANNEL_LAYOUT_CUBE
Definition: channel_layout.h:416
bprint.h
AV_CHAN_SURROUND_DIRECT_RIGHT
@ AV_CHAN_SURROUND_DIRECT_RIGHT
Definition: channel_layout.h:75
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:245
AV_CHANNEL_LAYOUT_QUAD
#define AV_CHANNEL_LAYOUT_QUAD
Definition: channel_layout.h:397
get_channel_layout_single
static FF_DISABLE_DEPRECATION_WARNINGS uint64_t get_channel_layout_single(const char *name, int name_len)
Definition: channel_layout.c:219
av_channel_name
int av_channel_name(char *buf, size_t buf_size, enum AVChannel channel_id)
Get a human readable string in an abbreviated form describing a given channel.
Definition: channel_layout.c:101
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
common.h
AV_CHANNEL_LAYOUT_7POINT0_FRONT
#define AV_CHANNEL_LAYOUT_7POINT0_FRONT
Definition: channel_layout.h:410
AV_CHANNEL_LAYOUT_5POINT1POINT4_BACK
#define AV_CHANNEL_LAYOUT_5POINT1POINT4_BACK
Definition: channel_layout.h:417
AV_CHANNEL_LAYOUT_3POINT1
#define AV_CHANNEL_LAYOUT_3POINT1
Definition: channel_layout.h:393
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AVChannelCustom::name
char name[16]
Definition: channel_layout.h:279
AV_CHAN_STEREO_LEFT
@ AV_CHAN_STEREO_LEFT
Stereo downmix.
Definition: channel_layout.h:69
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:262
av_bprint_channel_layout
void av_bprint_channel_layout(struct AVBPrint *bp, int nb_channels, uint64_t channel_layout)
Append a description of a channel layout to a bprint buffer.
Definition: channel_layout.c:287
ret
ret
Definition: filter_design.txt:187
av_channel_layout_check
int av_channel_layout_check(const AVChannelLayout *channel_layout)
Check whether a channel layout is valid, i.e.
Definition: channel_layout.c:977
AV_CHANNEL_LAYOUT_7POINT0
#define AV_CHANNEL_LAYOUT_7POINT0
Definition: channel_layout.h:409
av_opt_get_key_value
int av_opt_get_key_value(const char **ropts, const char *key_val_sep, const char *pairs_sep, unsigned flags, char **rkey, char **rval)
Extract a key-value pair from the beginning of a string.
Definition: opt.c:1645
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:99
id
enum AVCodecID id
Definition: dts2pts.c:364
AV_CHAN_BACK_CENTER
@ AV_CHAN_BACK_CENTER
Definition: channel_layout.h:58
av_channel_from_string
enum AVChannel av_channel_from_string(const char *str)
This is the inverse function of av_channel_name().
Definition: channel_layout.c:145
AV_CHANNEL_LAYOUT_2_1
#define AV_CHANNEL_LAYOUT_2_1
Definition: channel_layout.h:391
AV_CHAN_NONE
@ AV_CHAN_NONE
Invalid channel index.
Definition: channel_layout.h:49
AV_CHANNEL_ORDER_CUSTOM
@ AV_CHANNEL_ORDER_CUSTOM
The channel order does not correspond to any other predefined order and is stored as an explicit map.
Definition: channel_layout.h:125
channel_layout.h
AV_CHAN_LOW_FREQUENCY_2
@ AV_CHAN_LOW_FREQUENCY_2
Definition: channel_layout.h:76
av_channel_layout_subset
uint64_t av_channel_layout_subset(const AVChannelLayout *channel_layout, uint64_t mask)
Find out what channels from a given set are present in a channel layout, without regard for their pos...
Definition: channel_layout.c:1059
AV_CHAN_TOP_BACK_LEFT
@ AV_CHAN_TOP_BACK_LEFT
Definition: channel_layout.h:65
av_channel_layout_channel_from_string
enum AVChannel av_channel_layout_channel_from_string(const AVChannelLayout *channel_layout, const char *str)
Get a channel described by the given string.
Definition: channel_layout.c:896
av_channel_layout_index_from_channel
int av_channel_layout_index_from_channel(const AVChannelLayout *channel_layout, enum AVChannel channel)
Get the index of a given channel in a channel layout.
Definition: channel_layout.c:907
av_channel_layout_uninit
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
Definition: channel_layout.c:662
AV_CHAN_BACK_LEFT
@ AV_CHAN_BACK_LEFT
Definition: channel_layout.h:54
AV_CHANNEL_LAYOUT_6POINT0_FRONT
#define AV_CHANNEL_LAYOUT_6POINT0_FRONT
Definition: channel_layout.h:403
masked_description
static int64_t masked_description(const AVChannelLayout *channel_layout, int start_channel)
Definition: channel_layout.c:682
AV_CHAN_BOTTOM_FRONT_CENTER
@ AV_CHAN_BOTTOM_FRONT_CENTER
Definition: channel_layout.h:79
av_channel_layout_copy
int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src)
Make a copy of a channel layout.
Definition: channel_layout.c:669
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:72
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:270
AV_CHAN_TOP_FRONT_CENTER
@ AV_CHAN_TOP_FRONT_CENTER
Definition: channel_layout.h:63
AV_CHAN_WIDE_RIGHT
@ AV_CHAN_WIDE_RIGHT
Definition: channel_layout.h:73
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:388
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
AV_CHAN_TOP_FRONT_LEFT
@ AV_CHAN_TOP_FRONT_LEFT
Definition: channel_layout.h:62
AV_CHAN_AMBISONIC_BASE
@ AV_CHAN_AMBISONIC_BASE
Range of channels between AV_CHAN_AMBISONIC_BASE and AV_CHAN_AMBISONIC_END represent Ambisonic compon...
Definition: channel_layout.h:101
AV_CHANNEL_LAYOUT_5POINT1_BACK
#define AV_CHANNEL_LAYOUT_5POINT1_BACK
Definition: channel_layout.h:401
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
av_strlcpy
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:85
AV_CHANNEL_LAYOUT_6POINT1
#define AV_CHANNEL_LAYOUT_6POINT1
Definition: channel_layout.h:406
av_get_extended_channel_layout
int av_get_extended_channel_layout(const char *name, uint64_t *channel_layout, int *nb_channels)
Return a channel layout and the number of channels based on the specified name.
Definition: channel_layout.c:265
AV_CHANNEL_LAYOUT_5POINT0
#define AV_CHANNEL_LAYOUT_5POINT0
Definition: channel_layout.h:398
av_bprint_chars
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition: bprint.c:145
AV_CHAN_FRONT_LEFT
@ AV_CHAN_FRONT_LEFT
Definition: channel_layout.h:50
AV_CHANNEL_LAYOUT_5POINT1
#define AV_CHANNEL_LAYOUT_5POINT1
Definition: channel_layout.h:399
av_channel_name_bprint
void av_channel_name_bprint(AVBPrint *bp, enum AVChannel channel_id)
bprint variant of av_channel_name().
Definition: channel_layout.c:87
AVChannelLayout::u
union AVChannelLayout::@345 u
Details about which channels are present in this layout.
AVChannelCustom::id
enum AVChannel id
Definition: channel_layout.h:278
channel
channel
Definition: ebur128.h:39
av_get_default_channel_layout
int64_t av_get_default_channel_layout(int nb_channels)
Return default channel layout for a given number of channels.
Definition: channel_layout.c:335