Bug 1431221 - P1. Add method to retrieve SMPTE equivalent layout from any channel layout. r=padenot

MozReview-Commit-ID: J8yT5OWIbAH
This commit is contained in:
Jean-Yves Avenard 2018-01-22 15:10:09 +01:00
Родитель 69852a9807
Коммит 1e2f478164
2 изменённых файлов: 205 добавлений и 10 удалений

Просмотреть файл

@ -53,18 +53,96 @@ typedef AudioConfig::ChannelLayout ChannelLayout;
3F4-LFE L R C LFE Rls Rrs LS RS
*/
ChannelLayout ChannelLayout::LMONO{ AudioConfig::CHANNEL_MONO };
ChannelLayout ChannelLayout::LMONO_LFE{ AudioConfig::CHANNEL_MONO,
AudioConfig::CHANNEL_LFE };
ChannelLayout ChannelLayout::LSTEREO{ AudioConfig::CHANNEL_LEFT,
AudioConfig::CHANNEL_RIGHT };
ChannelLayout ChannelLayout::LSTEREO_LFE{ AudioConfig::CHANNEL_LEFT,
AudioConfig::CHANNEL_RIGHT,
AudioConfig::CHANNEL_LFE };
ChannelLayout ChannelLayout::L3F{ AudioConfig::CHANNEL_LEFT,
AudioConfig::CHANNEL_RIGHT,
AudioConfig::CHANNEL_CENTER };
ChannelLayout ChannelLayout::L3F_LFE{ AudioConfig::CHANNEL_LEFT,
AudioConfig::CHANNEL_RIGHT,
AudioConfig::CHANNEL_CENTER,
AudioConfig::CHANNEL_LFE };
ChannelLayout ChannelLayout::L2F1{ AudioConfig::CHANNEL_LEFT,
AudioConfig::CHANNEL_RIGHT,
AudioConfig::CHANNEL_RCENTER };
ChannelLayout ChannelLayout::L2F1_LFE{ AudioConfig::CHANNEL_LEFT,
AudioConfig::CHANNEL_RIGHT,
AudioConfig::CHANNEL_LFE,
AudioConfig::CHANNEL_RCENTER };
ChannelLayout ChannelLayout::L3F1{ AudioConfig::CHANNEL_LEFT,
AudioConfig::CHANNEL_RIGHT,
AudioConfig::CHANNEL_CENTER,
AudioConfig::CHANNEL_RCENTER };
ChannelLayout ChannelLayout::L3F1_LFE{ AudioConfig::CHANNEL_LEFT,
AudioConfig::CHANNEL_RIGHT,
AudioConfig::CHANNEL_CENTER,
AudioConfig::CHANNEL_LFE,
AudioConfig::CHANNEL_RCENTER };
ChannelLayout ChannelLayout::L2F2{ AudioConfig::CHANNEL_LEFT,
AudioConfig::CHANNEL_RIGHT,
AudioConfig::CHANNEL_LS,
AudioConfig::CHANNEL_RS };
ChannelLayout ChannelLayout::L2F2_LFE{ AudioConfig::CHANNEL_LEFT,
AudioConfig::CHANNEL_RIGHT,
AudioConfig::CHANNEL_LFE,
AudioConfig::CHANNEL_LS,
AudioConfig::CHANNEL_RS };
ChannelLayout ChannelLayout::L3F2{ AudioConfig::CHANNEL_LEFT,
AudioConfig::CHANNEL_RIGHT,
AudioConfig::CHANNEL_CENTER,
AudioConfig::CHANNEL_LS,
AudioConfig::CHANNEL_RS };
ChannelLayout ChannelLayout::L3F2_LFE{
AudioConfig::CHANNEL_LEFT, AudioConfig::CHANNEL_RIGHT,
AudioConfig::CHANNEL_CENTER, AudioConfig::CHANNEL_LFE,
AudioConfig::CHANNEL_LS, AudioConfig::CHANNEL_RS
};
ChannelLayout ChannelLayout::L3F3R_LFE{
AudioConfig::CHANNEL_LEFT, AudioConfig::CHANNEL_RIGHT,
AudioConfig::CHANNEL_CENTER, AudioConfig::CHANNEL_LFE,
AudioConfig::CHANNEL_RCENTER, AudioConfig::CHANNEL_LS,
AudioConfig::CHANNEL_RS
};
ChannelLayout ChannelLayout::L3F4_LFE{
AudioConfig::CHANNEL_LEFT, AudioConfig::CHANNEL_RIGHT,
AudioConfig::CHANNEL_CENTER, AudioConfig::CHANNEL_LFE,
AudioConfig::CHANNEL_RLS, AudioConfig::CHANNEL_RRS,
AudioConfig::CHANNEL_LS, AudioConfig::CHANNEL_RS
};
void
AudioConfig::ChannelLayout::UpdateChannelMap()
{
mChannelMap = 0;
mValid = mChannels.Length() <= MAX_AUDIO_CHANNELS;
mChannelMap = 0;
if (mValid) {
mChannelMap = Map();
mValid = mChannelMap > 0;
}
}
uint32_t
AudioConfig::ChannelLayout::Map() const
{
if (mChannelMap) {
return mChannelMap;
}
uint32_t map = 0;
for (size_t i = 0; i < mChannels.Length() && i <= MAX_AUDIO_CHANNELS; i++) {
uint32_t mask = 1 << mChannels[i];
if (mChannels[i] == CHANNEL_INVALID || (mChannelMap & mask)) {
mValid = false;
// Invalid configuration.
return 0;
}
mChannelMap |= mask;
map |= mask;
}
return map;
}
/* static */ const AudioConfig::Channel*
@ -116,6 +194,54 @@ AudioConfig::ChannelLayout::SMPTEDefault(uint32_t aChannels) const
}
}
/* static */ const AudioConfig::ChannelLayout&
AudioConfig::ChannelLayout::SMPTEDefault(
const ChannelLayout& aChannelLayout)
{
MOZ_ASSERT(LMONO_MAP == LMONO.Map());
MOZ_ASSERT(LMONO_LFE_MAP == LMONO_LFE.Map());
MOZ_ASSERT(LSTEREO_MAP == LSTEREO.Map());
MOZ_ASSERT(LSTEREO_LFE_MAP == LSTEREO_LFE.Map());
MOZ_ASSERT(L3F_MAP == L3F.Map());
MOZ_ASSERT(L3F_LFE_MAP == L3F_LFE.Map());
MOZ_ASSERT(L2F1_MAP == L2F1.Map());
MOZ_ASSERT(L2F1_LFE_MAP == L2F1_LFE.Map());
MOZ_ASSERT(L3F1_MAP == L3F1.Map());
MOZ_ASSERT(L3F1_LFE_MAP == L3F1_LFE.Map());
MOZ_ASSERT(L2F2_MAP == L2F2.Map());
MOZ_ASSERT(L2F2_LFE_MAP == L2F2_LFE.Map());
MOZ_ASSERT(L3F2_MAP == L3F2.Map());
MOZ_ASSERT(L3F2_LFE_MAP == L3F2_LFE.Map());
MOZ_ASSERT(L3F3R_LFE_MAP == L3F3R_LFE.Map());
MOZ_ASSERT(L3F4_LFE_MAP == L3F4_LFE.Map());
if (!aChannelLayout.IsValid()) {
return aChannelLayout;
}
const uint32_t map = aChannelLayout.Map();
switch (map) {
case LMONO_MAP: return LMONO;
case LMONO_LFE_MAP: return LMONO_LFE;
case LSTEREO_MAP: return LSTEREO;
case LSTEREO_LFE_MAP : return LSTEREO_LFE;
case L3F_MAP: return L3F;
case L3F_LFE_MAP: return L3F_LFE;
case L2F1_MAP: return L2F1;
case L2F1_LFE_MAP: return L2F1_LFE;
case L3F1_MAP: return L3F1;
case L3F1_LFE_MAP: return L3F1_LFE;
case L2F2_MAP: return L2F2;
case L2F2_LFE_MAP: return L2F2_LFE;
case L3F2_MAP: return L3F2;
case L3F2_LFE_MAP: return L3F2_LFE;
case L3F3R_LFE_MAP: return L3F3R_LFE;
case L3F4_LFE_MAP: return L3F4_LFE;
default:
// unknown return identical.
return aChannelLayout;
}
}
bool
AudioConfig::ChannelLayout::MappingTable(const ChannelLayout& aOther,
uint8_t* aMap) const

Просмотреть файл

@ -616,6 +616,8 @@ public:
class AudioConfig
{
public:
// Channel definition is conveniently defined to be in the same order as
// WAVEFORMAT && SMPTE, even though this is unused for now.
enum Channel
{
CHANNEL_INVALID = -1,
@ -623,12 +625,12 @@ public:
CHANNEL_LEFT,
CHANNEL_RIGHT,
CHANNEL_CENTER,
CHANNEL_LFE,
CHANNEL_RCENTER,
CHANNEL_LS,
CHANNEL_RS,
CHANNEL_RLS,
CHANNEL_RCENTER,
CHANNEL_RRS,
CHANNEL_LFE,
};
class ChannelLayout
@ -642,13 +644,17 @@ public:
ChannelLayout(uint32_t aChannels, const Channel* aConfig)
: ChannelLayout()
{
if (!aConfig) {
if (aChannels == 0 || !aConfig) {
mValid = false;
return;
}
mChannels.AppendElements(aConfig, aChannels);
UpdateChannelMap();
}
ChannelLayout(std::initializer_list<Channel> aChannelList)
: ChannelLayout(aChannelList.size(), aChannelList.begin())
{
}
bool operator==(const ChannelLayout& aOther) const
{
return mChannels == aOther.mChannels;
@ -665,10 +671,8 @@ public:
{
return mChannels.Length();
}
uint32_t Map() const
{
return mChannelMap;
}
uint32_t Map() const;
// Calculate the mapping table from the current layout to aOther such that
// one can easily go from one layout to the other by doing:
// out[channel] = in[map[channel]].
@ -684,6 +688,71 @@ public:
{
return mChannelMap & (1 << aChannel);
}
static const ChannelLayout& SMPTEDefault(
const ChannelLayout& aChannelLayout);
// Common channel layout definitions.
static ChannelLayout LMONO;
static constexpr uint32_t LMONO_MAP = 1 << CHANNEL_MONO;
static ChannelLayout LMONO_LFE;
static constexpr uint32_t LMONO_LFE_MAP =
1 << CHANNEL_MONO | 1 << CHANNEL_LFE;
static ChannelLayout LSTEREO;
static constexpr uint32_t LSTEREO_MAP =
1 << CHANNEL_LEFT | 1 << CHANNEL_RIGHT;
static ChannelLayout LSTEREO_LFE;
static constexpr uint32_t LSTEREO_LFE_MAP =
1 << CHANNEL_LEFT | 1 << CHANNEL_RIGHT | 1 << CHANNEL_LFE;
static ChannelLayout L3F;
static constexpr uint32_t L3F_MAP =
1 << CHANNEL_LEFT | 1 << CHANNEL_RIGHT | 1 << CHANNEL_CENTER;
static ChannelLayout L3F_LFE;
static constexpr uint32_t L3F_LFE_MAP =
1 << CHANNEL_LEFT | 1 << CHANNEL_RIGHT | 1 << CHANNEL_CENTER |
1 << CHANNEL_LFE;
static ChannelLayout L2F1;
static constexpr uint32_t L2F1_MAP =
1 << CHANNEL_LEFT | 1 << CHANNEL_RIGHT | 1 << CHANNEL_RCENTER;
static ChannelLayout L2F1_LFE;
static constexpr uint32_t L2F1_LFE_MAP =
1 << CHANNEL_LEFT | 1 << CHANNEL_RIGHT | 1 << CHANNEL_LFE |
1 << CHANNEL_RCENTER;
static ChannelLayout L3F1;
static constexpr uint32_t L3F1_MAP =
1 << CHANNEL_LEFT | 1 << CHANNEL_RIGHT | 1 << CHANNEL_CENTER |
1 << CHANNEL_RCENTER;
static ChannelLayout L3F1_LFE;
static constexpr uint32_t L3F1_LFE_MAP =
1 << CHANNEL_LEFT | 1 << CHANNEL_RIGHT | 1 << CHANNEL_CENTER |
1 << CHANNEL_LFE | 1 << CHANNEL_RCENTER;
static ChannelLayout L2F2;
static constexpr uint32_t L2F2_MAP = 1 << CHANNEL_LEFT |
1 << CHANNEL_RIGHT | 1 << CHANNEL_LS |
1 << CHANNEL_RS;
static ChannelLayout L2F2_LFE;
static constexpr uint32_t L2F2_LFE_MAP =
1 << CHANNEL_LEFT | 1 << CHANNEL_RIGHT | 1 << CHANNEL_LFE |
1 << CHANNEL_LS | 1 << CHANNEL_RS;
static ChannelLayout L3F2;
static constexpr uint32_t L3F2_MAP =
1 << CHANNEL_LEFT | 1 << CHANNEL_RIGHT | 1 << CHANNEL_CENTER |
1 << CHANNEL_LS | 1 << CHANNEL_RS;
static ChannelLayout L3F2_LFE;
static constexpr uint32_t L3F2_LFE_MAP =
1 << CHANNEL_LEFT | 1 << CHANNEL_RIGHT | 1 << CHANNEL_CENTER |
1 << CHANNEL_LFE | 1 << CHANNEL_LS | 1 << CHANNEL_RS;
static ChannelLayout L3F3R_LFE;
static constexpr uint32_t L3F3R_LFE_MAP =
1 << CHANNEL_LEFT | 1 << CHANNEL_RIGHT | 1 << CHANNEL_CENTER |
1 << CHANNEL_LFE | 1 << CHANNEL_RCENTER | 1 << CHANNEL_LS |
1 << CHANNEL_RS;
static ChannelLayout L3F4_LFE;
static constexpr uint32_t L3F4_LFE_MAP =
1 << CHANNEL_LEFT | 1 << CHANNEL_RIGHT | 1 << CHANNEL_CENTER |
1 << CHANNEL_LFE | 1 << CHANNEL_RLS | 1 << CHANNEL_RRS | 1 << CHANNEL_LS |
1 << CHANNEL_RS;
private:
void UpdateChannelMap();
const Channel* SMPTEDefault(uint32_t aChannels) const;