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 "avstring.h"
27 #include "avutil.h"
28 #include "channel_layout.h"
29 #include "bprint.h"
30 #include "common.h"
31 
32 struct channel_name {
33  const char *name;
34  const char *description;
35 };
36 
37 static const struct channel_name channel_names[] = {
38  [0] = { "FL", "front left" },
39  [1] = { "FR", "front right" },
40  [2] = { "FC", "front center" },
41  [3] = { "LFE", "low frequency" },
42  [4] = { "BL", "back left" },
43  [5] = { "BR", "back right" },
44  [6] = { "FLC", "front left-of-center" },
45  [7] = { "FRC", "front right-of-center" },
46  [8] = { "BC", "back center" },
47  [9] = { "SL", "side left" },
48  [10] = { "SR", "side right" },
49  [11] = { "TC", "top center" },
50  [12] = { "TFL", "top front left" },
51  [13] = { "TFC", "top front center" },
52  [14] = { "TFR", "top front right" },
53  [15] = { "TBL", "top back left" },
54  [16] = { "TBC", "top back center" },
55  [17] = { "TBR", "top back right" },
56  [29] = { "DL", "downmix left" },
57  [30] = { "DR", "downmix right" },
58  [31] = { "WL", "wide left" },
59  [32] = { "WR", "wide right" },
60  [33] = { "SDL", "surround direct left" },
61  [34] = { "SDR", "surround direct right" },
62  [35] = { "LFE2", "low frequency 2" },
63 };
64 
65 static const char *get_channel_name(int channel_id)
66 {
67  if (channel_id < 0 || channel_id >= FF_ARRAY_ELEMS(channel_names))
68  return NULL;
69  return channel_names[channel_id].name;
70 }
71 
72 static const struct {
73  const char *name;
75  uint64_t layout;
76 } channel_layout_map[] = {
77  { "mono", 1, AV_CH_LAYOUT_MONO },
78  { "stereo", 2, AV_CH_LAYOUT_STEREO },
79  { "2.1", 3, AV_CH_LAYOUT_2POINT1 },
80  { "3.0", 3, AV_CH_LAYOUT_SURROUND },
81  { "3.0(back)", 3, AV_CH_LAYOUT_2_1 },
82  { "4.0", 4, AV_CH_LAYOUT_4POINT0 },
83  { "quad", 4, AV_CH_LAYOUT_QUAD },
84  { "quad(side)", 4, AV_CH_LAYOUT_2_2 },
85  { "3.1", 4, AV_CH_LAYOUT_3POINT1 },
86  { "5.0", 5, AV_CH_LAYOUT_5POINT0_BACK },
87  { "5.0(side)", 5, AV_CH_LAYOUT_5POINT0 },
88  { "4.1", 5, AV_CH_LAYOUT_4POINT1 },
89  { "5.1", 6, AV_CH_LAYOUT_5POINT1_BACK },
90  { "5.1(side)", 6, AV_CH_LAYOUT_5POINT1 },
91  { "6.0", 6, AV_CH_LAYOUT_6POINT0 },
92  { "6.0(front)", 6, AV_CH_LAYOUT_6POINT0_FRONT },
93  { "hexagonal", 6, AV_CH_LAYOUT_HEXAGONAL },
94  { "6.1", 7, AV_CH_LAYOUT_6POINT1 },
95  { "6.1", 7, AV_CH_LAYOUT_6POINT1_BACK },
96  { "6.1(front)", 7, AV_CH_LAYOUT_6POINT1_FRONT },
97  { "7.0", 7, AV_CH_LAYOUT_7POINT0 },
98  { "7.0(front)", 7, AV_CH_LAYOUT_7POINT0_FRONT },
99  { "7.1", 8, AV_CH_LAYOUT_7POINT1 },
100  { "7.1(wide)", 8, AV_CH_LAYOUT_7POINT1_WIDE_BACK },
101  { "7.1(wide-side)", 8, AV_CH_LAYOUT_7POINT1_WIDE },
102  { "octagonal", 8, AV_CH_LAYOUT_OCTAGONAL },
103  { "downmix", 2, AV_CH_LAYOUT_STEREO_DOWNMIX, },
104 };
105 
106 static uint64_t get_channel_layout_single(const char *name, int name_len)
107 {
108  int i;
109  char *end;
110  int64_t layout;
111 
112  for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) {
113  if (strlen(channel_layout_map[i].name) == name_len &&
114  !memcmp(channel_layout_map[i].name, name, name_len))
115  return channel_layout_map[i].layout;
116  }
117  for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++)
118  if (channel_names[i].name &&
119  strlen(channel_names[i].name) == name_len &&
120  !memcmp(channel_names[i].name, name, name_len))
121  return (int64_t)1 << i;
122  i = strtol(name, &end, 10);
123  if (end - name == name_len ||
124  (end + 1 - name == name_len && *end == 'c'))
126  layout = strtoll(name, &end, 0);
127  if (end - name == name_len)
128  return FFMAX(layout, 0);
129  return 0;
130 }
131 
132 uint64_t av_get_channel_layout(const char *name)
133 {
134  const char *n, *e;
135  const char *name_end = name + strlen(name);
136  int64_t layout = 0, layout_single;
137 
138  for (n = name; n < name_end; n = e + 1) {
139  for (e = n; e < name_end && *e != '+' && *e != '|'; e++);
140  layout_single = get_channel_layout_single(n, e - n);
141  if (!layout_single)
142  return 0;
143  layout |= layout_single;
144  }
145  return layout;
146 }
147 
149  int nb_channels, uint64_t channel_layout)
150 {
151  int i;
152 
153  if (nb_channels <= 0)
154  nb_channels = av_get_channel_layout_nb_channels(channel_layout);
155 
156  for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
157  if (nb_channels == channel_layout_map[i].nb_channels &&
158  channel_layout == channel_layout_map[i].layout) {
159  av_bprintf(bp, "%s", channel_layout_map[i].name);
160  return;
161  }
162 
163  av_bprintf(bp, "%d channels", nb_channels);
164  if (channel_layout) {
165  int i, ch;
166  av_bprintf(bp, " (");
167  for (i = 0, ch = 0; i < 64; i++) {
168  if ((channel_layout & (UINT64_C(1) << i))) {
169  const char *name = get_channel_name(i);
170  if (name) {
171  if (ch > 0)
172  av_bprintf(bp, "+");
173  av_bprintf(bp, "%s", name);
174  }
175  ch++;
176  }
177  }
178  av_bprintf(bp, ")");
179  }
180 }
181 
182 void av_get_channel_layout_string(char *buf, int buf_size,
183  int nb_channels, uint64_t channel_layout)
184 {
185  AVBPrint bp;
186 
187  av_bprint_init_for_buffer(&bp, buf, buf_size);
188  av_bprint_channel_layout(&bp, nb_channels, channel_layout);
189 }
190 
191 int av_get_channel_layout_nb_channels(uint64_t channel_layout)
192 {
193  return av_popcount64(channel_layout);
194 }
195 
197  int i;
198  for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
199  if (nb_channels == channel_layout_map[i].nb_channels)
200  return channel_layout_map[i].layout;
201  return 0;
202 }
203 
204 int av_get_channel_layout_channel_index(uint64_t channel_layout,
205  uint64_t channel)
206 {
207  if (!(channel_layout & channel) ||
208  av_get_channel_layout_nb_channels(channel) != 1)
209  return AVERROR(EINVAL);
210  channel_layout &= channel - 1;
211  return av_get_channel_layout_nb_channels(channel_layout);
212 }
213 
214 const char *av_get_channel_name(uint64_t channel)
215 {
216  int i;
217  if (av_get_channel_layout_nb_channels(channel) != 1)
218  return NULL;
219  for (i = 0; i < 64; i++)
220  if ((1ULL<<i) & channel)
221  return get_channel_name(i);
222  return NULL;
223 }
224 
225 const char *av_get_channel_description(uint64_t channel)
226 {
227  int i;
228  if (av_get_channel_layout_nb_channels(channel) != 1)
229  return NULL;
230  for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++)
231  if ((1ULL<<i) & channel)
232  return channel_names[i].description;
233  return NULL;
234 }
235 
236 uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
237 {
238  int i;
239 
240  if (av_get_channel_layout_nb_channels(channel_layout) <= index)
241  return 0;
242 
243  for (i = 0; i < 64; i++) {
244  if ((1ULL << i) & channel_layout && !index--)
245  return 1ULL << i;
246  }
247  return 0;
248 }
249 
251  const char **name)
252 {
253  if (index >= FF_ARRAY_ELEMS(channel_layout_map))
254  return AVERROR_EOF;
255  if (layout) *layout = channel_layout_map[index].layout;
256  if (name) *name = channel_layout_map[index].name;
257  return 0;
258 }
#define AV_CH_LAYOUT_7POINT1
#define AV_CH_LAYOUT_4POINT1
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:93
#define AV_CH_LAYOUT_6POINT1
#define AV_CH_LAYOUT_6POINT0
#define AV_CH_LAYOUT_SURROUND
static const char * get_channel_name(int channel_id)
external API header
#define AV_CH_LAYOUT_7POINT0_FRONT
#define AV_CH_LAYOUT_4POINT0
#define AV_CH_LAYOUT_7POINT0
#define FF_ARRAY_ELEMS(a)
#define AV_CH_LAYOUT_STEREO
const char * description
int av_get_standard_channel_layout(unsigned index, uint64_t *layout, const char **name)
Get the value and name of a standard channel layout.
#define AV_CH_LAYOUT_5POINT0
const char * name
const char * av_get_channel_description(uint64_t channel)
Get the description of a given channel.
uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
Get the channel with the given index in channel_layout.
end end
#define AV_CH_LAYOUT_HEXAGONAL
void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size)
Init a print buffer using a pre-existing buffer.
Definition: bprint.c:84
int av_get_channel_layout_channel_index(uint64_t channel_layout, uint64_t channel)
Get the index of a channel in channel_layout.
#define AVERROR_EOF
End of file.
Definition: error.h:55
#define AV_CH_LAYOUT_5POINT1
static const struct channel_name channel_names[]
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
#define AV_CH_LAYOUT_QUAD
const char * av_get_channel_name(uint64_t channel)
Get the name of a given channel.
#define FFMAX(a, b)
Definition: common.h:56
#define AV_CH_LAYOUT_2_1
#define AV_CH_LAYOUT_2_2
#define AV_CH_LAYOUT_6POINT0_FRONT
Buffer to print data progressively.
Definition: bprint.h:75
audio channel layout utility functions
#define AV_CH_LAYOUT_STEREO_DOWNMIX
#define AV_CH_LAYOUT_3POINT1
#define AV_CH_LAYOUT_5POINT1_BACK
#define AV_CH_LAYOUT_6POINT1_BACK
NULL
Definition: eval.c:55
void * buf
Definition: avisynth_c.h:594
#define AV_CH_LAYOUT_7POINT1_WIDE_BACK
int index
Definition: gxfenc.c:89
synthesis window for stochastic i
#define AV_CH_LAYOUT_5POINT0_BACK
#define AV_CH_LAYOUT_OCTAGONAL
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
#define AV_CH_LAYOUT_7POINT1_WIDE
static const struct @161 channel_layout_map[]
common internal and external API header
#define AV_CH_LAYOUT_2POINT1
static uint64_t get_channel_layout_single(const char *name, int name_len)
uint64_t av_get_channel_layout(const char *name)
Return a channel layout id that matches name, or 0 if no match is found.
uint64_t layout
#define AV_CH_LAYOUT_6POINT1_FRONT
int nb_channels
#define AV_CH_LAYOUT_MONO
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.
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.
int64_t av_get_default_channel_layout(int nb_channels)
Return default channel layout for a given number of channels.