Bug 1444479 - P1. Remove 8 channels limitation in AudioConfig. r?padenot
Instead we place it at 32.
Future changes will change the meaning of this limit to when we can deal with channel layout. If outside that limit the audio will be played on a best attempt basis.
MozReview-Commit-ID: EavmmcxjLI0
--- a/dom/media/AudioConfig.cpp
+++ b/dom/media/AudioConfig.cpp
@@ -113,36 +113,42 @@ ChannelLayout ChannelLayout::L3F4_LFE{
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;
+ mValid = mChannels.Length() <= MAX_CHANNELS;
+ mChannelMap = UNKNOWN_MAP;
if (mValid) {
mChannelMap = Map();
mValid = mChannelMap > 0;
}
}
auto
AudioConfig::ChannelLayout::Map() const -> ChannelMap
{
- if (mChannelMap) {
+ if (mChannelMap != UNKNOWN_MAP) {
return mChannelMap;
}
+ if (mChannels.Length() > MAX_CHANNELS) {
+ return UNKNOWN_MAP;
+ }
ChannelMap map = UNKNOWN_MAP;
- for (size_t i = 0; i < mChannels.Length() && i <= MAX_AUDIO_CHANNELS; i++) {
+ for (size_t i = 0; i < mChannels.Length(); i++) {
+ if (mChannels[i] > MAX_CHANNELS) {
+ return UNKNOWN_MAP;
+ }
uint32_t mask = 1 << mChannels[i];
if (mChannels[i] == CHANNEL_INVALID || (mChannelMap & mask)) {
// Invalid configuration.
- return 0;
+ return UNKNOWN_MAP;
}
map |= mask;
}
return map;
}
const AudioConfig::Channel*
AudioConfig::ChannelLayout::DefaultLayoutForChannels(uint32_t aChannels) const
@@ -245,27 +251,30 @@ AudioConfig::ChannelLayout::SMPTEDefault
case L3F2_LFE_MAP: return L3F2_LFE;
case L3F2_BACK_MAP: return L3F2_BACK;
case L3F2_BACK_LFE_MAP: return L3F2_BACK_LFE;
case L3F3R_LFE_MAP: return L3F3R_LFE;
case L3F4_LFE_MAP: return L3F4_LFE;
default:
break;
}
- AutoTArray<Channel, MAX_AUDIO_CHANNELS> layout;
+
+ static_assert(MAX_CHANNELS <= sizeof(ChannelMap) * 8,
+ "Must be able to fit channels on bit mask");
+ AutoTArray<Channel, MAX_CHANNELS> layout;
uint32_t channels = 0;
uint32_t i = 0;
while (aMap) {
if (aMap & 1) {
- layout.AppendElement(static_cast<Channel>(i));
channels++;
- if (channels > MAX_AUDIO_CHANNELS) {
+ if (channels > MAX_CHANNELS) {
return ChannelLayout();
}
+ layout.AppendElement(static_cast<Channel>(i));
}
aMap >>= 1;
i++;
}
return ChannelLayout(channels, layout.Elements());
}
bool
--- a/dom/media/AudioConfig.h
+++ b/dom/media/AudioConfig.h
@@ -42,28 +42,30 @@ public:
CHANNEL_TOP_BACK_LEFT,
CHANNEL_TOP_BACK_CENTER,
CHANNEL_TOP_BACK_RIGHT
};
class ChannelLayout
{
public:
+ // The maximum number of channels a channel map can represent.
+ static constexpr uint32_t MAX_CHANNELS = 32;
+
typedef uint32_t ChannelMap;
- ChannelLayout() : mChannelMap(0), mValid(false) { }
+ ChannelLayout() : mChannelMap(UNKNOWN_MAP), 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();
}
ChannelLayout(std::initializer_list<Channel> aChannelList)
: ChannelLayout(aChannelList.size(), aChannelList.begin())
{
@@ -73,16 +75,17 @@ public:
return mChannels == aOther.mChannels;
}
bool operator!=(const ChannelLayout& aOther) const
{
return mChannels != aOther.mChannels;
}
const Channel& operator[](uint32_t aIndex) const
{
+ MOZ_ASSERT(mChannels.Length() > aIndex);
return mChannels[aIndex];
}
uint32_t Count() const
{
return mChannels.Length();
}
ChannelMap Map() const;
@@ -196,17 +199,17 @@ public:
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;
+ AutoTArray<Channel, MAX_CHANNELS> mChannels;
ChannelMap mChannelMap;
bool mValid;
};
enum SampleFormat
{
FORMAT_NONE = 0,
FORMAT_U8,