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 };
     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