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 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. 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 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 187 } // namespace media 188