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