Bug 1431221 - P5. Split AudioConfig.{h,cpp} from MediaInfo. r=padenot

MozReview-Commit-ID: EzaC19HS2B8
This commit is contained in:
Jean-Yves Avenard 2018-01-23 21:06:07 +01:00
Родитель e9e8bc2708
Коммит 48cf8d7243
7 изменённых файлов: 637 добавлений и 581 удалений

349
dom/media/AudioConfig.cpp Normal file
Просмотреть файл

@ -0,0 +1,349 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AudioConfig.h"
namespace mozilla {
typedef AudioConfig::ChannelLayout ChannelLayout;
/**
* AudioConfig::ChannelLayout
*/
/*
SMPTE channel layout (also known as wave order)
DUAL-MONO L R
DUAL-MONO-LFE L R LFE
MONO M
MONO-LFE M LFE
STEREO L R
STEREO-LFE L R LFE
3F L R C
3F-LFE L R C LFE
2F1 L R S
2F1-LFE L R LFE S
3F1 L R C S
3F1-LFE L R C LFE S
2F2 L R LS RS
2F2-LFE L R LFE LS RS
3F2 L R C LS RS
3F2-LFE L R C LFE LS RS
3F3R-LFE L R C LFE BC LS RS
3F4-LFE L R C LFE Rls Rrs LS RS
*/
ChannelLayout ChannelLayout::LMONO{ CHANNEL_FRONT_CENTER };
ChannelLayout ChannelLayout::LMONO_LFE{ CHANNEL_FRONT_CENTER, CHANNEL_LFE };
ChannelLayout ChannelLayout::LSTEREO{ CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT };
ChannelLayout ChannelLayout::LSTEREO_LFE{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_LFE };
ChannelLayout ChannelLayout::L3F{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_FRONT_CENTER };
ChannelLayout ChannelLayout::L3F_LFE{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_FRONT_CENTER,
CHANNEL_LFE };
ChannelLayout ChannelLayout::L2F1{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_BACK_CENTER };
ChannelLayout ChannelLayout::L2F1_LFE{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_LFE,
CHANNEL_BACK_CENTER };
ChannelLayout ChannelLayout::L3F1{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_FRONT_CENTER,
CHANNEL_BACK_CENTER };
ChannelLayout ChannelLayout::LSURROUND = ChannelLayout::L3F1;
ChannelLayout ChannelLayout::L3F1_LFE{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_FRONT_CENTER,
CHANNEL_LFE,
CHANNEL_BACK_CENTER };
ChannelLayout ChannelLayout::L2F2{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_SIDE_LEFT,
CHANNEL_SIDE_RIGHT };
ChannelLayout ChannelLayout::L2F2_LFE{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_LFE,
CHANNEL_SIDE_LEFT,
CHANNEL_SIDE_RIGHT };
ChannelLayout ChannelLayout::LQUAD{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_BACK_LEFT,
CHANNEL_BACK_RIGHT };
ChannelLayout ChannelLayout::LQUAD_LFE{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_LFE,
CHANNEL_BACK_LEFT,
CHANNEL_BACK_RIGHT };
ChannelLayout ChannelLayout::L3F2{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_FRONT_CENTER,
CHANNEL_SIDE_LEFT,
CHANNEL_SIDE_RIGHT };
ChannelLayout ChannelLayout::L3F2_LFE{
CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT, CHANNEL_FRONT_CENTER,
CHANNEL_LFE, CHANNEL_SIDE_LEFT, CHANNEL_SIDE_RIGHT
};
ChannelLayout ChannelLayout::L5POINT1_SURROUND = ChannelLayout::L3F2_LFE;
ChannelLayout ChannelLayout::L3F3R_LFE{
CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT, CHANNEL_FRONT_CENTER, CHANNEL_LFE,
CHANNEL_BACK_CENTER, CHANNEL_SIDE_LEFT, CHANNEL_SIDE_RIGHT
};
ChannelLayout ChannelLayout::L3F4_LFE{
CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT, CHANNEL_FRONT_CENTER,
CHANNEL_LFE, CHANNEL_BACK_LEFT, CHANNEL_BACK_RIGHT,
CHANNEL_SIDE_LEFT, CHANNEL_SIDE_RIGHT
};
ChannelLayout ChannelLayout::L7POINT1_SURROUND = ChannelLayout::L3F4_LFE;
void
AudioConfig::ChannelLayout::UpdateChannelMap()
{
mValid = mChannels.Length() <= MAX_AUDIO_CHANNELS;
mChannelMap = 0;
if (mValid) {
mChannelMap = Map();
mValid = mChannelMap > 0;
}
}
auto
AudioConfig::ChannelLayout::Map() const -> ChannelMap
{
if (mChannelMap) {
return mChannelMap;
}
ChannelMap map = UNKNOWN_MAP;
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)) {
// Invalid configuration.
return 0;
}
map |= mask;
}
return map;
}
const AudioConfig::Channel*
AudioConfig::ChannelLayout::DefaultLayoutForChannels(uint32_t aChannels) const
{
switch (aChannels) {
case 1: // MONO
{
static const Channel config[] = { CHANNEL_FRONT_CENTER };
return config;
}
case 2: // STEREO
{
static const Channel config[] = { CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT };
return config;
}
case 3: // 3F
{
static const Channel config[] = { CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT, CHANNEL_FRONT_CENTER };
return config;
}
case 4: // QUAD
{
static const Channel config[] = { CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT, CHANNEL_BACK_LEFT, CHANNEL_BACK_RIGHT };
return config;
}
case 5: // 3F2
{
static const Channel config[] = { CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT, CHANNEL_FRONT_CENTER, CHANNEL_SIDE_LEFT, CHANNEL_SIDE_RIGHT };
return config;
}
case 6: // 3F2-LFE
{
static const Channel config[] = { CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT, CHANNEL_FRONT_CENTER, CHANNEL_LFE, CHANNEL_SIDE_LEFT, CHANNEL_SIDE_RIGHT };
return config;
}
case 7: // 3F3R-LFE
{
static const Channel config[] = { CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT, CHANNEL_FRONT_CENTER, CHANNEL_LFE, CHANNEL_BACK_CENTER, CHANNEL_SIDE_LEFT, CHANNEL_SIDE_RIGHT };
return config;
}
case 8: // 3F4-LFE
{
static const Channel config[] = { CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT, CHANNEL_FRONT_CENTER, CHANNEL_LFE, CHANNEL_BACK_LEFT, CHANNEL_BACK_RIGHT, CHANNEL_SIDE_LEFT, CHANNEL_SIDE_RIGHT };
return config;
}
default:
return nullptr;
}
}
/* static */ AudioConfig::ChannelLayout
AudioConfig::ChannelLayout::SMPTEDefault(
const ChannelLayout& aChannelLayout)
{
if (!aChannelLayout.IsValid()) {
return aChannelLayout;
}
return SMPTEDefault(aChannelLayout.Map());
}
/* static */ ChannelLayout
AudioConfig::ChannelLayout::SMPTEDefault(ChannelMap aMap)
{
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(LQUAD_MAP == LQUAD.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());
// First handle the most common cases.
switch (aMap) {
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 LQUAD_MAP: return LQUAD;
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:
break;
}
AutoTArray<Channel, MAX_AUDIO_CHANNELS> layout;
uint32_t channels = 0;
uint32_t i = 1;
while (aMap) {
if (aMap & 1) {
layout.AppendElement(static_cast<Channel>(i));
channels++;
if (channels > MAX_AUDIO_CHANNELS) {
return ChannelLayout();
}
}
aMap >>= 1;
}
return ChannelLayout(channels, layout.Elements());
}
bool
AudioConfig::ChannelLayout::MappingTable(const ChannelLayout& aOther,
uint8_t* aMap) const
{
if (!IsValid() || !aOther.IsValid() ||
Map() != aOther.Map()) {
return false;
}
if (!aMap) {
return true;
}
for (uint32_t i = 0; i < Count(); i++) {
for (uint32_t j = 0; j < Count(); j++) {
if (aOther[j] == mChannels[i]) {
aMap[j] = i;
break;
}
}
}
return true;
}
/**
* AudioConfig::ChannelConfig
*/
/* static */ const char*
AudioConfig::FormatToString(AudioConfig::SampleFormat aFormat)
{
switch (aFormat) {
case FORMAT_U8: return "unsigned 8 bit";
case FORMAT_S16: return "signed 16 bit";
case FORMAT_S24: return "signed 24 bit MSB";
case FORMAT_S24LSB: return "signed 24 bit LSB";
case FORMAT_S32: return "signed 32 bit";
case FORMAT_FLT: return "32 bit floating point";
case FORMAT_NONE: return "none";
default: return "unknown";
}
}
/* static */ uint32_t
AudioConfig::SampleSize(AudioConfig::SampleFormat aFormat)
{
switch (aFormat) {
case FORMAT_U8: return 1;
case FORMAT_S16: return 2;
case FORMAT_S24: MOZ_FALLTHROUGH;
case FORMAT_S24LSB: MOZ_FALLTHROUGH;
case FORMAT_S32: MOZ_FALLTHROUGH;
case FORMAT_FLT: return 4;
case FORMAT_NONE:
default: return 0;
}
}
/* static */ uint32_t
AudioConfig::FormatToBits(AudioConfig::SampleFormat aFormat)
{
switch (aFormat) {
case FORMAT_U8: return 8;
case FORMAT_S16: return 16;
case FORMAT_S24LSB: MOZ_FALLTHROUGH;
case FORMAT_S24: return 24;
case FORMAT_S32: MOZ_FALLTHROUGH;
case FORMAT_FLT: return 32;
case FORMAT_NONE: MOZ_FALLTHROUGH;
default: return 0;
}
}
AudioConfig::AudioConfig(const ChannelLayout& aChannelLayout, uint32_t aRate,
AudioConfig::SampleFormat aFormat, bool aInterleaved)
: mChannelLayout(aChannelLayout)
, mChannels(aChannelLayout.Count())
, mRate(aRate)
, mFormat(aFormat)
, mInterleaved(aInterleaved)
{
}
AudioConfig::AudioConfig(uint32_t aChannels,
uint32_t aRate,
AudioConfig::SampleFormat aFormat,
bool aInterleaved)
: mChannelLayout(aChannels)
, mChannels(aChannels)
, mRate(aRate)
, mFormat(aFormat)
, mInterleaved(aInterleaved)
{
}
} // namespace mozilla

277
dom/media/AudioConfig.h Normal file
Просмотреть файл

@ -0,0 +1,277 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#if !defined(AudioLayout_h)
#define AudioLayout_h
#include <initializer_list>
#include <cstdint>
#include "nsTArray.h"
namespace mozilla {
// Maximum channel number we can currently handle (7.1)
#define MAX_AUDIO_CHANNELS 8
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,
CHANNEL_FRONT_LEFT = 0,
CHANNEL_FRONT_RIGHT,
CHANNEL_FRONT_CENTER,
CHANNEL_LFE,
CHANNEL_BACK_LEFT,
CHANNEL_BACK_RIGHT,
CHANNEL_FRONT_LEFT_OF_CENTER,
CHANNEL_FRONT_RIGHT_OF_CENTER,
CHANNEL_BACK_CENTER,
CHANNEL_SIDE_LEFT,
CHANNEL_SIDE_RIGHT,
// From WAVEFORMAT definition.
CHANNEL_TOP_CENTER,
CHANNEL_TOP_FRONT_LEFT,
CHANNEL_TOP_FRONT_CENTER,
CHANNEL_TOP_FRONT_RIGHT,
CHANNEL_TOP_BACK_LEFT,
CHANNEL_TOP_BACK_CENTER,
CHANNEL_TOP_BACK_RIGHT
};
class ChannelLayout
{
public:
typedef uint32_t ChannelMap;
ChannelLayout() : mChannelMap(0), mValid(false) { }
explicit ChannelLayout(uint32_t aChannels)
: ChannelLayout(aChannels, DefaultLayoutForChannels(aChannels))
{
}
ChannelLayout(uint32_t aChannels, const Channel* aConfig)
: ChannelLayout()
{
if (aChannels == 0 || !aConfig) {
mValid = false;
return;
}
mChannels.AppendElements(aConfig, aChannels);
UpdateChannelMap();
}
explicit ChannelLayout(std::initializer_list<Channel> aChannelList)
: ChannelLayout(aChannelList.size(), aChannelList.begin())
{
}
bool operator==(const ChannelLayout& aOther) const
{
return mChannels == aOther.mChannels;
}
bool operator!=(const ChannelLayout& aOther) const
{
return mChannels != aOther.mChannels;
}
const Channel& operator[](uint32_t aIndex) const
{
return mChannels[aIndex];
}
uint32_t Count() const
{
return mChannels.Length();
}
ChannelMap 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]].
// Returns true if the reordering is possible or false otherwise.
// If true, then aMap, if set, will be updated to contain the mapping table
// allowing conversion from the current layout to aOther.
// If aMap is nullptr, then MappingTable can be used to simply determine if
// the current layout can be easily reordered to aOther.
// aMap must be an array of size MAX_AUDIO_CHANNELS.
bool MappingTable(const ChannelLayout& aOther, uint8_t* aMap = nullptr) const;
bool IsValid() const { return mValid; }
bool HasChannel(Channel aChannel) const
{
return mChannelMap & (1 << aChannel);
}
static ChannelLayout SMPTEDefault(
const ChannelLayout& aChannelLayout);
static ChannelLayout SMPTEDefault(ChannelMap aMap);
static constexpr ChannelMap UNKNOWN_MAP = 0;
// Common channel layout definitions.
static ChannelLayout LMONO;
static constexpr ChannelMap LMONO_MAP = 1 << CHANNEL_FRONT_CENTER;
static ChannelLayout LMONO_LFE;
static constexpr ChannelMap LMONO_LFE_MAP =
1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_LFE;
static ChannelLayout LSTEREO;
static constexpr ChannelMap LSTEREO_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT;
static ChannelLayout LSTEREO_LFE;
static constexpr ChannelMap LSTEREO_LFE_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT | 1 << CHANNEL_LFE;
static ChannelLayout L3F;
static constexpr ChannelMap L3F_MAP = 1 << CHANNEL_FRONT_LEFT |
1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_FRONT_CENTER;
static ChannelLayout L3F_LFE;
static constexpr ChannelMap L3F_LFE_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_LFE;
static ChannelLayout L2F1;
static constexpr ChannelMap L2F1_MAP = 1 << CHANNEL_FRONT_LEFT |
1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_BACK_CENTER;
static ChannelLayout L2F1_LFE;
static constexpr ChannelMap L2F1_LFE_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT | 1 << CHANNEL_LFE |
1 << CHANNEL_BACK_CENTER;
static ChannelLayout L3F1;
static constexpr ChannelMap L3F1_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_BACK_CENTER;
static ChannelLayout LSURROUND; // Same as 3F1
static constexpr ChannelMap LSURROUND_MAP = L3F1_MAP;
static ChannelLayout L3F1_LFE;
static constexpr ChannelMap L3F1_LFE_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_LFE | 1 << CHANNEL_BACK_CENTER;
static ChannelLayout L2F2;
static constexpr ChannelMap L2F2_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_SIDE_LEFT | 1 << CHANNEL_SIDE_RIGHT;
static ChannelLayout L2F2_LFE;
static constexpr ChannelMap L2F2_LFE_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT | 1 << CHANNEL_LFE |
1 << CHANNEL_SIDE_LEFT | 1 << CHANNEL_SIDE_RIGHT;
static ChannelLayout LQUAD;
static constexpr ChannelMap LQUAD_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_BACK_LEFT | 1 << CHANNEL_BACK_RIGHT;
static ChannelLayout LQUAD_LFE;
static constexpr ChannelMap LQUAD_MAP_LFE =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT | 1 << CHANNEL_LFE |
1 << CHANNEL_BACK_LEFT | 1 << CHANNEL_BACK_RIGHT;
static ChannelLayout L3F2;
static constexpr ChannelMap L3F2_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_SIDE_LEFT |
1 << CHANNEL_SIDE_RIGHT;
static ChannelLayout L3F2_LFE;
static constexpr ChannelMap L3F2_LFE_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_LFE | 1 << CHANNEL_SIDE_LEFT |
1 << CHANNEL_SIDE_RIGHT;
// 3F2_LFE Alias
static ChannelLayout L5POINT1_SURROUND;
static constexpr ChannelMap L5POINT1_SURROUND_MAP = L3F2_LFE_MAP;
static ChannelLayout L3F3R_LFE;
static constexpr ChannelMap L3F3R_LFE_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_LFE | 1 << CHANNEL_BACK_CENTER |
1 << CHANNEL_SIDE_LEFT | 1 << CHANNEL_SIDE_RIGHT;
static ChannelLayout L3F4_LFE;
static constexpr ChannelMap L3F4_LFE_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_LFE | 1 << CHANNEL_BACK_LEFT |
1 << CHANNEL_BACK_RIGHT | 1 << CHANNEL_SIDE_LEFT |
1 << CHANNEL_SIDE_RIGHT;
// 3F4_LFE Alias
static ChannelLayout L7POINT1_SURROUND;
static constexpr ChannelMap L7POINT1_SURROUND_MAP = L3F4_LFE_MAP;
private:
void UpdateChannelMap();
const Channel* DefaultLayoutForChannels(uint32_t aChannels) const;
AutoTArray<Channel, MAX_AUDIO_CHANNELS> mChannels;
ChannelMap mChannelMap;
bool mValid;
};
enum SampleFormat
{
FORMAT_NONE = 0,
FORMAT_U8,
FORMAT_S16,
FORMAT_S24LSB,
FORMAT_S24,
FORMAT_S32,
FORMAT_FLT,
#if defined(MOZ_SAMPLE_TYPE_FLOAT32)
FORMAT_DEFAULT = FORMAT_FLT
#elif defined(MOZ_SAMPLE_TYPE_S16)
FORMAT_DEFAULT = FORMAT_S16
#else
#error "Not supported audio type"
#endif
};
AudioConfig(const ChannelLayout& aChannelLayout,
uint32_t aRate,
AudioConfig::SampleFormat aFormat = FORMAT_DEFAULT,
bool aInterleaved = true);
// Will create a channel configuration from default SMPTE ordering.
AudioConfig(uint32_t aChannels,
uint32_t aRate,
AudioConfig::SampleFormat aFormat = FORMAT_DEFAULT,
bool aInterleaved = true);
const ChannelLayout& Layout() const { return mChannelLayout; }
uint32_t Channels() const
{
if (!mChannelLayout.IsValid()) {
return mChannels;
}
return mChannelLayout.Count();
}
uint32_t Rate() const { return mRate; }
SampleFormat Format() const { return mFormat; }
bool Interleaved() const { return mInterleaved; }
bool operator==(const AudioConfig& aOther) const
{
return mChannelLayout == aOther.mChannelLayout && mRate == aOther.mRate &&
mFormat == aOther.mFormat && mInterleaved == aOther.mInterleaved;
}
bool operator!=(const AudioConfig& aOther) const
{
return !(*this == aOther);
}
bool IsValid() const
{
return mChannelLayout.IsValid() && Format() != FORMAT_NONE && Rate() > 0;
}
static const char* FormatToString(SampleFormat aFormat);
static uint32_t SampleSize(SampleFormat aFormat);
static uint32_t FormatToBits(SampleFormat aFormat);
private:
// Channels configuration.
ChannelLayout mChannelLayout;
// Channel count.
uint32_t mChannels;
// Sample rate.
uint32_t mRate;
// Sample format.
SampleFormat mFormat;
bool mInterleaved;
};
} // namespace mozilla
#endif // AudioLayout_h

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

@ -50,8 +50,9 @@
#define MASK_3F1 (AudioConfig::ChannelLayout::L3F1_MAP)
#define MASK_3F1_LFE (AudioConfig::ChannelLayout::L3F1_LFE_MAP)
#define MASK_2F2 (AudioConfig::ChannelLayout::L2F2_MAP)
#define MASK_QUAD (AudioConfig::ChannelLayout::LQUAD_MAP)
#define MASK_2F2_LFE (AudioConfig::ChannelLayout::L2F2_LFE_MAP)
#define MASK_QUAD (AudioConfig::ChannelLayout::LQUAD_MAP)
#define MASK_QUAD_LFE (AudioConfig::ChannelLayout::LQUAD_MAP_LFE)
#define MASK_3F2 (AudioConfig::ChannelLayout::L3F2_MAP)
#define MASK_3F2_LFE (AudioConfig::ChannelLayout::L3F2_LFE_MAP)
#define MASK_3F3R_LFE (AudioConfig::ChannelLayout::L3F3R_LFE_MAP)
@ -183,8 +184,10 @@ const layoutInfo kLayoutInfos[CUBEB_LAYOUT_MAX] = {
{ "2f1 lfe", 4, MASK_2F1_LFE }, // CUBEB_LAYOUT_2F1_LFE
{ "3f1", 4, MASK_3F1 }, // CUBEB_LAYOUT_3F1
{ "3f1 lfe", 5, MASK_3F1_LFE }, // CUBEB_LAYOUT_3F1_LFE
{ "2f2", 4, MASK_2F2_LFE }, // CUBEB_LAYOUT_2F2
{ "2f2", 4, MASK_2F2 }, // CUBEB_LAYOUT_2F2
{ "2f2 lfe", 5, MASK_2F2_LFE }, // CUBEB_LAYOUT_2F2_LFE
{ "quad", 4, MASK_QUAD }, // CUBEB_LAYOUT_QUAD
{ "quad lfe", 5, MASK_QUAD_LFE }, // CUBEB_LAYOUT_QUAD_LFE
{ "3f2", 5, MASK_3F2 }, // CUBEB_LAYOUT_3F2
{ "3f2 lfe", 6, MASK_3F2_LFE }, // CUBEB_LAYOUT_3F2_LFE
{ "3f3r lfe", 7, MASK_3F3R_LFE }, // CUBEB_LAYOUT_3F3R_LFE
@ -655,6 +658,8 @@ cubeb_channel_layout ConvertChannelMapToCubebLayout(uint32_t aChannelMap)
case MASK_3F1_LFE: return CUBEB_LAYOUT_3F1_LFE;
case MASK_2F2: return CUBEB_LAYOUT_2F2;
case MASK_2F2_LFE: return CUBEB_LAYOUT_2F2_LFE;
case MASK_QUAD: return CUBEB_LAYOUT_QUAD;
case MASK_QUAD_LFE: return CUBEB_LAYOUT_QUAD_LFE;
case MASK_3F2: return CUBEB_LAYOUT_3F2;
case MASK_3F2_LFE: return CUBEB_LAYOUT_3F2_LFE;
case MASK_3F3R_LFE: return CUBEB_LAYOUT_3F3R_LFE;

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

@ -6,6 +6,7 @@
#if !defined(MediaData_h)
#define MediaData_h
#include "AudioConfig.h"
#include "AudioSampleFormat.h"
#include "ImageTypes.h"
#include "SharedBuffer.h"

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

@ -25,318 +25,4 @@ TrackTypeToStr(TrackInfo::TrackType aTrack)
}
}
typedef AudioConfig::ChannelLayout ChannelLayout;
/**
* AudioConfig::ChannelLayout
*/
/*
SMPTE channel layout (also known as wave order)
DUAL-MONO L R
DUAL-MONO-LFE L R LFE
MONO M
MONO-LFE M LFE
STEREO L R
STEREO-LFE L R LFE
3F L R C
3F-LFE L R C LFE
2F1 L R S
2F1-LFE L R LFE S
3F1 L R C S
3F1-LFE L R C LFE S
2F2 L R LS RS
2F2-LFE L R LFE LS RS
3F2 L R C LS RS
3F2-LFE L R C LFE LS RS
3F3R-LFE L R C LFE BC LS RS
3F4-LFE L R C LFE Rls Rrs LS RS
*/
ChannelLayout ChannelLayout::LMONO{ CHANNEL_FRONT_CENTER };
ChannelLayout ChannelLayout::LMONO_LFE{ CHANNEL_FRONT_CENTER, CHANNEL_LFE };
ChannelLayout ChannelLayout::LSTEREO{ CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT };
ChannelLayout ChannelLayout::LSTEREO_LFE{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_LFE };
ChannelLayout ChannelLayout::L3F{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_FRONT_CENTER };
ChannelLayout ChannelLayout::L3F_LFE{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_FRONT_CENTER,
CHANNEL_LFE };
ChannelLayout ChannelLayout::L2F1{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_BACK_CENTER };
ChannelLayout ChannelLayout::L2F1_LFE{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_LFE,
CHANNEL_BACK_CENTER };
ChannelLayout ChannelLayout::L3F1{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_FRONT_CENTER,
CHANNEL_BACK_CENTER };
ChannelLayout ChannelLayout::LSURROUND = ChannelLayout::L3F1;
ChannelLayout ChannelLayout::L3F1_LFE{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_FRONT_CENTER,
CHANNEL_LFE,
CHANNEL_BACK_CENTER };
ChannelLayout ChannelLayout::L2F2{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_SIDE_LEFT,
CHANNEL_SIDE_RIGHT };
ChannelLayout ChannelLayout::L2F2_LFE{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_LFE,
CHANNEL_SIDE_LEFT,
CHANNEL_SIDE_RIGHT };
ChannelLayout ChannelLayout::LQUAD{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_BACK_LEFT,
CHANNEL_BACK_RIGHT };
ChannelLayout ChannelLayout::LQUAD_LFE{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_LFE,
CHANNEL_BACK_LEFT,
CHANNEL_BACK_RIGHT };
ChannelLayout ChannelLayout::L3F2{ CHANNEL_FRONT_LEFT,
CHANNEL_FRONT_RIGHT,
CHANNEL_FRONT_CENTER,
CHANNEL_SIDE_LEFT,
CHANNEL_SIDE_RIGHT };
ChannelLayout ChannelLayout::L3F2_LFE{
CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT, CHANNEL_FRONT_CENTER,
CHANNEL_LFE, CHANNEL_SIDE_LEFT, CHANNEL_SIDE_RIGHT
};
ChannelLayout ChannelLayout::L5POINT1_SURROUND = ChannelLayout::L3F2_LFE;
ChannelLayout ChannelLayout::L3F3R_LFE{
CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT, CHANNEL_FRONT_CENTER, CHANNEL_LFE,
CHANNEL_BACK_CENTER, CHANNEL_SIDE_LEFT, CHANNEL_SIDE_RIGHT
};
ChannelLayout ChannelLayout::L3F4_LFE{
CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT, CHANNEL_FRONT_CENTER,
CHANNEL_LFE, CHANNEL_BACK_LEFT, CHANNEL_BACK_RIGHT,
CHANNEL_SIDE_LEFT, CHANNEL_SIDE_RIGHT
};
ChannelLayout ChannelLayout::L7POINT1_SURROUND = ChannelLayout::L3F4_LFE;
void
AudioConfig::ChannelLayout::UpdateChannelMap()
{
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)) {
// Invalid configuration.
return 0;
}
map |= mask;
}
return map;
}
/* static */ const AudioConfig::Channel*
AudioConfig::ChannelLayout::SMPTEDefault(uint32_t aChannels) const
{
switch (aChannels) {
case 1: // MONO
{
static const Channel config[] = { CHANNEL_FRONT_CENTER };
return config;
}
case 2: // STEREO
{
static const Channel config[] = { CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT };
return config;
}
case 3: // 3F
{
static const Channel config[] = { CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT, CHANNEL_FRONT_CENTER };
return config;
}
case 4: // 2F2
{
static const Channel config[] = { CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT, CHANNEL_BACK_LEFT, CHANNEL_BACK_RIGHT };
return config;
}
case 5: // 3F2
{
static const Channel config[] = { CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT, CHANNEL_FRONT_CENTER, CHANNEL_SIDE_LEFT, CHANNEL_SIDE_RIGHT };
return config;
}
case 6: // 3F2-LFE
{
static const Channel config[] = { CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT, CHANNEL_FRONT_CENTER, CHANNEL_LFE, CHANNEL_SIDE_LEFT, CHANNEL_SIDE_RIGHT };
return config;
}
case 7: // 3F3R-LFE
{
static const Channel config[] = { CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT, CHANNEL_FRONT_CENTER, CHANNEL_LFE, CHANNEL_BACK_CENTER, CHANNEL_SIDE_LEFT, CHANNEL_SIDE_RIGHT };
return config;
}
case 8: // 3F4-LFE
{
static const Channel config[] = { CHANNEL_FRONT_LEFT, CHANNEL_FRONT_RIGHT, CHANNEL_FRONT_CENTER, CHANNEL_LFE, CHANNEL_BACK_LEFT, CHANNEL_BACK_RIGHT, CHANNEL_SIDE_LEFT, CHANNEL_SIDE_RIGHT };
return config;
}
default:
return nullptr;
}
}
/* 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(LQUAD_MAP == LQUAD.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 LQUAD_MAP: return LQUAD;
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
{
if (!IsValid() || !aOther.IsValid() ||
Map() != aOther.Map()) {
return false;
}
if (!aMap) {
return true;
}
for (uint32_t i = 0; i < Count(); i++) {
for (uint32_t j = 0; j < Count(); j++) {
if (aOther[j] == mChannels[i]) {
aMap[j] = i;
break;
}
}
}
return true;
}
/**
* AudioConfig::ChannelConfig
*/
/* static */ const char*
AudioConfig::FormatToString(AudioConfig::SampleFormat aFormat)
{
switch (aFormat) {
case FORMAT_U8: return "unsigned 8 bit";
case FORMAT_S16: return "signed 16 bit";
case FORMAT_S24: return "signed 24 bit MSB";
case FORMAT_S24LSB: return "signed 24 bit LSB";
case FORMAT_S32: return "signed 32 bit";
case FORMAT_FLT: return "32 bit floating point";
case FORMAT_NONE: return "none";
default: return "unknown";
}
}
/* static */ uint32_t
AudioConfig::SampleSize(AudioConfig::SampleFormat aFormat)
{
switch (aFormat) {
case FORMAT_U8: return 1;
case FORMAT_S16: return 2;
case FORMAT_S24: MOZ_FALLTHROUGH;
case FORMAT_S24LSB: MOZ_FALLTHROUGH;
case FORMAT_S32: MOZ_FALLTHROUGH;
case FORMAT_FLT: return 4;
case FORMAT_NONE:
default: return 0;
}
}
/* static */ uint32_t
AudioConfig::FormatToBits(AudioConfig::SampleFormat aFormat)
{
switch (aFormat) {
case FORMAT_U8: return 8;
case FORMAT_S16: return 16;
case FORMAT_S24LSB: MOZ_FALLTHROUGH;
case FORMAT_S24: return 24;
case FORMAT_S32: MOZ_FALLTHROUGH;
case FORMAT_FLT: return 32;
case FORMAT_NONE: MOZ_FALLTHROUGH;
default: return 0;
}
}
AudioConfig::AudioConfig(const ChannelLayout& aChannelLayout, uint32_t aRate,
AudioConfig::SampleFormat aFormat, bool aInterleaved)
: mChannelLayout(aChannelLayout)
, mChannels(aChannelLayout.Count())
, mRate(aRate)
, mFormat(aFormat)
, mInterleaved(aInterleaved)
{}
AudioConfig::AudioConfig(uint32_t aChannels, uint32_t aRate,
AudioConfig::SampleFormat aFormat, bool aInterleaved)
: mChannelLayout(aChannels)
, mChannels(aChannels)
, mRate(aRate)
, mFormat(aFormat)
, mInterleaved(aInterleaved)
{}
} // namespace mozilla

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

@ -11,6 +11,7 @@
#include "nsDataHashtable.h"
#include "nsString.h"
#include "nsTArray.h"
#include "AudioConfig.h"
#include "ImageTypes.h"
#include "MediaData.h"
#include "TrackID.h" // for TrackID
@ -39,9 +40,6 @@ public:
typedef nsDataHashtable<nsCStringHashKey, nsCString> MetadataTags;
// Maximum channel number we can currently handle (7.1)
#define MAX_AUDIO_CHANNELS 8
class TrackInfo
{
public:
@ -613,268 +611,6 @@ public:
const nsCString& mMimeType;
};
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,
CHANNEL_FRONT_LEFT = 0,
CHANNEL_FRONT_RIGHT,
CHANNEL_FRONT_CENTER,
CHANNEL_LFE,
CHANNEL_BACK_LEFT,
CHANNEL_BACK_RIGHT,
CHANNEL_FRONT_LEFT_OF_CENTER,
CHANNEL_FRONT_RIGHT_OF_CENTER,
CHANNEL_BACK_CENTER,
CHANNEL_SIDE_LEFT,
CHANNEL_SIDE_RIGHT,
// From WAVEFORMAT definition.
CHANNEL_TOP_CENTER,
CHANNEL_TOP_FRONT_LEFT,
CHANNEL_TOP_FRONT_CENTER,
CHANNEL_TOP_FRONT_RIGHT,
CHANNEL_TOP_BACK_LEFT,
CHANNEL_TOP_BACK_CENTER,
CHANNEL_TOP_BACK_RIGHT
};
class ChannelLayout
{
public:
ChannelLayout() : mChannelMap(0), mValid(false) { }
explicit ChannelLayout(uint32_t aChannels)
: ChannelLayout(aChannels, SMPTEDefault(aChannels))
{
}
ChannelLayout(uint32_t aChannels, const Channel* aConfig)
: ChannelLayout()
{
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;
}
bool operator!=(const ChannelLayout& aOther) const
{
return mChannels != aOther.mChannels;
}
const Channel& operator[](uint32_t aIndex) const
{
return mChannels[aIndex];
}
uint32_t Count() const
{
return mChannels.Length();
}
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]].
// Returns true if the reordering is possible or false otherwise.
// If true, then aMap, if set, will be updated to contain the mapping table
// allowing conversion from the current layout to aOther.
// If aMap is nullptr, then MappingTable can be used to simply determine if
// the current layout can be easily reordered to aOther.
// aMap must be an array of size MAX_AUDIO_CHANNELS.
bool MappingTable(const ChannelLayout& aOther, uint8_t* aMap = nullptr) const;
bool IsValid() const { return mValid; }
bool HasChannel(Channel aChannel) const
{
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_FRONT_CENTER;
static ChannelLayout LMONO_LFE;
static constexpr uint32_t LMONO_LFE_MAP =
1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_LFE;
static ChannelLayout LSTEREO;
static constexpr uint32_t LSTEREO_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT;
static ChannelLayout LSTEREO_LFE;
static constexpr uint32_t LSTEREO_LFE_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT | 1 << CHANNEL_LFE;
static ChannelLayout L3F;
static constexpr uint32_t L3F_MAP = 1 << CHANNEL_FRONT_LEFT |
1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_FRONT_CENTER;
static ChannelLayout L3F_LFE;
static constexpr uint32_t L3F_LFE_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_LFE;
static ChannelLayout L2F1;
static constexpr uint32_t L2F1_MAP = 1 << CHANNEL_FRONT_LEFT |
1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_BACK_CENTER;
static ChannelLayout L2F1_LFE;
static constexpr uint32_t L2F1_LFE_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT | 1 << CHANNEL_LFE |
1 << CHANNEL_BACK_CENTER;
static ChannelLayout L3F1;
static constexpr uint32_t L3F1_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_BACK_CENTER;
static ChannelLayout LSURROUND; // Same as 3F1
static constexpr uint32_t LSURROUND_MAP = L3F1_MAP;
static ChannelLayout L3F1_LFE;
static constexpr uint32_t L3F1_LFE_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_LFE | 1 << CHANNEL_BACK_CENTER;
static ChannelLayout L2F2;
static constexpr uint32_t L2F2_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_SIDE_LEFT | 1 << CHANNEL_SIDE_RIGHT;
static ChannelLayout L2F2_LFE;
static constexpr uint32_t L2F2_LFE_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT | 1 << CHANNEL_LFE |
1 << CHANNEL_SIDE_LEFT | 1 << CHANNEL_SIDE_RIGHT;
static ChannelLayout LQUAD;
static constexpr uint32_t LQUAD_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_BACK_LEFT | 1 << CHANNEL_BACK_RIGHT;
static ChannelLayout LQUAD_LFE;
static constexpr uint32_t LQUAD_MAP_LFE =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT | 1 << CHANNEL_LFE |
1 << CHANNEL_BACK_LEFT | 1 << CHANNEL_BACK_RIGHT;
static ChannelLayout L3F2;
static constexpr uint32_t L3F2_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_SIDE_LEFT |
1 << CHANNEL_SIDE_RIGHT;
static ChannelLayout L3F2_LFE;
static constexpr uint32_t L3F2_LFE_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_LFE | 1 << CHANNEL_SIDE_LEFT |
1 << CHANNEL_SIDE_RIGHT;
// 3F2_LFE Alias
static ChannelLayout L5POINT1_SURROUND;
static constexpr uint32_t L5POINT1_SURROUND_MAP = L3F2_LFE_MAP;
static ChannelLayout L3F3R_LFE;
static constexpr uint32_t L3F3R_LFE_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_LFE | 1 << CHANNEL_BACK_CENTER |
1 << CHANNEL_SIDE_LEFT | 1 << CHANNEL_SIDE_RIGHT;
static ChannelLayout L3F4_LFE;
static constexpr uint32_t L3F4_LFE_MAP =
1 << CHANNEL_FRONT_LEFT | 1 << CHANNEL_FRONT_RIGHT |
1 << CHANNEL_FRONT_CENTER | 1 << CHANNEL_LFE | 1 << CHANNEL_BACK_LEFT |
1 << CHANNEL_BACK_RIGHT | 1 << CHANNEL_SIDE_LEFT |
1 << CHANNEL_SIDE_RIGHT;
// 3F4_LFE Alias
static ChannelLayout L7POINT1_SURROUND;
static constexpr uint32_t L7POINT1_SURROUND_MAP = L3F4_LFE_MAP;
private:
void UpdateChannelMap();
const Channel* SMPTEDefault(uint32_t aChannels) const;
AutoTArray<Channel, MAX_AUDIO_CHANNELS> mChannels;
uint32_t mChannelMap;
bool mValid;
};
enum SampleFormat
{
FORMAT_NONE = 0,
FORMAT_U8,
FORMAT_S16,
FORMAT_S24LSB,
FORMAT_S24,
FORMAT_S32,
FORMAT_FLT,
#if defined(MOZ_SAMPLE_TYPE_FLOAT32)
FORMAT_DEFAULT = FORMAT_FLT
#elif defined(MOZ_SAMPLE_TYPE_S16)
FORMAT_DEFAULT = FORMAT_S16
#else
#error "Not supported audio type"
#endif
};
AudioConfig(const ChannelLayout& aChannelLayout, uint32_t aRate,
AudioConfig::SampleFormat aFormat = FORMAT_DEFAULT,
bool aInterleaved = true);
// Will create a channel configuration from default SMPTE ordering.
AudioConfig(uint32_t aChannels, uint32_t aRate,
AudioConfig::SampleFormat aFormat = FORMAT_DEFAULT,
bool aInterleaved = true);
const ChannelLayout& Layout() const
{
return mChannelLayout;
}
uint32_t Channels() const
{
if (!mChannelLayout.IsValid()) {
return mChannels;
}
return mChannelLayout.Count();
}
uint32_t Rate() const
{
return mRate;
}
SampleFormat Format() const
{
return mFormat;
}
bool Interleaved() const
{
return mInterleaved;
}
bool operator==(const AudioConfig& aOther) const
{
return mChannelLayout == aOther.mChannelLayout && mRate == aOther.mRate &&
mFormat == aOther.mFormat && mInterleaved == aOther.mInterleaved;
}
bool operator!=(const AudioConfig& aOther) const
{
return !(*this == aOther);
}
bool IsValid() const
{
return mChannelLayout.IsValid() && Format() != FORMAT_NONE && Rate() > 0;
}
static const char* FormatToString(SampleFormat aFormat);
static uint32_t SampleSize(SampleFormat aFormat);
static uint32_t FormatToBits(SampleFormat aFormat);
private:
// Channels configuration.
ChannelLayout mChannelLayout;
// Channel count.
uint32_t mChannels;
// Sample rate.
uint32_t mRate;
// Sample format.
SampleFormat mFormat;
bool mInterleaved;
};
} // namespace mozilla
#endif // MediaInfo_h

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

@ -92,6 +92,7 @@ EXPORTS += [
'AudioBufferUtils.h',
'AudioChannelFormat.h',
'AudioCompactor.h',
'AudioConfig.h',
'AudioConverter.h',
'AudioMixer.h',
'AudioPacketizer.h',
@ -208,6 +209,7 @@ UNIFIED_SOURCES += [
'AudioCaptureStream.cpp',
'AudioChannelFormat.cpp',
'AudioCompactor.cpp',
'AudioConfig.cpp',
'AudioConverter.cpp',
'AudioDeviceInfo.cpp',
'AudioSegment.cpp',