1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/base/channel_layout.h"
7 #include "base/basictypes.h"
8 #include "base/logging.h"
12 static const int kLayoutToChannels
[] = {
13 0, // CHANNEL_LAYOUT_NONE
14 0, // CHANNEL_LAYOUT_UNSUPPORTED
15 1, // CHANNEL_LAYOUT_MONO
16 2, // CHANNEL_LAYOUT_STEREO
17 3, // CHANNEL_LAYOUT_2_1
18 3, // CHANNEL_LAYOUT_SURROUND
19 4, // CHANNEL_LAYOUT_4_0
20 4, // CHANNEL_LAYOUT_2_2
21 4, // CHANNEL_LAYOUT_QUAD
22 5, // CHANNEL_LAYOUT_5_0
23 6, // CHANNEL_LAYOUT_5_1
24 5, // CHANNEL_LAYOUT_5_0_BACK
25 6, // CHANNEL_LAYOUT_5_1_BACK
26 7, // CHANNEL_LAYOUT_7_0
27 8, // CHANNEL_LAYOUT_7_1
28 8, // CHANNEL_LAYOUT_7_1_WIDE
29 2, // CHANNEL_LAYOUT_STEREO_DOWNMIX
30 3, // CHANNEL_LAYOUT_2POINT1
31 4, // CHANNEL_LAYOUT_3_1
32 5, // CHANNEL_LAYOUT_4_1
33 6, // CHANNEL_LAYOUT_6_0
34 6, // CHANNEL_LAYOUT_6_0_FRONT
35 6, // CHANNEL_LAYOUT_HEXAGONAL
36 7, // CHANNEL_LAYOUT_6_1
37 7, // CHANNEL_LAYOUT_6_1_BACK
38 7, // CHANNEL_LAYOUT_6_1_FRONT
39 7, // CHANNEL_LAYOUT_7_0_FRONT
40 8, // CHANNEL_LAYOUT_7_1_WIDE_BACK
41 8, // CHANNEL_LAYOUT_OCTAGONAL
42 0, // CHANNEL_LAYOUT_DISCRETE
43 3, // CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC
44 5, // CHANNEL_LAYOUT_4_1_QUAD_SIDE
47 // The channel orderings for each layout as specified by FFmpeg. Each value
48 // represents the index of each channel in each layout. Values of -1 mean the
49 // channel at that index is not used for that layout. For example, the left side
50 // surround sound channel in FFmpeg's 5.1 layout is in the 5th position (because
51 // the order is L, R, C, LFE, LS, RS), so
52 // kChannelOrderings[CHANNEL_LAYOUT_5_1][SIDE_LEFT] = 4;
53 static const int kChannelOrderings
[CHANNEL_LAYOUT_MAX
+ 1][CHANNELS_MAX
+ 1] = {
54 // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
56 // CHANNEL_LAYOUT_NONE
57 { -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
59 // CHANNEL_LAYOUT_UNSUPPORTED
60 { -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
62 // CHANNEL_LAYOUT_MONO
63 { -1 , -1 , 0 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
65 // CHANNEL_LAYOUT_STEREO
66 { 0 , 1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
69 { 0 , 1 , -1 , -1 , -1 , -1 , -1 , -1 , 2 , -1 , -1 },
71 // CHANNEL_LAYOUT_SURROUND
72 { 0 , 1 , 2 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
75 { 0 , 1 , 2 , -1 , -1 , -1 , -1 , -1 , 3 , -1 , -1 },
78 { 0 , 1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , 2 , 3 },
80 // CHANNEL_LAYOUT_QUAD
81 { 0 , 1 , -1 , -1 , 2 , 3 , -1 , -1 , -1 , -1 , -1 },
84 { 0 , 1 , 2 , -1 , -1 , -1 , -1 , -1 , -1 , 3 , 4 },
87 { 0 , 1 , 2 , 3 , -1 , -1 , -1 , -1 , -1 , 4 , 5 },
89 // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
91 // CHANNEL_LAYOUT_5_0_BACK
92 { 0 , 1 , 2 , -1 , 3 , 4 , -1 , -1 , -1 , -1 , -1 },
94 // CHANNEL_LAYOUT_5_1_BACK
95 { 0 , 1 , 2 , 3 , 4 , 5 , -1 , -1 , -1 , -1 , -1 },
98 { 0 , 1 , 2 , -1 , 5 , 6 , -1 , -1 , -1 , 3 , 4 },
100 // CHANNEL_LAYOUT_7_1
101 { 0 , 1 , 2 , 3 , 6 , 7 , -1 , -1 , -1 , 4 , 5 },
103 // CHANNEL_LAYOUT_7_1_WIDE
104 { 0 , 1 , 2 , 3 , -1 , -1 , 6 , 7 , -1 , 4 , 5 },
106 // CHANNEL_LAYOUT_STEREO_DOWNMIX
107 { 0 , 1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
109 // CHANNEL_LAYOUT_2POINT1
110 { 0 , 1 , -1 , 2 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
112 // CHANNEL_LAYOUT_3_1
113 { 0 , 1 , 2 , 3 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
115 // CHANNEL_LAYOUT_4_1
116 { 0 , 1 , 2 , 4 , -1 , -1 , -1 , -1 , 3 , -1 , -1 },
118 // CHANNEL_LAYOUT_6_0
119 { 0 , 1 , 2 , -1 , -1 , -1 , -1 , -1 , 5 , 3 , 4 },
121 // CHANNEL_LAYOUT_6_0_FRONT
122 { 0 , 1 , -1 , -1 , -1 , -1 , 4 , 5 , -1 , 2 , 3 },
124 // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
126 // CHANNEL_LAYOUT_HEXAGONAL
127 { 0 , 1 , 2 , -1 , 3 , 4 , -1 , -1 , 5 , -1 , -1 },
129 // CHANNEL_LAYOUT_6_1
130 { 0 , 1 , 2 , 3 , -1 , -1 , -1 , -1 , 6 , 4 , 5 },
132 // CHANNEL_LAYOUT_6_1_BACK
133 { 0 , 1 , 2 , 3 , 4 , 5 , -1 , -1 , 6 , -1 , -1 },
135 // CHANNEL_LAYOUT_6_1_FRONT
136 { 0 , 1 , -1 , 6 , -1 , -1 , 4 , 5 , -1 , 2 , 3 },
138 // CHANNEL_LAYOUT_7_0_FRONT
139 { 0 , 1 , 2 , -1 , -1 , -1 , 5 , 6 , -1 , 3 , 4 },
141 // CHANNEL_LAYOUT_7_1_WIDE_BACK
142 { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , -1 , -1 , -1 },
144 // CHANNEL_LAYOUT_OCTAGONAL
145 { 0 , 1 , 2 , -1 , 5 , 6 , -1 , -1 , 7 , 3 , 4 },
147 // CHANNEL_LAYOUT_DISCRETE
148 { -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
150 // CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC
151 { 0 , 1 , 2 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
153 // CHANNEL_LAYOUT_4_1_QUAD_SIDE
154 { 0 , 1 , -1 , 4 , -1 , -1 , -1 , -1 , -1 , 2 , 3 },
156 // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
159 int ChannelLayoutToChannelCount(ChannelLayout layout
) {
160 DCHECK_LT(static_cast<size_t>(layout
), arraysize(kLayoutToChannels
));
161 return kLayoutToChannels
[layout
];
164 // Converts a channel count into a channel layout.
165 ChannelLayout
GuessChannelLayout(int channels
) {
168 return CHANNEL_LAYOUT_MONO
;
170 return CHANNEL_LAYOUT_STEREO
;
172 return CHANNEL_LAYOUT_SURROUND
;
174 return CHANNEL_LAYOUT_QUAD
;
176 return CHANNEL_LAYOUT_5_0
;
178 return CHANNEL_LAYOUT_5_1
;
180 return CHANNEL_LAYOUT_6_1
;
182 return CHANNEL_LAYOUT_7_1
;
184 DVLOG(1) << "Unsupported channel count: " << channels
;
186 return CHANNEL_LAYOUT_UNSUPPORTED
;
189 int ChannelOrder(ChannelLayout layout
, Channels channel
) {
190 DCHECK_LT(static_cast<size_t>(layout
), arraysize(kChannelOrderings
));
191 DCHECK_LT(static_cast<size_t>(channel
), arraysize(kChannelOrderings
[0]));
192 return kChannelOrderings
[layout
][channel
];
195 const char* ChannelLayoutToString(ChannelLayout layout
) {
197 case CHANNEL_LAYOUT_NONE
:
199 case CHANNEL_LAYOUT_UNSUPPORTED
:
200 return "UNSUPPORTED";
201 case CHANNEL_LAYOUT_MONO
:
203 case CHANNEL_LAYOUT_STEREO
:
205 case CHANNEL_LAYOUT_2_1
:
207 case CHANNEL_LAYOUT_SURROUND
:
209 case CHANNEL_LAYOUT_4_0
:
211 case CHANNEL_LAYOUT_2_2
:
213 case CHANNEL_LAYOUT_QUAD
:
215 case CHANNEL_LAYOUT_5_0
:
217 case CHANNEL_LAYOUT_5_1
:
219 case CHANNEL_LAYOUT_5_0_BACK
:
221 case CHANNEL_LAYOUT_5_1_BACK
:
223 case CHANNEL_LAYOUT_7_0
:
225 case CHANNEL_LAYOUT_7_1
:
227 case CHANNEL_LAYOUT_7_1_WIDE
:
229 case CHANNEL_LAYOUT_STEREO_DOWNMIX
:
230 return "STEREO_DOWNMIX";
231 case CHANNEL_LAYOUT_2POINT1
:
233 case CHANNEL_LAYOUT_3_1
:
235 case CHANNEL_LAYOUT_4_1
:
237 case CHANNEL_LAYOUT_6_0
:
239 case CHANNEL_LAYOUT_6_0_FRONT
:
241 case CHANNEL_LAYOUT_HEXAGONAL
:
243 case CHANNEL_LAYOUT_6_1
:
245 case CHANNEL_LAYOUT_6_1_BACK
:
247 case CHANNEL_LAYOUT_6_1_FRONT
:
249 case CHANNEL_LAYOUT_7_0_FRONT
:
251 case CHANNEL_LAYOUT_7_1_WIDE_BACK
:
252 return "7.1_WIDE_BACK";
253 case CHANNEL_LAYOUT_OCTAGONAL
:
255 case CHANNEL_LAYOUT_DISCRETE
:
257 case CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC
:
258 return "STEREO_AND_KEYBOARD_MIC";
259 case CHANNEL_LAYOUT_4_1_QUAD_SIDE
:
260 return "4.1_QUAD_SIDE";
262 NOTREACHED() << "Invalid channel layout provided: " << layout
;