• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "media/base/channel_layout.h"
6 
7 #include "base/basictypes.h"
8 #include "base/logging.h"
9 
10 namespace media {
11 
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 };
45 
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
54 
55     // CHANNEL_LAYOUT_NONE
56     {  -1 , -1 , -1 , -1  , -1 , -1 , -1    , -1    , -1 , -1 , -1 },
57 
58     // CHANNEL_LAYOUT_UNSUPPORTED
59     {  -1 , -1 , -1 , -1  , -1 , -1 , -1    , -1    , -1 , -1 , -1 },
60 
61     // CHANNEL_LAYOUT_MONO
62     {  -1 , -1 , 0  , -1  , -1 , -1 , -1    , -1    , -1 , -1 , -1 },
63 
64     // CHANNEL_LAYOUT_STEREO
65     {  0  , 1  , -1 , -1  , -1 , -1 , -1    , -1    , -1 , -1 , -1 },
66 
67     // CHANNEL_LAYOUT_2_1
68     {  0  , 1  , -1 , -1  , -1 , -1 , -1    , -1    , 2  , -1 , -1 },
69 
70     // CHANNEL_LAYOUT_SURROUND
71     {  0  , 1  , 2  , -1  , -1 , -1 , -1    , -1    , -1 , -1 , -1 },
72 
73     // CHANNEL_LAYOUT_4_0
74     {  0  , 1  , 2  , -1  , -1 , -1 , -1    , -1    , 3  , -1 , -1 },
75 
76     // CHANNEL_LAYOUT_2_2
77     {  0  , 1  , -1 , -1  , -1 , -1 , -1    , -1    , -1 , 2  ,  3 },
78 
79     // CHANNEL_LAYOUT_QUAD
80     {  0  , 1  , -1 , -1  , 2  , 3  , -1    , -1    , -1 , -1 , -1 },
81 
82     // CHANNEL_LAYOUT_5_0
83     {  0  , 1  , 2  , -1  , -1 , -1 , -1    , -1    , -1 , 3  ,  4 },
84 
85     // CHANNEL_LAYOUT_5_1
86     {  0  , 1  , 2  , 3   , -1 , -1 , -1    , -1    , -1 , 4  ,  5 },
87 
88     // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
89 
90     // CHANNEL_LAYOUT_5_0_BACK
91     {  0  , 1  , 2  , -1  , 3  , 4  , -1    , -1    , -1 , -1 , -1 },
92 
93     // CHANNEL_LAYOUT_5_1_BACK
94     {  0  , 1  , 2  , 3   , 4  , 5  , -1    , -1    , -1 , -1 , -1 },
95 
96     // CHANNEL_LAYOUT_7_0
97     {  0  , 1  , 2  , -1  , 5  , 6  , -1    , -1    , -1 , 3  ,  4 },
98 
99     // CHANNEL_LAYOUT_7_1
100     {  0  , 1  , 2  , 3   , 6  , 7  , -1    , -1    , -1 , 4  ,  5 },
101 
102     // CHANNEL_LAYOUT_7_1_WIDE
103     {  0  , 1  , 2  , 3   , -1 , -1 , 6     , 7     , -1 , 4  ,  5 },
104 
105     // CHANNEL_LAYOUT_STEREO_DOWNMIX
106     {  0  , 1  , -1 , -1  , -1 , -1 , -1    , -1    , -1 , -1 , -1 },
107 
108     // CHANNEL_LAYOUT_2POINT1
109     {  0  , 1  , -1 ,  2  , -1 , -1 , -1    , -1    , -1 , -1 , -1 },
110 
111     // CHANNEL_LAYOUT_3_1
112     {  0  , 1  ,  2 ,  3  , -1 , -1 , -1    , -1    , -1 , -1 , -1 },
113 
114     // CHANNEL_LAYOUT_4_1
115     {  0  , 1  ,  2 ,  4  , -1 , -1 , -1    , -1    ,  3 , -1 , -1 },
116 
117     // CHANNEL_LAYOUT_6_0
118     {  0  , 1  , 2  , -1  , -1 , -1 , -1    , -1    ,  5 , 3  ,  4 },
119 
120     // CHANNEL_LAYOUT_6_0_FRONT
121     {  0  , 1  , -1 , -1  , -1 , -1 ,  4    ,  5    , -1 , 2  ,  3 },
122 
123     // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
124 
125     // CHANNEL_LAYOUT_HEXAGONAL
126     {  0  , 1  , 2  , -1  , 3  , 4  , -1    , -1    ,  5 , -1 , -1 },
127 
128     // CHANNEL_LAYOUT_6_1
129     {  0  , 1  , 2  , 3   , -1 , -1 , -1    , -1    ,  6 , 4  ,  5 },
130 
131     // CHANNEL_LAYOUT_6_1_BACK
132     {  0  , 1  , 2  , 3   , 4  , 5  , -1    , -1    ,  6 , -1 , -1 },
133 
134     // CHANNEL_LAYOUT_6_1_FRONT
135     {  0  , 1  , -1 , 6   , -1 , -1 , 4     , 5     , -1 , 2  ,  3 },
136 
137     // CHANNEL_LAYOUT_7_0_FRONT
138     {  0  , 1  , 2  , -1  , -1 , -1 , 5     , 6     , -1 , 3  ,  4 },
139 
140     // CHANNEL_LAYOUT_7_1_WIDE_BACK
141     {  0  , 1  , 2  , 3   , 4  , 5  , 6     , 7     , -1 , -1 , -1 },
142 
143     // CHANNEL_LAYOUT_OCTAGONAL
144     {  0  , 1  , 2  , -1  , 5  , 6  , -1    , -1    ,  7 , 3  ,  4 },
145 
146     // CHANNEL_LAYOUT_DISCRETE
147     {  -1 , -1 , -1 , -1  , -1 , -1 , -1    , -1    , -1 , -1 , -1 },
148 
149     // CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC
150     {  0  , 1  , 2  , -1  , -1 , -1 , -1    , -1    , -1 , -1 , -1 },
151 
152     // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
153 };
154 
ChannelLayoutToChannelCount(ChannelLayout layout)155 int ChannelLayoutToChannelCount(ChannelLayout layout) {
156   DCHECK_LT(static_cast<size_t>(layout), arraysize(kLayoutToChannels));
157   return kLayoutToChannels[layout];
158 }
159 
160 // Converts a channel count into a channel layout.
GuessChannelLayout(int channels)161 ChannelLayout GuessChannelLayout(int channels) {
162   switch (channels) {
163     case 1:
164       return CHANNEL_LAYOUT_MONO;
165     case 2:
166       return CHANNEL_LAYOUT_STEREO;
167     case 3:
168       return CHANNEL_LAYOUT_SURROUND;
169     case 4:
170       return CHANNEL_LAYOUT_QUAD;
171     case 5:
172       return CHANNEL_LAYOUT_5_0;
173     case 6:
174       return CHANNEL_LAYOUT_5_1;
175     case 7:
176       return CHANNEL_LAYOUT_6_1;
177     case 8:
178       return CHANNEL_LAYOUT_7_1;
179     default:
180       DVLOG(1) << "Unsupported channel count: " << channels;
181   }
182   return CHANNEL_LAYOUT_UNSUPPORTED;
183 }
184 
ChannelOrder(ChannelLayout layout,Channels channel)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];
189 }
190 
ChannelLayoutToString(ChannelLayout layout)191 const char* ChannelLayoutToString(ChannelLayout layout) {
192   switch (layout) {
193     case CHANNEL_LAYOUT_NONE:
194       return "NONE";
195     case CHANNEL_LAYOUT_UNSUPPORTED:
196       return "UNSUPPORTED";
197     case CHANNEL_LAYOUT_MONO:
198       return "MONO";
199     case CHANNEL_LAYOUT_STEREO:
200       return "STEREO";
201     case CHANNEL_LAYOUT_2_1:
202       return "2.1";
203     case CHANNEL_LAYOUT_SURROUND:
204       return "SURROUND";
205     case CHANNEL_LAYOUT_4_0:
206       return "4.0";
207     case CHANNEL_LAYOUT_2_2:
208       return "2.2";
209     case CHANNEL_LAYOUT_QUAD:
210       return "QUAD";
211     case CHANNEL_LAYOUT_5_0:
212       return "5.0";
213     case CHANNEL_LAYOUT_5_1:
214       return "5.1";
215     case CHANNEL_LAYOUT_5_0_BACK:
216       return "5.0_BACK";
217     case CHANNEL_LAYOUT_5_1_BACK:
218       return "5.1_BACK";
219     case CHANNEL_LAYOUT_7_0:
220       return "7.0";
221     case CHANNEL_LAYOUT_7_1:
222       return "7.1";
223     case CHANNEL_LAYOUT_7_1_WIDE:
224       return "7.1_WIDE";
225     case CHANNEL_LAYOUT_STEREO_DOWNMIX:
226       return "STEREO_DOWNMIX";
227     case CHANNEL_LAYOUT_2POINT1:
228       return "2POINT1";
229     case CHANNEL_LAYOUT_3_1:
230       return "3.1";
231     case CHANNEL_LAYOUT_4_1:
232       return "4.1";
233     case CHANNEL_LAYOUT_6_0:
234       return "6.0";
235     case CHANNEL_LAYOUT_6_0_FRONT:
236       return "6.0_FRONT";
237     case CHANNEL_LAYOUT_HEXAGONAL:
238       return "HEXAGONAL";
239     case CHANNEL_LAYOUT_6_1:
240       return "6.1";
241     case CHANNEL_LAYOUT_6_1_BACK:
242       return "6.1_BACK";
243     case CHANNEL_LAYOUT_6_1_FRONT:
244       return "6.1_FRONT";
245     case CHANNEL_LAYOUT_7_0_FRONT:
246       return "7.0_FRONT";
247     case CHANNEL_LAYOUT_7_1_WIDE_BACK:
248       return "7.1_WIDE_BACK";
249     case CHANNEL_LAYOUT_OCTAGONAL:
250       return "OCTAGONAL";
251     case CHANNEL_LAYOUT_DISCRETE:
252       return "DISCRETE";
253     case CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC:
254       return "STEREO_AND_KEYBOARD_MIC";
255   }
256   NOTREACHED() << "Invalid channel layout provided: " << layout;
257   return "";
258 }
259 
260 }  // namespace media
261