Home | History | Annotate | Download | only in base
      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 
    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.
    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 
    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 
    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