Bug 1444479 - P1. Remove 8 channels limitation in AudioConfig. r?padenot draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Fri, 16 Mar 2018 16:37:27 +0100
changeset 769394 b1c3beed574a507dbf2d32376ff8a1a188014976
parent 769393 f115bf2867f4d33401a6e0fc237bee57c0aff512
child 769395 822125df1ffe91a0493862560d8f294cc418b1ce
push id103110
push userbmo:jyavenard@mozilla.com
push dateMon, 19 Mar 2018 14:36:56 +0000
reviewerspadenot
bugs1444479
milestone61.0a1
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
dom/media/AudioConfig.cpp
dom/media/AudioConfig.h
--- 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,