Bug 1311876: P2. Recreate audio decoder when an error occurs. r=gerald
authorJean-Yves Avenard <jyavenard@mozilla.com>
Wed, 26 Oct 2016 09:06:14 +1100
changeset 362409 cecc442d8369d14b87dfbb84d6c26795e6425523
parent 362408 8d250d43e701c22487fe99542096aa3d9ba801c4
child 362410 7deb2a00563d8f87b64dcaefcaaf223937aee1ef
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-beta@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald
bugs1311876
milestone52.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 1311876: P2. Recreate audio decoder when an error occurs. r=gerald MozReview-Commit-ID: CwQMZwSNndO
dom/media/platforms/apple/AppleATDecoder.cpp
dom/media/platforms/apple/AppleATDecoder.h
--- a/dom/media/platforms/apple/AppleATDecoder.cpp
+++ b/dom/media/platforms/apple/AppleATDecoder.cpp
@@ -24,16 +24,17 @@ AppleATDecoder::AppleATDecoder(const Aud
   : mConfig(aConfig)
   , mFileStreamError(false)
   , mTaskQueue(aTaskQueue)
   , mCallback(aCallback)
   , mConverter(nullptr)
   , mStream(nullptr)
   , mIsFlushing(false)
   , mParsedFramesForAACMagicCookie(0)
+  , mErrored(false)
 {
   MOZ_COUNT_CTOR(AppleATDecoder);
   LOG("Creating Apple AudioToolbox decoder");
   LOG("Audio Decoder configuration: %s %d Hz %d channels %d bits per channel",
       mConfig.mMimeType.get(),
       mConfig.mRate,
       mConfig.mChannels,
       mConfig.mBitDepth);
@@ -84,19 +85,27 @@ AppleATDecoder::Input(MediaRawData* aSam
   mTaskQueue->Dispatch(runnable.forget());
 }
 
 void
 AppleATDecoder::ProcessFlush()
 {
   MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
   mQueuedSamples.Clear();
-  OSStatus rv = AudioConverterReset(mConverter);
-  if (rv) {
-    LOG("Error %d resetting AudioConverter", rv);
+  if (mConverter) {
+    OSStatus rv = AudioConverterReset(mConverter);
+    if (rv) {
+      LOG("Error %d resetting AudioConverter", rv);
+    }
+  }
+  if (mErrored) {
+    mParsedFramesForAACMagicCookie = 0;
+    mMagicCookie.Clear();
+    ProcessShutdown();
+    mErrored = false;
   }
 }
 
 void
 AppleATDecoder::Flush()
 {
   MOZ_ASSERT(mCallback->OnReaderTaskQueue());
   LOG("Flushing AudioToolbox AAC decoder");
@@ -116,34 +125,43 @@ AppleATDecoder::Drain()
   mCallback->DrainComplete();
   Flush();
 }
 
 void
 AppleATDecoder::Shutdown()
 {
   MOZ_ASSERT(mCallback->OnReaderTaskQueue());
+  nsCOMPtr<nsIRunnable> runnable =
+    NewRunnableMethod(this, &AppleATDecoder::ProcessShutdown);
+  SyncRunnable::DispatchToThread(mTaskQueue, runnable);
+}
 
-  LOG("Shutdown: Apple AudioToolbox AAC decoder");
-  mQueuedSamples.Clear();
-  OSStatus rv = AudioConverterDispose(mConverter);
-  if (rv) {
-    LOG("error %d disposing of AudioConverter", rv);
-    return;
-  }
-  mConverter = nullptr;
+void
+AppleATDecoder::ProcessShutdown()
+{
+  MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
 
   if (mStream) {
-    rv = AudioFileStreamClose(mStream);
+    OSStatus rv = AudioFileStreamClose(mStream);
     if (rv) {
       LOG("error %d disposing of AudioFileStream", rv);
       return;
     }
     mStream = nullptr;
   }
+
+  if (mConverter) {
+    LOG("Shutdown: Apple AudioToolbox AAC decoder");
+    OSStatus rv = AudioConverterDispose(mConverter);
+    if (rv) {
+      LOG("error %d disposing of AudioConverter", rv);
+    }
+    mConverter = nullptr;
+  }
 }
 
 struct PassthroughUserData {
   UInt32 mChannels;
   UInt32 mDataSize;
   const void* mData;
   AudioStreamPacketDescription mPacket;
 };
@@ -202,17 +220,17 @@ AppleATDecoder::SubmitSample(MediaRawDat
   }
 
   mQueuedSamples.AppendElement(aSample);
 
   if (rv == NS_OK) {
     for (size_t i = 0; i < mQueuedSamples.Length(); i++) {
       rv = DecodeSample(mQueuedSamples[i]);
       if (NS_FAILED(rv)) {
-        mQueuedSamples.Clear();
+        mErrored = true;
         mCallback->Error(MediaResult(
           rv, RESULT_DETAIL("Unable to decode sample %lld", aSample->mTime)));
         return;
       }
     }
     mQueuedSamples.Clear();
   }
   mCallback->InputExhausted();
--- a/dom/media/platforms/apple/AppleATDecoder.h
+++ b/dom/media/platforms/apple/AppleATDecoder.h
@@ -54,23 +54,25 @@ private:
   UInt32 mFormatID;
   AudioFileStreamID mStream;
   nsTArray<RefPtr<MediaRawData>> mQueuedSamples;
   UniquePtr<AudioConfig::ChannelLayout> mChannelLayout;
   UniquePtr<AudioConverter> mAudioConverter;
   Atomic<bool> mIsFlushing;
 
   void ProcessFlush();
+  void ProcessShutdown();
   void SubmitSample(MediaRawData* aSample);
   nsresult DecodeSample(MediaRawData* aSample);
   nsresult GetInputAudioDescription(AudioStreamBasicDescription& aDesc,
                                     const nsTArray<uint8_t>& aExtraData);
   // Setup AudioConverter once all information required has been gathered.
   // Will return NS_ERROR_NOT_INITIALIZED if more data is required.
   nsresult SetupDecoder(MediaRawData* aSample);
   nsresult GetImplicitAACMagicCookie(const MediaRawData* aSample);
   nsresult SetupChannelLayout();
   uint32_t mParsedFramesForAACMagicCookie;
+  bool mErrored;
 };
 
 } // namespace mozilla
 
 #endif // mozilla_AppleATDecoder_h