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