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