Bug 1497951 - P4. Rework and simplify code flow. r=bryce
authorJean-Yves Avenard <jyavenard@mozilla.com>
Wed, 07 Nov 2018 13:49:13 +0000
changeset 444868 80643ce074f619a1b210781d8e0e695e3b3e3372
parent 444867 e8e4842ca7bf4fcb7d2796fed6a72ff1caa8c0a5
child 444869 9b18bd5c4c8b27d090d68e9350caf0401b8c05cd
push id72528
push userjyavenard@mozilla.com
push dateWed, 07 Nov 2018 15:10:53 +0000
treeherderautoland@f91c9161f993 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbryce
bugs1497951
milestone65.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 1497951 - P4. Rework and simplify code flow. r=bryce Depends on D10909 Differential Revision: https://phabricator.services.mozilla.com/D10911
dom/media/platforms/wrappers/MediaChangeMonitor.cpp
dom/media/platforms/wrappers/MediaChangeMonitor.h
--- a/dom/media/platforms/wrappers/MediaChangeMonitor.cpp
+++ b/dom/media/platforms/wrappers/MediaChangeMonitor.cpp
@@ -163,62 +163,62 @@ MediaChangeMonitor::MediaChangeMonitor(P
 MediaChangeMonitor::~MediaChangeMonitor()
 {
 }
 
 RefPtr<MediaDataDecoder::InitPromise>
 MediaChangeMonitor::Init()
 {
   RefPtr<MediaChangeMonitor> self = this;
-  return InvokeAsync(mTaskQueue, __func__, [self, this]() {
-    if (mDecoder) {
-      return mDecoder->Init();
-    }
+  return InvokeAsync(
+    mTaskQueue, __func__, [self, this]() -> RefPtr<InitPromise> {
+      if (mDecoder) {
+        RefPtr<InitPromise> p = mInitPromise.Ensure(__func__);
+        mDecoder->Init()
+          ->Then(mTaskQueue,
+                 __func__,
+                 [self, this](InitPromise::ResolveOrRejectValue&& aValue) {
+                   mInitPromiseRequest.Complete();
+                   if (aValue.IsResolve()) {
+                     mConversionRequired = Some(mDecoder->NeedsConversion());
+                     mCanRecycleDecoder = Some(CanRecycleDecoder());
+                   }
+                   return mInitPromise.ResolveOrRejectIfExists(
+                     std::move(aValue), __func__);
+                 })
+          ->Track(mInitPromiseRequest);
+        return p;
+      }
 
-    // We haven't been able to initialize a decoder due to a missing extradata.
-    return MediaDataDecoder::InitPromise::CreateAndResolve(
-      TrackType::kVideoTrack, __func__);
-  });
+      // We haven't been able to initialize a decoder due to missing extradata.
+      return MediaDataDecoder::InitPromise::CreateAndResolve(
+        TrackType::kVideoTrack, __func__);
+    });
 }
 
 RefPtr<MediaDataDecoder::DecodePromise>
 MediaChangeMonitor::Decode(MediaRawData* aSample)
 {
   RefPtr<MediaChangeMonitor> self = this;
   RefPtr<MediaRawData> sample = aSample;
   return InvokeAsync(mTaskQueue, __func__, [self, this, sample]() {
     MOZ_RELEASE_ASSERT(mFlushPromise.IsEmpty(),
                        "Flush operatin didn't complete");
 
     MOZ_RELEASE_ASSERT(
       !mDecodePromiseRequest.Exists() && !mInitPromiseRequest.Exists(),
       "Can't request a new decode until previous one completed");
 
-    MediaResult rv(NS_OK);
-    if (!mDecoder) {
-      // Attempt to create a decoder, we'll check if all initialisation data
-      // are present.
-      rv = CreateDecoderAndInit(sample);
-      if (rv == NS_ERROR_NOT_INITIALIZED) {
-        // We are missing the required init data to create the decoder.
-        // Ignore for the time being, the MediaRawData will be dropped.
-        return DecodePromise::CreateAndResolve(DecodedData(), __func__);
-      }
-    } else {
-      // Initialize the members that we couldn't if the extradata was given
-      // during MediaChangeMonitor's construction.
-      if (!mConversionRequired) {
-        mConversionRequired = Some(mDecoder->NeedsConversion());
-      }
-      if (!mCanRecycleDecoder) {
-        mCanRecycleDecoder = Some(CanRecycleDecoder());
-      }
-      rv = CheckForChange(sample);
+    MediaResult rv = CheckForChange(sample);
+
+    if (rv == NS_ERROR_NOT_INITIALIZED) {
+      // We are missing the required init data to create the decoder.
+      // Ignore for the time being, the MediaRawData will be dropped.
+      return DecodePromise::CreateAndResolve(DecodedData(), __func__);
     }
-
     if (rv == NS_ERROR_DOM_MEDIA_INITIALIZING_DECODER) {
       // The decoder is pending initialization.
       RefPtr<DecodePromise> p = mDecodePromise.Ensure(__func__);
       return p;
     }
 
     if (NS_FAILED(rv)) {
       return DecodePromise::CreateAndReject(rv, __func__);
@@ -305,16 +305,17 @@ MediaChangeMonitor::Drain()
 }
 
 RefPtr<ShutdownPromise>
 MediaChangeMonitor::Shutdown()
 {
   RefPtr<MediaChangeMonitor> self = this;
   return InvokeAsync(mTaskQueue, __func__, [self, this]() {
     mInitPromiseRequest.DisconnectIfExists();
+    mInitPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
     mDecodePromiseRequest.DisconnectIfExists();
     mDecodePromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
     mDrainRequest.DisconnectIfExists();
     mFlushRequest.DisconnectIfExists();
     mFlushPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
     mShutdownRequest.DisconnectIfExists();
 
     if (mShutdownPromise) {
@@ -462,16 +463,18 @@ MediaChangeMonitor::CreateDecoderAndInit
     return NS_ERROR_DOM_MEDIA_INITIALIZING_DECODER;
   }
   return rv;
 }
 
 bool
 MediaChangeMonitor::CanRecycleDecoder() const
 {
+  AssertOnTaskQueue();
+
   MOZ_ASSERT(mDecoder);
   return StaticPrefs::MediaDecoderRecycleEnabled() &&
          mDecoder->SupportDecoderRecycling();
 }
 
 void
 MediaChangeMonitor::DecodeFirstSample(MediaRawData* aSample)
 {
@@ -508,16 +511,20 @@ MediaChangeMonitor::DecodeFirstSample(Me
     ->Track(mDecodePromiseRequest);
 }
 
 MediaResult
 MediaChangeMonitor::CheckForChange(MediaRawData* aSample)
 {
   AssertOnTaskQueue();
 
+  if (!mDecoder) {
+    return CreateDecoderAndInit(aSample);
+  }
+
   MediaResult rv = mChangeMonitor->CheckForChange(aSample);
 
   if (NS_SUCCEEDED(rv) || rv != NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER) {
     return rv;
   }
 
   if (*mCanRecycleDecoder) {
     // Do not recreate the decoder, reuse it.
--- a/dom/media/platforms/wrappers/MediaChangeMonitor.h
+++ b/dom/media/platforms/wrappers/MediaChangeMonitor.h
@@ -77,17 +77,17 @@ public:
       MediaDataDecoder::ConversionRequired aConversion,
       MediaRawData* aSample) = 0;
     virtual ~CodecChangeMonitor() = default;
   };
 
 private:
   UniquePtr<CodecChangeMonitor> mChangeMonitor;
 
-  void AssertOnTaskQueue()
+  void AssertOnTaskQueue() const
   {
     MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
   }
 
   bool CanRecycleDecoder() const;
 
   // Will create the required MediaDataDecoder if need AVCC and we have a SPS NAL.
   // Returns NS_ERROR_FAILURE if error is permanent and can't be recovered and
@@ -103,16 +103,17 @@ private:
 
   RefPtr<PlatformDecoderModule> mPDM;
   VideoInfo mCurrentConfig;
   RefPtr<layers::KnowsCompositor> mKnowsCompositor;
   RefPtr<layers::ImageContainer> mImageContainer;
   const RefPtr<TaskQueue> mTaskQueue;
   RefPtr<MediaDataDecoder> mDecoder;
   MozPromiseRequestHolder<InitPromise> mInitPromiseRequest;
+  MozPromiseHolder<InitPromise> mInitPromise;
   MozPromiseRequestHolder<DecodePromise> mDecodePromiseRequest;
   MozPromiseHolder<DecodePromise> mDecodePromise;
   MozPromiseRequestHolder<FlushPromise> mFlushRequest;
   MediaDataDecoder::DecodedData mPendingFrames;
   MozPromiseRequestHolder<DecodePromise> mDrainRequest;
   MozPromiseRequestHolder<ShutdownPromise> mShutdownRequest;
   RefPtr<ShutdownPromise> mShutdownPromise;
   MozPromiseHolder<FlushPromise> mFlushPromise;