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 
28 #include "avstring.h"
29 #include "avutil.h"
30 #include "channel_layout.h"
31 #include "bprint.h"
32 #include "common.h"
33 
34 struct channel_name {
35  const char *name;
36  const char *description;
37 };
38 
39 static const struct channel_name channel_names[] = {
40  [0] = { "FL", "front left" },
41  [1] = { "FR", "front right" },
42  [2] = { "FC", "front center" },
43  [3] = { "LFE", "low frequency" },
44  [4] = { "BL", "back left" },
45  [5] = { "BR", "back right" },
46  [6] = { "FLC", "front left-of-center" },
47  [7] = { "FRC", "front right-of-center" },
48  [8] = { "BC", "back center" },
49  [9] = { "SL", "side left" },
50  [10] = { "SR", "side right" },
51  [11] = { "TC", "top center" },
52  [12] = { "TFL", "top front left" },
53  [13] = { "TFC", "top front center" },
54  [14] = { "TFR", "top front right" },
55  [15] = { "TBL", "top back left" },
56  [16] = { "TBC", "top back center" },
57  [17] = { "TBR", "top back right" },
58  [29] = { "DL", "downmix left" },
59  [30] = { "DR", "downmix right" },
60  [31] = { "WL", "wide left" },
61  [32] = { "WR", "wide right" },
62  [33] = { "SDL", "surround direct left" },
63  [34] = { "SDR", "surround direct right" },
64  [35] = { "LFE2", "low frequency 2" },
65  [36] = { "TSL", "top side left" },
66  [37] = { "TSR", "top side right" },
67  [38] = { "BFC", "bottom front center" },
68  [39] = { "BFL", "bottom front left" },
69  [40] = { "BFR", "bottom front right" },
70 };
71 
72 static const char *get_channel_name(int channel_id)
73 {
74  if (channel_id < 0 || channel_id >= FF_ARRAY_ELEMS(channel_names))
75  return NULL;
76  return channel_names[channel_id].name;
77 }
78 
79 static const struct {
80  const char *name;
82  uint64_t layout;
83 } channel_layout_map[] = {
84  { "mono", 1, AV_CH_LAYOUT_MONO },
85  { "stereo", 2, AV_CH_LAYOUT_STEREO },
86  { "2.1", 3, AV_CH_LAYOUT_2POINT1 },
87  { "3.0", 3, AV_CH_LAYOUT_SURROUND },
88  { "3.0(back)", 3, AV_CH_LAYOUT_2_1 },
89  { "4.0", 4, AV_CH_LAYOUT_4POINT0 },
90  { "quad", 4, AV_CH_LAYOUT_QUAD },
91  { "quad(side)", 4, AV_CH_LAYOUT_2_2 },
92  { "3.1", 4, AV_CH_LAYOUT_3POINT1 },
93  { "5.0", 5, AV_CH_LAYOUT_5POINT0_BACK },
94  { "5.0(side)", 5, AV_CH_LAYOUT_5POINT0 },
95  { "4.1", 5, AV_CH_LAYOUT_4POINT1 },
96  { "5.1", 6, AV_CH_LAYOUT_5POINT1_BACK },
97  { "5.1(side)", 6, AV_CH_LAYOUT_5POINT1 },
98  { "6.0", 6, AV_CH_LAYOUT_6POINT0 },
99  { "6.0(front)", 6, AV_CH_LAYOUT_6POINT0_FRONT },
100  { "hexagonal", 6, AV_CH_LAYOUT_HEXAGONAL },
101  { "6.1", 7, AV_CH_LAYOUT_6POINT1 },
102  { "6.1(back)", 7, AV_CH_LAYOUT_6POINT1_BACK },
103  { "6.1(front)", 7, AV_CH_LAYOUT_6POINT1_FRONT },
104  { "7.0", 7, AV_CH_LAYOUT_7POINT0 },
105  { "7.0(front)", 7, AV_CH_LAYOUT_7POINT0_FRONT },
106  { "7.1", 8, AV_CH_LAYOUT_7POINT1 },
107  { "7.1(wide)", 8, AV_CH_LAYOUT_7POINT1_WIDE_BACK },
108  { "7.1(wide-side)", 8, AV_CH_LAYOUT_7POINT1_WIDE },
109  { "octagonal", 8, AV_CH_LAYOUT_OCTAGONAL },
110  { "hexadecagonal", 16, AV_CH_LAYOUT_HEXADECAGONAL },
111  { "downmix", 2, AV_CH_LAYOUT_STEREO_DOWNMIX, },
112  { "22.2", 24, AV_CH_LAYOUT_22POINT2, },
113 };
114 
115 static uint64_t get_channel_layout_single(const char *name, int name_len)
116 {
117  int i;
118  char *end;
119  int64_t layout;
120 
121  for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) {
122  if (strlen(channel_layout_map[i].name) == name_len &&
123  !memcmp(channel_layout_map[i].name, name, name_len))
124  return channel_layout_map[i].layout;
125  }
126  for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++)
127  if (channel_names[i].name &&
128  strlen(channel_names[i].name) == name_len &&
129  !memcmp(channel_names[i].name, name, name_len))
130  return (int64_t)1 << i;
131 
132  errno = 0;
133  i = strtol(name, &end, 10);
134 
135  if (!errno && (end + 1 - name == name_len && *end == 'c'))
137 
138  errno = 0;
139  layout = strtoll(name, &end, 0);
140  if (!errno && end - name == name_len)
141  return FFMAX(layout, 0);
142  return 0;
143 }
144 
145 uint64_t av_get_channel_layout(const char *name)
146 {
147  const char *n, *e;
148  const char *name_end = name + strlen(name);
149  int64_t layout = 0, layout_single;
150 
151  for (n = name; n < name_end; n = e + 1) {
152  for (e = n; e < name_end && *e != '+' && *e != '|'; e++);
153  layout_single = get_channel_layout_single(n, e - n);
154  if (!layout_single)
155  return 0;
156  layout |= layout_single;
157  }
158  return layout;
159 }
160 
161 int av_get_extended_channel_layout(const char *name, uint64_t* channel_layout, int* nb_channels)
162 {
163  int nb = 0;
164  char *end;
165  uint64_t layout = av_get_channel_layout(name);
166 
167  if (layout) {
168  *channel_layout = layout;
170  return 0;
171  }
172 
173  nb = strtol(name, &end, 10);
174  if (!errno && *end == 'C' && *(end + 1) == '\0' && nb > 0 && nb < 64) {
175  *channel_layout = 0;
176  *nb_channels = nb;
177  return 0;
178  }
179 
180  return AVERROR(EINVAL);
181 }
182 
183 void av_bprint_channel_layout(struct AVBPrint *bp,
184  int nb_channels, uint64_t channel_layout)
185 {
186  int i;
187 
188  if (nb_channels <= 0)
190 
191  for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
193  channel_layout == channel_layout_map[i].layout) {
194  av_bprintf(bp, "%s", channel_layout_map[i].name);
195  return;
196  }
197 
198  av_bprintf(bp, "%d channels", nb_channels);
199  if (channel_layout) {
200  int i, ch;
201  av_bprintf(bp, " (");
202  for (i = 0, ch = 0; i < 64; i++) {
203  if ((channel_layout & (UINT64_C(1) << i))) {
204  const char *name = get_channel_name(i);
205  if (name) {
206  if (ch > 0)
207  av_bprintf(bp, "+");
208  av_bprintf(bp, "%s", name);
209  }
210  ch++;
211  }
212  }
213  av_bprintf(bp, ")");
214  }
215 }
216 
217 void av_get_channel_layout_string(char *buf, int buf_size,
218  int nb_channels, uint64_t channel_layout)
219 {
220  AVBPrint bp;
221 
222  av_bprint_init_for_buffer(&bp, buf, buf_size);
223  av_bprint_channel_layout(&bp, nb_channels, channel_layout);
224 }
225 
226 int av_get_channel_layout_nb_channels(uint64_t channel_layout)
227 {
228  return av_popcount64(channel_layout);
229 }
230 
232  int i;
233  for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
235  return channel_layout_map[i].layout;
236  return 0;
237 }
238 
239 int av_get_channel_layout_channel_index(uint64_t channel_layout,
240  uint64_t channel)
241 {
242  if (!(channel_layout & channel) ||
244  return AVERROR(EINVAL);
245  channel_layout &= channel - 1;
246  return av_get_channel_layout_nb_channels(channel_layout);
247 }
248 
249 const char *av_get_channel_name(uint64_t channel)
250 {
251  int i;
253  return NULL;
254  for (i = 0; i < 64; i++)
255  if ((1ULL<<i) & channel)
256  return get_channel_name(i);
257  return NULL;
258 }
259 
260 const char *av_get_channel_description(uint64_t channel)
261 {
262  int i;
264  return NULL;
265  for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++)
266  if ((1ULL<<i) & channel)
267  return channel_names[i].description;
268  return NULL;
269 }
270 
271 uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
272 {
273  int i;
274 
275  if (av_get_channel_layout_nb_channels(channel_layout) <= index)
276  return 0;
277 
278  for (i = 0; i < 64; i++) {
279  if ((1ULL << i) & channel_layout && !index--)
280  return 1ULL << i;
281  }
282  return 0;
283 }
284 
286  const char **name)
287 {
289  return AVERROR_EOF;
290  if (layout) *layout = channel_layout_map[index].layout;
291  if (name) *name = channel_layout_map[index].name;
292  return 0;
293 }
AV_CH_LAYOUT_7POINT0
#define AV_CH_LAYOUT_7POINT0
Definition: channel_layout.h:110
AV_CH_LAYOUT_6POINT1
#define AV_CH_LAYOUT_6POINT1
Definition: channel_layout.h:107
AV_CH_LAYOUT_7POINT1_WIDE_BACK
#define AV_CH_LAYOUT_7POINT1_WIDE_BACK
Definition: channel_layout.h:114
AV_CH_LAYOUT_5POINT0_BACK
#define AV_CH_LAYOUT_5POINT0_BACK
Definition: channel_layout.h:102
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
AV_CH_LAYOUT_HEXADECAGONAL
#define AV_CH_LAYOUT_HEXADECAGONAL
Definition: channel_layout.h:116
av_popcount64
#define av_popcount64
Definition: common.h:179
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:55
AV_CH_LAYOUT_MONO
#define AV_CH_LAYOUT_MONO
Definition: channel_layout.h:90
av_get_channel_layout_string
void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout)
Return a description of a channel layout.
Definition: channel_layout.c:217
AV_CH_LAYOUT_HEXAGONAL
#define AV_CH_LAYOUT_HEXAGONAL
Definition: channel_layout.h:106
AV_CH_LAYOUT_6POINT0_FRONT
#define AV_CH_LAYOUT_6POINT0_FRONT
Definition: channel_layout.h:105
AV_CH_LAYOUT_6POINT1_FRONT
#define AV_CH_LAYOUT_6POINT1_FRONT
Definition: channel_layout.h:109
av_get_channel_layout
uint64_t av_get_channel_layout(const char *name)
Return a channel layout id that matches name, or 0 if no match is found.
Definition: channel_layout.c:145
channel_name
Definition: channel_layout.c:34
channel_name::description
const char * description
Definition: channel_layout.c:36
AV_CH_LAYOUT_6POINT0
#define AV_CH_LAYOUT_6POINT0
Definition: channel_layout.h:104
channel_name::name
const char * name
Definition: channel_layout.c:35
AV_CH_LAYOUT_STEREO
#define AV_CH_LAYOUT_STEREO
Definition: channel_layout.h:91
AV_CH_LAYOUT_QUAD
#define AV_CH_LAYOUT_QUAD
Definition: channel_layout.h:99
description
Tag description
Definition: snow.txt:206
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
AV_CH_LAYOUT_22POINT2
#define AV_CH_LAYOUT_22POINT2
Definition: channel_layout.h:118
av_bprint_channel_layout
void av_bprint_channel_layout(struct AVBPrint *bp, int nb_channels, uint64_t channel_layout)
Append a description of a channel layout to a bprint buffer.
Definition: channel_layout.c:183
AV_CH_LAYOUT_7POINT0_FRONT
#define AV_CH_LAYOUT_7POINT0_FRONT
Definition: channel_layout.h:111
AV_CH_LAYOUT_STEREO_DOWNMIX
#define AV_CH_LAYOUT_STEREO_DOWNMIX
Definition: channel_layout.h:117
av_get_channel_name
const char * av_get_channel_name(uint64_t channel)
Get the name of a given channel.
Definition: channel_layout.c:249
name
const char * name
Definition: channel_layout.c:80
AV_CH_LAYOUT_2_1
#define AV_CH_LAYOUT_2_1
Definition: channel_layout.h:93
NULL
#define NULL
Definition: coverity.c:32
AV_CH_LAYOUT_5POINT1
#define AV_CH_LAYOUT_5POINT1
Definition: channel_layout.h:101
channel_names
static const struct channel_name channel_names[]
Definition: channel_layout.c:39
av_get_standard_channel_layout
int av_get_standard_channel_layout(unsigned index, uint64_t *layout, const char **name)
Get the value and name of a standard channel layout.
Definition: channel_layout.c:285
index
int index
Definition: gxfenc.c:89
av_get_channel_layout_nb_channels
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
Definition: channel_layout.c:226
FFMAX
#define FFMAX(a, b)
Definition: common.h:103
AV_CH_LAYOUT_5POINT1_BACK
#define AV_CH_LAYOUT_5POINT1_BACK
Definition: channel_layout.h:103
AV_CH_LAYOUT_3POINT1
#define AV_CH_LAYOUT_3POINT1
Definition: channel_layout.h:95
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_CH_LAYOUT_OCTAGONAL
#define AV_CH_LAYOUT_OCTAGONAL
Definition: channel_layout.h:115
AV_CH_LAYOUT_5POINT0
#define AV_CH_LAYOUT_5POINT0
Definition: channel_layout.h:100
bprint.h
i
int i
Definition: input.c:407
AV_CH_LAYOUT_2POINT1
#define AV_CH_LAYOUT_2POINT1
Definition: channel_layout.h:92
av_channel_layout_extract_channel
uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
Get the channel with the given index in channel_layout.
Definition: channel_layout.c:271
common.h
av_get_channel_layout_channel_index
int av_get_channel_layout_channel_index(uint64_t channel_layout, uint64_t channel)
Get the index of a channel in channel_layout.
Definition: channel_layout.c:239
AV_CH_LAYOUT_7POINT1
#define AV_CH_LAYOUT_7POINT1
Definition: channel_layout.h:112
AV_CH_LAYOUT_4POINT1
#define AV_CH_LAYOUT_4POINT1
Definition: channel_layout.h:97
AV_CH_LAYOUT_7POINT1_WIDE
#define AV_CH_LAYOUT_7POINT1_WIDE
Definition: channel_layout.h:113
AV_CH_LAYOUT_SURROUND
#define AV_CH_LAYOUT_SURROUND
Definition: channel_layout.h:94
layout
uint64_t layout
Definition: channel_layout.c:82
get_channel_layout_single
static uint64_t get_channel_layout_single(const char *name, int name_len)
Definition: channel_layout.c:115
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:94
av_get_channel_description
const char * av_get_channel_description(uint64_t channel)
Get the description of a given channel.
Definition: channel_layout.c:260
channel_layout.h
av_get_extended_channel_layout
int av_get_extended_channel_layout(const char *name, uint64_t *channel_layout, int *nb_channels)
Return a channel layout and the number of channels based on the specified name.
Definition: channel_layout.c:161
get_channel_name
static const char * get_channel_name(int channel_id)
Definition: channel_layout.c:72
avutil.h
av_get_default_channel_layout
int64_t av_get_default_channel_layout(int nb_channels)
Return default channel layout for a given number of channels.
Definition: channel_layout.c:231
AV_CH_LAYOUT_4POINT0
#define AV_CH_LAYOUT_4POINT0
Definition: channel_layout.h:96
AV_CH_LAYOUT_6POINT1_BACK
#define AV_CH_LAYOUT_6POINT1_BACK
Definition: channel_layout.h:108
channel_layout_map
static const struct @289 channel_layout_map[]
avstring.h
AV_CH_LAYOUT_2_2
#define AV_CH_LAYOUT_2_2
Definition: channel_layout.h:98
channel
channel
Definition: ebur128.h:39
nb_channels
int nb_channels
Definition: channel_layout.c:81