bug 1391482 generalize WebAudioDecodeJob buffer as AudioChunk r=padenot
authorKarl Tomlinson <karlt+@karlt.net>
Wed, 16 Aug 2017 18:10:06 +1200
changeset 377742 76419265414eb717527bb94b4e896964993729bc
parent 377741 480d761a45ae40b175502e9769a1f5a3838446b1
child 377743 a3aa8b09341fa06b92d9d3a6ac8cb8b951df2d7f
push id94338
push userkwierso@gmail.com
push dateThu, 31 Aug 2017 02:58:58 +0000
treeherdermozilla-inbound@9ca18987dabb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs1391482
milestone57.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 1391482 generalize WebAudioDecodeJob buffer as AudioChunk r=padenot MozReview-Commit-ID: 4H3F0SzAknc
dom/media/webaudio/MediaBufferDecoder.cpp
dom/media/webaudio/MediaBufferDecoder.h
--- a/dom/media/webaudio/MediaBufferDecoder.cpp
+++ b/dom/media/webaudio/MediaBufferDecoder.cpp
@@ -335,84 +335,94 @@ MediaDecodeTask::FinishDecode()
                                      destSampleRate,
                                      SPEEX_RESAMPLER_QUALITY_DEFAULT, nullptr);
     speex_resampler_skip_zeros(resampler);
     resampledFrames += speex_resampler_get_output_latency(resampler);
   }
 
   // Allocate the channel buffers.  Note that if we end up resampling, we may
   // write fewer bytes than mResampledFrames to the output buffer, in which
-  // case mWriteIndex will tell us how many valid samples we have.
-  mDecodeJob.mBuffer = ThreadSharedFloatArrayBufferList::
+  // case writeIndex will tell us how many valid samples we have.
+  RefPtr<ThreadSharedFloatArrayBufferList> buffer =
+    ThreadSharedFloatArrayBufferList::
     Create(channelCount, resampledFrames, fallible);
-  if (!mDecodeJob.mBuffer) {
+  if (!buffer) {
     ReportFailureOnMainThread(WebAudioDecodeJob::UnknownError);
     return;
   }
+  mDecodeJob.mBuffer.mChannelData.SetLength(channelCount);
+  for (uint32_t i = 0; i < channelCount; ++i) {
+    mDecodeJob.mBuffer.mChannelData[i] = buffer->GetData(i);
+  }
+  mDecodeJob.mBuffer.mBuffer = buffer.forget();
+  mDecodeJob.mBuffer.mVolume = 1.0f;
+  mDecodeJob.mBuffer.mBufferFormat = AUDIO_FORMAT_FLOAT32;
 
+  uint32_t writeIndex = 0;
   RefPtr<AudioData> audioData;
   while ((audioData = mAudioQueue.PopFront())) {
     audioData->EnsureAudioBuffer(); // could lead to a copy :(
     AudioDataValue* bufferData = static_cast<AudioDataValue*>
       (audioData->mAudioBuffer->Data());
 
     if (sampleRate != destSampleRate) {
-      const uint32_t maxOutSamples = resampledFrames - mDecodeJob.mWriteIndex;
+      const uint32_t maxOutSamples = resampledFrames - writeIndex;
 
       for (uint32_t i = 0; i < audioData->mChannels; ++i) {
         uint32_t inSamples = audioData->mFrames;
         uint32_t outSamples = maxOutSamples;
         float* outData =
-          mDecodeJob.mBuffer->GetDataForWrite(i) + mDecodeJob.mWriteIndex;
+          mDecodeJob.mBuffer.ChannelDataForWrite<float>(i) + writeIndex;
 
         WebAudioUtils::SpeexResamplerProcess(
             resampler, i, &bufferData[i * audioData->mFrames], &inSamples,
             outData, &outSamples);
 
         if (i == audioData->mChannels - 1) {
-          mDecodeJob.mWriteIndex += outSamples;
-          MOZ_ASSERT(mDecodeJob.mWriteIndex <= resampledFrames);
+          writeIndex += outSamples;
+          MOZ_ASSERT(writeIndex <= resampledFrames);
           MOZ_ASSERT(inSamples == audioData->mFrames);
         }
       }
     } else {
       for (uint32_t i = 0; i < audioData->mChannels; ++i) {
         float* outData =
-          mDecodeJob.mBuffer->GetDataForWrite(i) + mDecodeJob.mWriteIndex;
+          mDecodeJob.mBuffer.ChannelDataForWrite<float>(i) + writeIndex;
         ConvertAudioSamples(&bufferData[i * audioData->mFrames],
                             outData, audioData->mFrames);
 
         if (i == audioData->mChannels - 1) {
-          mDecodeJob.mWriteIndex += audioData->mFrames;
+          writeIndex += audioData->mFrames;
         }
       }
     }
   }
 
   if (sampleRate != destSampleRate) {
     uint32_t inputLatency = speex_resampler_get_input_latency(resampler);
-    const uint32_t maxOutSamples = resampledFrames - mDecodeJob.mWriteIndex;
+    const uint32_t maxOutSamples = resampledFrames - writeIndex;
     for (uint32_t i = 0; i < channelCount; ++i) {
       uint32_t inSamples = inputLatency;
       uint32_t outSamples = maxOutSamples;
       float* outData =
-        mDecodeJob.mBuffer->GetDataForWrite(i) + mDecodeJob.mWriteIndex;
+        mDecodeJob.mBuffer.ChannelDataForWrite<float>(i) + writeIndex;
 
       WebAudioUtils::SpeexResamplerProcess(
           resampler, i, (AudioDataValue*)nullptr, &inSamples,
           outData, &outSamples);
 
       if (i == channelCount - 1) {
-        mDecodeJob.mWriteIndex += outSamples;
-        MOZ_ASSERT(mDecodeJob.mWriteIndex <= resampledFrames);
+        writeIndex += outSamples;
+        MOZ_ASSERT(writeIndex <= resampledFrames);
         MOZ_ASSERT(inSamples == inputLatency);
       }
     }
   }
 
+  mDecodeJob.mBuffer.mDuration = writeIndex;
   mPhase = PhaseEnum::AllocateBuffer;
   mMainThread->Dispatch(do_AddRef(this));
 }
 
 void
 MediaDecodeTask::AllocateBuffer()
 {
   MOZ_ASSERT(NS_IsMainThread());
@@ -439,22 +449,19 @@ MediaDecodeTask::CallbackTheResult()
 
 bool
 WebAudioDecodeJob::AllocateBuffer()
 {
   MOZ_ASSERT(!mOutput);
   MOZ_ASSERT(NS_IsMainThread());
 
   // Now create the AudioBuffer
-  ErrorResult rv;
-  uint32_t channelCount = mBuffer->GetChannels();
-  mOutput = AudioBuffer::Create(mContext->GetOwner(), channelCount,
-                                mWriteIndex, mContext->SampleRate(),
-                                mBuffer.forget(), rv);
-  return !rv.Failed();
+  mOutput = AudioBuffer::Create(mContext->GetOwner(),
+                                mContext->SampleRate(), Move(mBuffer));
+  return mOutput != nullptr;
 }
 
 void
 AsyncDecodeWebAudio(const char* aContentType, uint8_t* aBuffer,
                     uint32_t aLength, WebAudioDecodeJob& aDecodeJob)
 {
   Maybe<MediaContainerType> containerType = MakeMediaContainerType(aContentType);
   // Do not attempt to decode the media if we were not successful at sniffing
@@ -490,17 +497,16 @@ AsyncDecodeWebAudio(const char* aContent
 }
 
 WebAudioDecodeJob::WebAudioDecodeJob(const nsACString& aContentType,
                                      AudioContext* aContext,
                                      Promise* aPromise,
                                      DecodeSuccessCallback* aSuccessCallback,
                                      DecodeErrorCallback* aFailureCallback)
   : mContentType(aContentType)
-  , mWriteIndex(0)
   , mContext(aContext)
   , mPromise(aPromise)
   , mSuccessCallback(aSuccessCallback)
   , mFailureCallback(aFailureCallback)
 {
   MOZ_ASSERT(aContext);
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_COUNT_CTOR(WebAudioDecodeJob);
@@ -590,19 +596,17 @@ WebAudioDecodeJob::SizeOfExcludingThis(M
     amount += mSuccessCallback->SizeOfIncludingThis(aMallocSizeOf);
   }
   if (mFailureCallback) {
     amount += mFailureCallback->SizeOfIncludingThis(aMallocSizeOf);
   }
   if (mOutput) {
     amount += mOutput->SizeOfIncludingThis(aMallocSizeOf);
   }
-  if (mBuffer) {
-    amount += mBuffer->SizeOfIncludingThis(aMallocSizeOf);
-  }
+  amount += mBuffer.SizeOfExcludingThis(aMallocSizeOf, false);
   return amount;
 }
 
 size_t
 WebAudioDecodeJob::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
 }
--- a/dom/media/webaudio/MediaBufferDecoder.h
+++ b/dom/media/webaudio/MediaBufferDecoder.h
@@ -2,16 +2,17 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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/. */
 
 #ifndef MediaBufferDecoder_h_
 #define MediaBufferDecoder_h_
 
+#include "AudioSegment.h"
 #include "nsWrapperCache.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "mozilla/dom/TypedArray.h"
 #include "mozilla/MemoryReporting.h"
 
 namespace mozilla {
@@ -50,24 +51,23 @@ struct WebAudioDecodeJob final
   void OnSuccess(ErrorCode /* ignored */);
   void OnFailure(ErrorCode aErrorCode);
 
   bool AllocateBuffer();
 
   size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
+  AudioChunk mBuffer;
   nsCString mContentType;
-  uint32_t mWriteIndex;
   RefPtr<dom::AudioContext> mContext;
   RefPtr<dom::Promise> mPromise;
   RefPtr<dom::DecodeSuccessCallback> mSuccessCallback;
   RefPtr<dom::DecodeErrorCallback> mFailureCallback; // can be null
   RefPtr<dom::AudioBuffer> mOutput;
-  RefPtr<ThreadSharedFloatArrayBufferList> mBuffer;
 };
 
 void AsyncDecodeWebAudio(const char* aContentType, uint8_t* aBuffer,
                          uint32_t aLength, WebAudioDecodeJob& aDecodeJob);
 
 } // namespace mozilla
 
 #endif