Bug 1341200. Part 8 - let DecoderData::ShutdownDecoder() handle shutdown in the middle of flush. r=jya
authorJW Wang <jwwang@mozilla.com>
Sun, 26 Feb 2017 22:51:22 +0800
changeset 394810 161f4237b402880a0b66cf1981c51e28014f3a3e
parent 394809 4acb3ce34d942b50697a0b62eddca5b7882b37b3
child 394811 28e9aedd34dc5f25e9131e7d508454c449c1f1e0
push id1468
push userasasaki@mozilla.com
push dateMon, 05 Jun 2017 19:31:07 +0000
treeherdermozilla-release@0641fc6ee9d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1341200
milestone54.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 1341200. Part 8 - let DecoderData::ShutdownDecoder() handle shutdown in the middle of flush. r=jya MozReview-Commit-ID: FW23TFQLStR
dom/media/MediaFormatReader.cpp
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -373,33 +373,46 @@ MediaFormatReader::ShutdownPromisePool::
       }
     });
 }
 
 void
 MediaFormatReader::DecoderData::ShutdownDecoder()
 {
   MutexAutoLock lock(mMutex);
-  if (mDecoder) {
-    RefPtr<MediaFormatReader> owner = mOwner;
-    TrackType type = mType == MediaData::AUDIO_DATA
-                     ? TrackType::kAudioTrack
-                     : TrackType::kVideoTrack;
-    mShuttingDown = true;
-    mDecoder->Shutdown()
-      ->Then(mOwner->OwnerThread(), __func__,
-             [owner, this, type]() {
-               mShuttingDown = false;
-               mShutdownPromise.ResolveIfExists(true, __func__);
-               owner->ScheduleUpdate(type);
-             },
-             []() { MOZ_RELEASE_ASSERT(false, "Can't ever be here"); });
+
+  if (!mDecoder) {
+    // No decoder to shut down.
+    return;
+  }
+
+  if (mFlushing) {
+    // Flush is is in action. Shutdown will be initiated after flush completes.
+    if (mShutdownPromise.IsEmpty()) {
+      mOwner->mShutdownPromisePool->Track(mShutdownPromise.Ensure(__func__));
+    }
+    return;
   }
+
+  if (!mShutdownPromise.IsEmpty()) {
+    // This is called from the resolve/reject function of Flush.
+    // Let's continue shutdown.
+    mDecoder->Shutdown()->ChainTo(mShutdownPromise.Steal(), __func__);
+  } else {
+    // No flush is in action. We can shut down the decoder now.
+    mOwner->mShutdownPromisePool->Track(mDecoder->Shutdown());
+  }
+
+  // mShutdownPromisePool will handle the order of decoder shutdown so
+  // we can forget mDecoder and be ready to create a new one.
+  mDecoder = nullptr;
   mDescription = "shutdown";
-  mDecoder = nullptr;
+  mOwner->ScheduleUpdate(mType == MediaData::AUDIO_DATA
+                         ? TrackType::kAudioTrack
+                         : TrackType::kVideoTrack);
 }
 
 void
 MediaFormatReader::DecoderData::Flush()
 {
   if (mFlushing || mFlushed) {
     // Flush still pending or already flushed, nothing more to do.
     return;
@@ -1137,54 +1150,24 @@ MediaFormatReader::Shutdown()
            &MediaFormatReader::TearDownDecoders);
 }
 
 void
 MediaFormatReader::ShutdownDecoder(TrackType aTrack)
 {
   LOGV("%s", TrackTypeToStr(aTrack));
 
+  // Shut down the pending decoder if any.
+  mDecoderFactory->ShutdownDecoder(aTrack);
+
   auto& decoder = GetDecoderData(aTrack);
-  if (!decoder.mDecoder) {
-    LOGV("Already shut down");
-    return;
-  }
-  if (!decoder.mShutdownPromise.IsEmpty()) {
-    LOGV("Shutdown already in progress");
-    return;
-  }
-
-  if (!decoder.mFlushed && decoder.mDecoder) {
-    // The decoder has yet to be flushed.
-    // We always flush the decoder prior to a shutdown to ensure that all the
-    // potentially pending operations on the decoder are completed.
-    decoder.Flush();
-    mShutdownPromisePool->Track(decoder.mShutdownPromise.Ensure(__func__));
-    return;
-  }
-
-  if (decoder.mFlushing || decoder.mShuttingDown) {
-    // Let the current flush or shutdown operation complete, Flush will continue
-    // shutting down the current decoder now that the shutdown promise is set.
-    mShutdownPromisePool->Track(decoder.mShutdownPromise.Ensure(__func__));
-    return;
-  }
-
-  if (!decoder.mDecoder) {
-    // Shutdown any decoders that may be in the process of being initialized
-    // in the Decoder Factory.
-    // This will be a no-op until we're processing the final decoder shutdown
-    // prior to the MediaFormatReader being shutdown.
-    mDecoderFactory->ShutdownDecoder(aTrack);
-    return;
-  }
-
-  // Finally, let's just shut down the currently active decoder.
+  // Flush the decoder if necessary.
+  decoder.Flush();
+  // Shut down the decoder if any.
   decoder.ShutdownDecoder();
-  mShutdownPromisePool->Track(decoder.mShutdownPromise.Ensure(__func__));
 }
 
 RefPtr<ShutdownPromise>
 MediaFormatReader::TearDownDecoders()
 {
   if (mAudio.mTaskQueue) {
     mAudio.mTaskQueue->BeginShutdown();
     mAudio.mTaskQueue->AwaitShutdownAndIdle();