• 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 };
44 
45 // The channel orderings for each layout as specified by FFmpeg.  Each value
46 // represents the index of each channel in each layout.  Values of -1 mean the
47 // channel at that index is not used for that layout.For example, the left side
48 // surround sound channel in FFmpeg's 5.1 layout is in the 5th position (because
49 // the order is L, R, C, LFE, LS, RS), so
50 // kChannelOrderings[CHANNEL_LAYOUT_5POINT1][SIDE_LEFT] = 4;
51 static const int kChannelOrderings[CHANNEL_LAYOUT_MAX][CHANNELS_MAX] = {
52     // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
53 
54     // CHANNEL_LAYOUT_NONE
55     {  -1 , -1 , -1 , -1  , -1 , -1 , -1    , -1    , -1 , -1 , -1 },
56 
57     // CHANNEL_LAYOUT_UNSUPPORTED
58     {  -1 , -1 , -1 , -1  , -1 , -1 , -1    , -1    , -1 , -1 , -1 },
59 
60     // CHANNEL_LAYOUT_MONO
61     {  -1 , -1 , 0  , -1  , -1 , -1 , -1    , -1    , -1 , -1 , -1 },
62 
63     // CHANNEL_LAYOUT_STEREO
64     {  0  , 1  , -1 , -1  , -1 , -1 , -1    , -1    , -1 , -1 , -1 },
65 
66     // CHANNEL_LAYOUT_2_1
67     {  0  , 1  , -1 , -1  , -1 , -1 , -1    , -1    , 2  , -1 , -1 },
68 
69     // CHANNEL_LAYOUT_SURROUND
70     {  0  , 1  , 2  , -1  , -1 , -1 , -1    , -1    , -1 , -1 , -1 },
71 
72     // CHANNEL_LAYOUT_4_0
73     {  0  , 1  , 2  , -1  , -1 , -1 , -1    , -1    , 3  , -1 , -1 },
74 
75     // CHANNEL_LAYOUT_2_2
76     {  0  , 1  , -1 , -1  , -1 , -1 , -1    , -1    , -1 , 2  ,  3 },
77 
78     // CHANNEL_LAYOUT_QUAD
79     {  0  , 1  , -1 , -1  , 2  , 3  , -1    , -1    , -1 , -1 , -1 },
80 
81     // CHANNEL_LAYOUT_5_0
82     {  0  , 1  , 2  , -1  , -1 , -1 , -1    , -1    , -1 , 3  ,  4 },
83 
84     // CHANNEL_LAYOUT_5_1
85     {  0  , 1  , 2  , 3   , -1 , -1 , -1    , -1    , -1 , 4  ,  5 },
86 
87     // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
88 
89     // CHANNEL_LAYOUT_5_0_BACK
90     {  0  , 1  , 2  , -1  , 3  , 4  , -1    , -1    , -1 , -1 , -1 },
91 
92     // CHANNEL_LAYOUT_5_1_BACK
93     {  0  , 1  , 2  , 3   , 4  , 5  , -1    , -1    , -1 , -1 , -1 },
94 
95     // CHANNEL_LAYOUT_7_0
96     {  0  , 1  , 2  , -1  , 5  , 6  , -1    , -1    , -1 , 3  ,  4 },
97 
98     // CHANNEL_LAYOUT_7_1
99     {  0  , 1  , 2  , 3   , 6  , 7  , -1    , -1    , -1 , 4  ,  5 },
100 
101     // CHANNEL_LAYOUT_7_1_WIDE
102     {  0  , 1  , 2  , 3   , -1 , -1 , 6     , 7     , -1 , 4  ,  5 },
103 
104     // CHANNEL_LAYOUT_STEREO_DOWNMIX
105     {  0  , 1  , -1 , -1  , -1 , -1 , -1    , -1    , -1 , -1 , -1 },
106 
107     // CHANNEL_LAYOUT_2POINT1
108     {  0  , 1  , -1 ,  2  , -1 , -1 , -1    , -1    , -1 , -1 , -1 },
109 
110     // CHANNEL_LAYOUT_3_1
111     {  0  , 1  ,  2 ,  3  , -1 , -1 , -1    , -1    , -1 , -1 , -1 },
112 
113     // CHANNEL_LAYOUT_4_1
114     {  0  , 1  ,  2 ,  4  , -1 , -1 , -1    , -1    ,  3 , -1 , -1 },
115 
116     // CHANNEL_LAYOUT_6_0
117     {  0  , 1  , 2  , -1  , -1 , -1 , -1    , -1    ,  5 , 3  ,  4 },
118 
119     // CHANNEL_LAYOUT_6_0_FRONT
120     {  0  , 1  , -1 , -1  , -1 , -1 ,  4    ,  5    , -1 , 2  ,  3 },
121 
122     // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
123 
124     // CHANNEL_LAYOUT_HEXAGONAL
125     {  0  , 1  , 2  , -1  , 3  , 4  , -1    , -1    ,  5 , -1 , -1 },
126 
127     // CHANNEL_LAYOUT_6_1
128     {  0  , 1  , 2  , 3   , -1 , -1 , -1    , -1    ,  6 , 4  ,  5 },
129 
130     // CHANNEL_LAYOUT_6_1_BACK
131     {  0  , 1  , 2  , 3   , 4  , 5  , -1    , -1    ,  6 , -1 , -1 },
132 
133     // CHANNEL_LAYOUT_6_1_FRONT
134     {  0  , 1  , -1 , 6   , -1 , -1 , 4     , 5     , -1 , 2  ,  3 },
135 
136     // CHANNEL_LAYOUT_7_0_FRONT
137     {  0  , 1  , 2  , -1  , -1 , -1 , 5     , 6     , -1 , 3  ,  4 },
138 
139     // CHANNEL_LAYOUT_7_1_WIDE_BACK
140     {  0  , 1  , 2  , 3   , 4  , 5  , 6     , 7     , -1 , -1 , -1 },
141 
142     // CHANNEL_LAYOUT_OCTAGONAL
143     {  0  , 1  , 2  , -1  , 5  , 6  , -1    , -1    ,  7 , 3  ,  4 },
144 
145     // CHANNEL_LAYOUT_DISCRETE
146     {  -1 , -1 , -1 , -1  , -1 , -1 , -1    , -1    , -1 , -1 , -1 },
147 
148     // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
149 };
150 
ChannelLayoutToChannelCount(ChannelLayout layout)151 int ChannelLayoutToChannelCount(ChannelLayout layout) {
152   DCHECK_LT(static_cast<size_t>(layout), arraysize(kLayoutToChannels));
153   return kLayoutToChannels[layout];
154 }
155 
156 // Converts a channel count into a channel layout.
GuessChannelLayout(int channels)157 ChannelLayout GuessChannelLayout(int channels) {
158   switch (channels) {
159     case 1:
160       return CHANNEL_LAYOUT_MONO;
161     case 2:
162       return CHANNEL_LAYOUT_STEREO;
163     case 3:
164       return CHANNEL_LAYOUT_SURROUND;
165     case 4:
166       return CHANNEL_LAYOUT_QUAD;
167     case 5:
168       return CHANNEL_LAYOUT_5_0;
169     case 6:
170       return CHANNEL_LAYOUT_5_1;
171     case 7:
172       return CHANNEL_LAYOUT_6_1;
173     case 8:
174       return CHANNEL_LAYOUT_7_1;
175     default:
176       DVLOG(1) << "Unsupported channel count: " << channels;
177   }
178   return CHANNEL_LAYOUT_UNSUPPORTED;
179 }
180 
ChannelOrder(ChannelLayout layout,Channels channel)181 int ChannelOrder(ChannelLayout layout, Channels channel) {
182   DCHECK_LT(static_cast<size_t>(layout), arraysize(kChannelOrderings));
183   DCHECK_LT(static_cast<size_t>(channel), arraysize(kChannelOrderings[0]));
184   return kChannelOrderings[layout][channel];
185 }
186 
ChannelLayoutToString(ChannelLayout layout)187 const char* ChannelLayoutToString(ChannelLayout layout) {
188   switch (layout) {
189     case CHANNEL_LAYOUT_NONE:
190       return "NONE";
191     case CHANNEL_LAYOUT_UNSUPPORTED:
192       return "UNSUPPORTED";
193     case CHANNEL_LAYOUT_MONO:
194       return "MONO";
195     case CHANNEL_LAYOUT_STEREO:
196       return "STEREO";
197     case CHANNEL_LAYOUT_2_1:
198       return "2.1";
199     case CHANNEL_LAYOUT_SURROUND:
200       return "SURROUND";
201     case CHANNEL_LAYOUT_4_0:
202       return "4.0";
203     case CHANNEL_LAYOUT_2_2:
204       return "2.2";
205     case CHANNEL_LAYOUT_QUAD:
206       return "QUAD";
207     case CHANNEL_LAYOUT_5_0:
208       return "5.0";
209     case CHANNEL_LAYOUT_5_1:
210       return "5.1";
211     case CHANNEL_LAYOUT_5_0_BACK:
212       return "5.0_BACK";
213     case CHANNEL_LAYOUT_5_1_BACK:
214       return "5.1_BACK";
215     case CHANNEL_LAYOUT_7_0:
216       return "7.0";
217     case CHANNEL_LAYOUT_7_1:
218       return "7.1";
219     case CHANNEL_LAYOUT_7_1_WIDE:
220       return "7.1_WIDE";
221     case CHANNEL_LAYOUT_STEREO_DOWNMIX:
222       return "STEREO_DOWNMIX";
223     case CHANNEL_LAYOUT_2POINT1:
224       return "2POINT1";
225     case CHANNEL_LAYOUT_3_1:
226       return "3.1";
227     case CHANNEL_LAYOUT_4_1:
228       return "4.1";
229     case CHANNEL_LAYOUT_6_0:
230       return "6.0";
231     case CHANNEL_LAYOUT_6_0_FRONT:
232       return "6.0_FRONT";
233     case CHANNEL_LAYOUT_HEXAGONAL:
234       return "HEXAGONAL";
235     case CHANNEL_LAYOUT_6_1:
236       return "6.1";
237     case CHANNEL_LAYOUT_6_1_BACK:
238       return "6.1_BACK";
239     case CHANNEL_LAYOUT_6_1_FRONT:
240       return "6.1_FRONT";
241     case CHANNEL_LAYOUT_7_0_FRONT:
242       return "7.0_FRONT";
243     case CHANNEL_LAYOUT_7_1_WIDE_BACK:
244       return "7.1_WIDE_BACK";
245     case CHANNEL_LAYOUT_OCTAGONAL:
246       return "OCTAGONAL";
247     case CHANNEL_LAYOUT_DISCRETE:
248       return "DISCRETE";
249     case CHANNEL_LAYOUT_MAX:
250       break;
251   }
252   NOTREACHED() << "Invalid channel layout provided: " << layout;
253   return "";
254 }
255 
256 }  // namespace media
257