blob: 8a442b357a98830e6c209e2921f9aa4b7fa83514 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/base/channel_layout.h"
#include "base/basictypes.h"
#include "base/logging.h"
namespace media {
static const int kLayoutToChannels[] = {
0, // CHANNEL_LAYOUT_NONE
0, // CHANNEL_LAYOUT_UNSUPPORTED
1, // CHANNEL_LAYOUT_MONO
2, // CHANNEL_LAYOUT_STEREO
3, // CHANNEL_LAYOUT_2_1
3, // CHANNEL_LAYOUT_SURROUND
4, // CHANNEL_LAYOUT_4POINT0
4, // CHANNEL_LAYOUT_2_2
4, // CHANNEL_LAYOUT_QUAD
5, // CHANNEL_LAYOUT_5POINT0
6, // CHANNEL_LAYOUT_5POINT1
5, // CHANNEL_LAYOUT_5POINT0_BACK
6, // CHANNEL_LAYOUT_5POINT1_BACK
7, // CHANNEL_LAYOUT_7POINT0
8, // CHANNEL_LAYOUT_7POINT1
8, // CHANNEL_LAYOUT_7POINT1_WIDE
2, // CHANNEL_LAYOUT_STEREO_DOWNMIX
3, // CHANNEL_LAYOUT_2POINT1
4, // CHANNEL_LAYOUT_3_1
5, // CHANNEL_LAYOUT_4_1
6, // CHANNEL_LAYOUT_6_0
6, // CHANNEL_LAYOUT_6_0_FRONT
6, // CHANNEL_LAYOUT_HEXAGONAL
7, // CHANNEL_LAYOUT_6_1
7, // CHANNEL_LAYOUT_6_1_BACK
7, // CHANNEL_LAYOUT_6_1_FRONT
7, // CHANNEL_LAYOUT_7_0_FRONT
8, // CHANNEL_LAYOUT_7_1_WIDE_BACK
8, // CHANNEL_LAYOUT_OCTAGONAL
};
// The channel orderings for each layout as specified by FFmpeg. Each value
// represents the index of each channel in each layout. Values of -1 mean the
// channel at that index is not used for that layout.For example, the left side
// surround sound channel in FFmpeg's 5.1 layout is in the 5th position (because
// the order is L, R, C, LFE, LS, RS), so
// kChannelOrderings[CHANNEL_LAYOUT_5POINT1][SIDE_LEFT] = 4;
static const int kChannelOrderings[CHANNEL_LAYOUT_MAX][CHANNELS_MAX] = {
// FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
// CHANNEL_LAYOUT_NONE
{ -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
// CHANNEL_LAYOUT_UNSUPPORTED
{ -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
// CHANNEL_LAYOUT_MONO
{ -1 , -1 , 0 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
// CHANNEL_LAYOUT_STEREO
{ 0 , 1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
// CHANNEL_LAYOUT_2_1
{ 0 , 1 , -1 , -1 , -1 , -1 , -1 , -1 , 2 , -1 , -1 },
// CHANNEL_LAYOUT_SURROUND
{ 0 , 1 , 2 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
// CHANNEL_LAYOUT_4POINT0
{ 0 , 1 , 2 , -1 , -1 , -1 , -1 , -1 , 3 , -1 , -1 },
// CHANNEL_LAYOUT_2_2
{ 0 , 1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , 2 , 3 },
// CHANNEL_LAYOUT_QUAD
{ 0 , 1 , -1 , -1 , 2 , 3 , -1 , -1 , -1 , -1 , -1 },
// CHANNEL_LAYOUT_5POINT0
{ 0 , 1 , 2 , -1 , -1 , -1 , -1 , -1 , -1 , 3 , 4 },
// CHANNEL_LAYOUT_5POINT1
{ 0 , 1 , 2 , 3 , -1 , -1 , -1 , -1 , -1 , 4 , 5 },
// FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
// CHANNEL_LAYOUT_5POINT0_BACK
{ 0 , 1 , 2 , -1 , 3 , 4 , -1 , -1 , -1 , -1 , -1 },
// CHANNEL_LAYOUT_5POINT1_BACK
{ 0 , 1 , 2 , 3 , 4 , 5 , -1 , -1 , -1 , -1 , -1 },
// CHANNEL_LAYOUT_7POINT0
{ 0 , 1 , 2 , -1 , 5 , 6 , -1 , -1 , -1 , 3 , 4 },
// CHANNEL_LAYOUT_7POINT1
{ 0 , 1 , 2 , 3 , 6 , 7 , -1 , -1 , -1 , 4 , 5 },
// CHANNEL_LAYOUT_7POINT1_WIDE
{ 0 , 1 , 2 , 3 , -1 , -1 , 6 , 7 , -1 , 4 , 5 },
// CHANNEL_LAYOUT_STEREO_DOWNMIX
{ 0 , 1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
// CHANNEL_LAYOUT_2POINT1
{ 0 , 1 , -1 , 2 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
// CHANNEL_LAYOUT_3_1
{ 0 , 1 , 2 , 3 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
// CHANNEL_LAYOUT_4_1
{ 0 , 1 , 2 , 4 , -1 , -1 , -1 , -1 , 3 , -1 , -1 },
// CHANNEL_LAYOUT_6_0
{ 0 , 1 , 2 , -1 , -1 , -1 , -1 , -1 , 5 , 3 , 4 },
// CHANNEL_LAYOUT_6_0_FRONT
{ 0 , 1 , -1 , -1 , -1 , -1 , 4 , 5 , -1 , 2 , 3 },
// FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
// CHANNEL_LAYOUT_HEXAGONAL
{ 0 , 1 , 2 , -1 , 3 , 4 , -1 , -1 , 5 , -1 , -1 },
// CHANNEL_LAYOUT_6_1
{ 0 , 1 , 2 , 3 , -1 , -1 , -1 , -1 , 6 , 4 , 5 },
// CHANNEL_LAYOUT_6_1_BACK
{ 0 , 1 , 2 , 3 , 4 , 5 , -1 , -1 , 6 , -1 , -1 },
// CHANNEL_LAYOUT_6_1_FRONT
{ 0 , 1 , -1 , 6 , -1 , -1 , 4 , 5 , -1 , 2 , 3 },
// CHANNEL_LAYOUT_7_0_FRONT
{ 0 , 1 , 2 , -1 , -1 , -1 , 5 , 6 , -1 , 3 , 4 },
// CHANNEL_LAYOUT_7_1_WIDE_BACK
{ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , -1 , -1 , -1 },
// CHANNEL_LAYOUT_OCTAGONAL
{ 0 , 1 , 2 , -1 , 5 , 6 , -1 , -1 , 7 , 3 , 4 },
// FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
};
int ChannelLayoutToChannelCount(ChannelLayout layout) {
DCHECK_LT(static_cast<size_t>(layout), arraysize(kLayoutToChannels));
return kLayoutToChannels[layout];
}
int ChannelOrder(ChannelLayout layout, Channels channel) {
DCHECK_LT(static_cast<size_t>(layout), arraysize(kChannelOrderings));
DCHECK_LT(static_cast<size_t>(channel), arraysize(kChannelOrderings[0]));
return kChannelOrderings[layout][channel];
}
// Converts a channel count into a channel layout.
ChannelLayout GuessChannelLayout(int channels) {
switch (channels) {
case 1:
return CHANNEL_LAYOUT_MONO;
case 2:
return CHANNEL_LAYOUT_STEREO;
case 3:
return CHANNEL_LAYOUT_SURROUND;
case 4:
return CHANNEL_LAYOUT_QUAD;
case 5:
return CHANNEL_LAYOUT_5_0;
case 6:
return CHANNEL_LAYOUT_5_1;
case 7:
return CHANNEL_LAYOUT_6_1;
case 8:
return CHANNEL_LAYOUT_7_1;
default:
DVLOG(1) << "Unsupported channel count: " << channels;
}
return CHANNEL_LAYOUT_UNSUPPORTED;
}
} // namespace media