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 292697 ef6f7eda31ff661574b9dcef63a0224cbc19e3fc
parent 292696 a15ba02878040db7fd4332fa81f66bdbac0a30c0
child 292698 aa80c4c2ed4faa382a6fe9214e3a63f9351fd992
push id74954
push userjyavenard@mozilla.com
push dateTue, 12 Apr 2016 03:01:39 +0000
treeherdermozilla-inbound@ef6f7eda31ff [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;
     }