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
46 // The channel orderings for each layout as specified by FFmpeg. Each value
47 // represents the index of each channel in each layout. Values of -1 mean the
48 // channel at that index is not used for that layout. For example, the left side
49 // surround sound channel in FFmpeg's 5.1 layout is in the 5th position (because
50 // the order is L, R, C, LFE, LS, RS), so
51 // kChannelOrderings[CHANNEL_LAYOUT_5POINT1][SIDE_LEFT] = 4;
52 static const int kChannelOrderings[CHANNEL_LAYOUT_MAX + 1][CHANNELS_MAX + 1] = {
53 // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
55 // CHANNEL_LAYOUT_NONE
56 { -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
58 // CHANNEL_LAYOUT_UNSUPPORTED
59 { -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
61 // CHANNEL_LAYOUT_MONO
62 { -1 , -1 , 0 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
64 // CHANNEL_LAYOUT_STEREO
65 { 0 , 1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
68 { 0 , 1 , -1 , -1 , -1 , -1 , -1 , -1 , 2 , -1 , -1 },
70 // CHANNEL_LAYOUT_SURROUND
71 { 0 , 1 , 2 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
74 { 0 , 1 , 2 , -1 , -1 , -1 , -1 , -1 , 3 , -1 , -1 },
77 { 0 , 1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , 2 , 3 },
79 // CHANNEL_LAYOUT_QUAD
80 { 0 , 1 , -1 , -1 , 2 , 3 , -1 , -1 , -1 , -1 , -1 },
83 { 0 , 1 , 2 , -1 , -1 , -1 , -1 , -1 , -1 , 3 , 4 },
86 { 0 , 1 , 2 , 3 , -1 , -1 , -1 , -1 , -1 , 4 , 5 },
88 // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
90 // CHANNEL_LAYOUT_5_0_BACK
91 { 0 , 1 , 2 , -1 , 3 , 4 , -1 , -1 , -1 , -1 , -1 },
93 // CHANNEL_LAYOUT_5_1_BACK
94 { 0 , 1 , 2 , 3 , 4 , 5 , -1 , -1 , -1 , -1 , -1 },
97 { 0 , 1 , 2 , -1 , 5 , 6 , -1 , -1 , -1 , 3 , 4 },
100 { 0 , 1 , 2 , 3 , 6 , 7 , -1 , -1 , -1 , 4 , 5 },
102 // CHANNEL_LAYOUT_7_1_WIDE
103 { 0 , 1 , 2 , 3 , -1 , -1 , 6 , 7 , -1 , 4 , 5 },
105 // CHANNEL_LAYOUT_STEREO_DOWNMIX
106 { 0 , 1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
108 // CHANNEL_LAYOUT_2POINT1
109 { 0 , 1 , -1 , 2 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
111 // CHANNEL_LAYOUT_3_1
112 { 0 , 1 , 2 , 3 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
114 // CHANNEL_LAYOUT_4_1
115 { 0 , 1 , 2 , 4 , -1 , -1 , -1 , -1 , 3 , -1 , -1 },
117 // CHANNEL_LAYOUT_6_0
118 { 0 , 1 , 2 , -1 , -1 , -1 , -1 , -1 , 5 , 3 , 4 },
120 // CHANNEL_LAYOUT_6_0_FRONT
121 { 0 , 1 , -1 , -1 , -1 , -1 , 4 , 5 , -1 , 2 , 3 },
123 // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
125 // CHANNEL_LAYOUT_HEXAGONAL
126 { 0 , 1 , 2 , -1 , 3 , 4 , -1 , -1 , 5 , -1 , -1 },
128 // CHANNEL_LAYOUT_6_1
129 { 0 , 1 , 2 , 3 , -1 , -1 , -1 , -1 , 6 , 4 , 5 },
131 // CHANNEL_LAYOUT_6_1_BACK
132 { 0 , 1 , 2 , 3 , 4 , 5 , -1 , -1 , 6 , -1 , -1 },
134 // CHANNEL_LAYOUT_6_1_FRONT
135 { 0 , 1 , -1 , 6 , -1 , -1 , 4 , 5 , -1 , 2 , 3 },
137 // CHANNEL_LAYOUT_7_0_FRONT
138 { 0 , 1 , 2 , -1 , -1 , -1 , 5 , 6 , -1 , 3 , 4 },
140 // CHANNEL_LAYOUT_7_1_WIDE_BACK
141 { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , -1 , -1 , -1 },
143 // CHANNEL_LAYOUT_OCTAGONAL
144 { 0 , 1 , 2 , -1 , 5 , 6 , -1 , -1 , 7 , 3 , 4 },
146 // CHANNEL_LAYOUT_DISCRETE
147 { -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
149 // CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC
150 { 0 , 1 , 2 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
152 // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
155 int ChannelLayoutToChannelCount(ChannelLayout layout) {
156 DCHECK_LT(static_cast<size_t>(layout), arraysize(kLayoutToChannels));
157 return kLayoutToChannels[layout];
160 // Converts a channel count into a channel layout.
161 ChannelLayout GuessChannelLayout(int channels) {
164 return CHANNEL_LAYOUT_MONO;
166 return CHANNEL_LAYOUT_STEREO;
168 return CHANNEL_LAYOUT_SURROUND;
170 return CHANNEL_LAYOUT_QUAD;
172 return CHANNEL_LAYOUT_5_0;
174 return CHANNEL_LAYOUT_5_1;
176 return CHANNEL_LAYOUT_6_1;
178 return CHANNEL_LAYOUT_7_1;
180 DVLOG(1) << "Unsupported channel count: " << channels;
182 return CHANNEL_LAYOUT_UNSUPPORTED;
185 int ChannelOrder(ChannelLayout layout, Channels channel) {
186 DCHECK_LT(static_cast<size_t>(layout), arraysize(kChannelOrderings));
187 DCHECK_LT(static_cast<size_t>(channel), arraysize(kChannelOrderings[0]));
188 return kChannelOrderings[layout][channel];
191 const char* ChannelLayoutToString(ChannelLayout layout) {
193 case CHANNEL_LAYOUT_NONE:
195 case CHANNEL_LAYOUT_UNSUPPORTED:
196 return "UNSUPPORTED";
197 case CHANNEL_LAYOUT_MONO:
199 case CHANNEL_LAYOUT_STEREO:
201 case CHANNEL_LAYOUT_2_1:
203 case CHANNEL_LAYOUT_SURROUND:
205 case CHANNEL_LAYOUT_4_0:
207 case CHANNEL_LAYOUT_2_2:
209 case CHANNEL_LAYOUT_QUAD:
211 case CHANNEL_LAYOUT_5_0:
213 case CHANNEL_LAYOUT_5_1:
215 case CHANNEL_LAYOUT_5_0_BACK:
217 case CHANNEL_LAYOUT_5_1_BACK:
219 case CHANNEL_LAYOUT_7_0:
221 case CHANNEL_LAYOUT_7_1:
223 case CHANNEL_LAYOUT_7_1_WIDE:
225 case CHANNEL_LAYOUT_STEREO_DOWNMIX:
226 return "STEREO_DOWNMIX";
227 case CHANNEL_LAYOUT_2POINT1:
229 case CHANNEL_LAYOUT_3_1:
231 case CHANNEL_LAYOUT_4_1:
233 case CHANNEL_LAYOUT_6_0:
235 case CHANNEL_LAYOUT_6_0_FRONT:
237 case CHANNEL_LAYOUT_HEXAGONAL:
239 case CHANNEL_LAYOUT_6_1:
241 case CHANNEL_LAYOUT_6_1_BACK:
243 case CHANNEL_LAYOUT_6_1_FRONT:
245 case CHANNEL_LAYOUT_7_0_FRONT:
247 case CHANNEL_LAYOUT_7_1_WIDE_BACK:
248 return "7.1_WIDE_BACK";
249 case CHANNEL_LAYOUT_OCTAGONAL:
251 case CHANNEL_LAYOUT_DISCRETE:
253 case CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC:
254 return "STEREO_AND_KEYBOARD_MIC";
256 NOTREACHED() << "Invalid channel layout provided: " << layout;