Bug 1248861: P12. Update AudioCompactor to account for alignment padding. r=rillian
authorJean-Yves Avenard <jyavenard@mozilla.com>
Sat, 09 Apr 2016 21:11:16 +1000
changeset 330584 ef6f7eda31ff661574b9dcef63a0224cbc19e3fc
parent 330583 a15ba02878040db7fd4332fa81f66bdbac0a30c0
child 330585 aa80c4c2ed4faa382a6fe9214e3a63f9351fd992
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrillian
bugs1248861
milestone48.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1248861: P12. Update AudioCompactor to account for alignment padding. r=rillian MozReview-Commit-ID: 2e9oUthWW4C
dom/media/AudioCompactor.h
dom/media/MediaData.h
--- a/dom/media/AudioCompactor.h
+++ b/dom/media/AudioCompactor.h
@@ -12,17 +12,25 @@
 
 namespace mozilla {
 
 class AudioCompactor
 {
 public:
   explicit AudioCompactor(MediaQueue<AudioData>& aQueue)
     : mQueue(aQueue)
-  { }
+  {
+    // Determine padding size used by AlignedBuffer.
+    size_t paddedSize = AlignedAudioBuffer::AlignmentPaddingSize();
+    mSamplesPadding = paddedSize / sizeof(AudioDataValue);
+    if (mSamplesPadding * sizeof(AudioDataValue) < paddedSize) {
+      // Round up.
+      mSamplesPadding++;
+    }
+  }
 
   // Push audio data into the underlying queue with minimal heap allocation
   // slop.  This method is responsible for allocating AudioDataValue[] buffers.
   // The caller must provide a functor to copy the data into the buffers.  The
   // functor must provide the following signature:
   //
   //   uint32_t operator()(AudioDataValue *aBuffer, uint32_t aSamples);
   //
@@ -36,16 +44,19 @@ public:
             uint32_t aFrames, uint32_t aChannels, CopyFunc aCopyFunc)
   {
     // If we are losing more than a reasonable amount to padding, try to chunk
     // the data.
     size_t maxSlop = AudioDataSize(aFrames, aChannels) / MAX_SLOP_DIVISOR;
 
     while (aFrames > 0) {
       uint32_t samples = GetChunkSamples(aFrames, aChannels, maxSlop);
+      if (aFrames * aChannels > mSamplesPadding) {
+        samples -= mSamplesPadding;
+      }
       AlignedAudioBuffer buffer(samples);
       if (!buffer) {
         return false;
       }
 
       // Copy audio data to buffer using caller-provided functor.
       uint32_t framesCopied = aCopyFunc(buffer.get(), samples);
 
@@ -113,13 +124,14 @@ private:
   }
 
   static size_t AudioDataSize(uint32_t aFrames, uint32_t aChannels)
   {
     return aFrames * BytesPerFrame(aChannels);
   }
 
   MediaQueue<AudioData> &mQueue;
+  size_t mSamplesPadding;
 };
 
 } // namespace mozilla
 
 #endif // AudioCompactor_h
--- a/dom/media/MediaData.h
+++ b/dom/media/MediaData.h
@@ -195,31 +195,37 @@ public:
   {
     return mCapacity;
   }
 
   // For backward compatibility with UniquePtr<Type[]>
   Type* get() const { return mData; }
   explicit operator bool() const { return mData != nullptr; }
 
+  // Size in bytes of extra space allocated for padding.
+  static size_t AlignmentPaddingSize()
+  {
+    return AlignmentOffset() * 2;
+  }
+
 private:
-  size_t AlignmentOffset() const
+  static size_t AlignmentOffset()
   {
     return Alignment ? Alignment - 1 : 0;
   }
 
   // Ensure that the backend buffer can hold aLength data. Will update mData.
   // Will enforce that the start of allocated data is always Alignment bytes
   // aligned and that it has sufficient end padding to allow for Alignment bytes
   // block read as required by some data decoders.
   // Returns false if memory couldn't be allocated.
   bool EnsureCapacity(size_t aLength)
   {
     const CheckedInt<size_t> sizeNeeded =
-      CheckedInt<size_t>(aLength) * sizeof(Type) + AlignmentOffset() * 2;
+      CheckedInt<size_t>(aLength) * sizeof(Type) + AlignmentPaddingSize();
 
     if (!sizeNeeded.isValid()) {
       // overflow.
       return false;
     }
     if (mData && mCapacity >= sizeNeeded.value()) {
       return true;
     }