Bug 1496529 - P6. Always run EMEDecryptor on the decoder's taskqueue. r=bryce
authorJean-Yves Avenard <jyavenard@mozilla.com>
Tue, 09 Oct 2018 22:58:05 +0000
changeset 496090 40f7fbd43f5189d6710be9a96bc852f73debf6ac
parent 496089 93312ff3f1808a9e79a961d879c340eee99a22b1
child 496091 970b4aaccd355a7512297b26c198441937fc9328
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbryce
bugs1496529
milestone64.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 1496529 - P6. Always run EMEDecryptor on the decoder's taskqueue. r=bryce P2 changed the way the H264Converter would be calling the decoder. The assumption in the EMEDecryptor was pretty incorrect to start with. Depends on D7865 Differential Revision: https://phabricator.services.mozilla.com/D7882
dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
--- a/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
@@ -97,38 +97,41 @@ public:
   RefPtr<InitPromise> Init() override
   {
     MOZ_ASSERT(!mIsShutdown);
     return mDecoder->Init();
   }
 
   RefPtr<DecodePromise> Decode(MediaRawData* aSample) override
   {
-    MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
-    MOZ_RELEASE_ASSERT(mDecrypts.Count() == 0,
-                       "Can only process one sample at a time");
-    RefPtr<DecodePromise> p = mDecodePromise.Ensure(__func__);
+    RefPtr<EMEDecryptor> self = this;
+    RefPtr<MediaRawData> sample = aSample;
+    return InvokeAsync(mTaskQueue, __func__, [self, this, sample]() {
+      MOZ_RELEASE_ASSERT(mDecrypts.Count() == 0,
+                         "Can only process one sample at a time");
+      RefPtr<DecodePromise> p = mDecodePromise.Ensure(__func__);
 
-    RefPtr<EMEDecryptor> self = this;
-    mSamplesWaitingForKey->WaitIfKeyNotUsable(aSample)
-      ->Then(mTaskQueue, __func__,
-             [self](RefPtr<MediaRawData> aSample) {
-               self->mKeyRequest.Complete();
-               self->ThrottleDecode(aSample);
-             },
-             [self]() {
-               self->mKeyRequest.Complete();
-             })
-      ->Track(mKeyRequest);
+      mSamplesWaitingForKey->WaitIfKeyNotUsable(sample)
+        ->Then(mTaskQueue,
+               __func__,
+               [self](const RefPtr<MediaRawData>& aSample) {
+                 self->mKeyRequest.Complete();
+                 self->ThrottleDecode(aSample);
+               },
+               [self]() { self->mKeyRequest.Complete(); })
+        ->Track(mKeyRequest);
 
-    return p;
+      return p;
+    });
   }
 
   void ThrottleDecode(MediaRawData* aSample)
   {
+    MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
+
     RefPtr<EMEDecryptor> self = this;
     mThroughputLimiter.Throttle(aSample)
       ->Then(mTaskQueue, __func__,
              [self] (RefPtr<MediaRawData> aSample) {
                self->mThrottleRequest.Complete();
                self->AttemptDecode(aSample);
              },
              [self]() {
@@ -221,60 +224,65 @@ public:
                  self->mDecodePromise.RejectIfExists(aError, __func__);
                })
         ->Track(mDecodeRequest);
     }
   }
 
   RefPtr<FlushPromise> Flush() override
   {
-    MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
-    MOZ_ASSERT(!mIsShutdown);
-    mKeyRequest.DisconnectIfExists();
-    mThrottleRequest.DisconnectIfExists();
-    mDecodeRequest.DisconnectIfExists();
-    mDecodePromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
-    mThroughputLimiter.Flush();
-    for (auto iter = mDecrypts.Iter(); !iter.Done(); iter.Next()) {
-      nsAutoPtr<DecryptPromiseRequestHolder>& holder = iter.Data();
-      holder->DisconnectIfExists();
-      iter.Remove();
-    }
-    RefPtr<SamplesWaitingForKey> k = mSamplesWaitingForKey;
-    return mDecoder->Flush()->Then(
-      mTaskQueue, __func__,
-      [k]() {
-        k->Flush();
-        return FlushPromise::CreateAndResolve(true, __func__);
+    RefPtr<EMEDecryptor> self = this;
+    return InvokeAsync(
+      mTaskQueue, __func__, [self, this]() -> RefPtr<FlushPromise> {
+        MOZ_ASSERT(!mIsShutdown);
+        mKeyRequest.DisconnectIfExists();
+        mThrottleRequest.DisconnectIfExists();
+        mDecodeRequest.DisconnectIfExists();
+        mDecodePromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
+        mThroughputLimiter.Flush();
+        for (auto iter = mDecrypts.Iter(); !iter.Done(); iter.Next()) {
+          nsAutoPtr<DecryptPromiseRequestHolder>& holder = iter.Data();
+          holder->DisconnectIfExists();
+          iter.Remove();
+        }
+        RefPtr<SamplesWaitingForKey> k = mSamplesWaitingForKey;
+        return mDecoder->Flush()->Then(mTaskQueue, __func__, [k]() {
+          k->Flush();
+          return FlushPromise::CreateAndResolve(true, __func__);
+        });
       });
   }
 
   RefPtr<DecodePromise> Drain() override
   {
-    MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
-    MOZ_ASSERT(!mIsShutdown);
-    MOZ_ASSERT(mDecodePromise.IsEmpty() && !mDecodeRequest.Exists(),
-               "Must wait for decoding to complete");
-    for (auto iter = mDecrypts.Iter(); !iter.Done(); iter.Next()) {
-      nsAutoPtr<DecryptPromiseRequestHolder>& holder = iter.Data();
-      holder->DisconnectIfExists();
-      iter.Remove();
-    }
-    return mDecoder->Drain();
+    RefPtr<EMEDecryptor> self = this;
+    return InvokeAsync(mTaskQueue, __func__, [self, this]() {
+      MOZ_ASSERT(!mIsShutdown);
+      MOZ_ASSERT(mDecodePromise.IsEmpty() && !mDecodeRequest.Exists(),
+                 "Must wait for decoding to complete");
+      for (auto iter = mDecrypts.Iter(); !iter.Done(); iter.Next()) {
+        nsAutoPtr<DecryptPromiseRequestHolder>& holder = iter.Data();
+        holder->DisconnectIfExists();
+        iter.Remove();
+      }
+      return mDecoder->Drain();
+    });
   }
 
   RefPtr<ShutdownPromise> Shutdown() override
   {
-    MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
-    MOZ_ASSERT(!mIsShutdown);
-    mIsShutdown = true;
-    mSamplesWaitingForKey = nullptr;
-    RefPtr<MediaDataDecoder> decoder = mDecoder.forget();
-    mProxy = nullptr;
-    return decoder->Shutdown();
+    RefPtr<EMEDecryptor> self = this;
+    return InvokeAsync(mTaskQueue, __func__, [self, this]() {
+      MOZ_ASSERT(!mIsShutdown);
+      mIsShutdown = true;
+      mSamplesWaitingForKey = nullptr;
+      RefPtr<MediaDataDecoder> decoder = mDecoder.forget();
+      mProxy = nullptr;
+      return decoder->Shutdown();
+    });
   }
 
   nsCString GetDescriptionName() const override
   {
     return mDecoder->GetDescriptionName();
   }
 
   ConversionRequired NeedsConversion() const override
@@ -326,60 +334,70 @@ EMEMediaDataDecoderProxy::EMEMediaDataDe
                                aParams.mOnWaitingForKeyEvent))
   , mProxy(aProxy)
 {
 }
 
 RefPtr<MediaDataDecoder::DecodePromise>
 EMEMediaDataDecoderProxy::Decode(MediaRawData* aSample)
 {
-  RefPtr<DecodePromise> p = mDecodePromise.Ensure(__func__);
-
   RefPtr<EMEMediaDataDecoderProxy> self = this;
-  mSamplesWaitingForKey->WaitIfKeyNotUsable(aSample)
-    ->Then(mTaskQueue, __func__,
-           [self, this](RefPtr<MediaRawData> aSample) {
-             mKeyRequest.Complete();
+  RefPtr<MediaRawData> sample = aSample;
+  return InvokeAsync(mTaskQueue, __func__, [self, this, sample]() {
+    RefPtr<DecodePromise> p = mDecodePromise.Ensure(__func__);
+    mSamplesWaitingForKey->WaitIfKeyNotUsable(sample)
+      ->Then(mTaskQueue,
+             __func__,
+             [self, this](RefPtr<MediaRawData> aSample) {
+               mKeyRequest.Complete();
 
-             MediaDataDecoderProxy::Decode(aSample)
-               ->Then(mTaskQueue, __func__,
-                      [self, this](const DecodedData& aResults) {
-                        mDecodeRequest.Complete();
-                        mDecodePromise.Resolve(aResults, __func__);
-                      },
-                      [self, this](const MediaResult& aError) {
-                        mDecodeRequest.Complete();
-                        mDecodePromise.Reject(aError, __func__);
-                      })
-               ->Track(mDecodeRequest);
-           },
-           [self]() {
-             self->mKeyRequest.Complete();
-             MOZ_CRASH("Should never get here");
-           })
-    ->Track(mKeyRequest);
+               MediaDataDecoderProxy::Decode(aSample)
+                 ->Then(mTaskQueue,
+                        __func__,
+                        [self, this](const DecodedData& aResults) {
+                          mDecodeRequest.Complete();
+                          mDecodePromise.Resolve(aResults, __func__);
+                        },
+                        [self, this](const MediaResult& aError) {
+                          mDecodeRequest.Complete();
+                          mDecodePromise.Reject(aError, __func__);
+                        })
+                 ->Track(mDecodeRequest);
+             },
+             [self]() {
+               self->mKeyRequest.Complete();
+               MOZ_CRASH("Should never get here");
+             })
+      ->Track(mKeyRequest);
 
-  return p;
+    return p;
+  });
 }
 
 RefPtr<MediaDataDecoder::FlushPromise>
 EMEMediaDataDecoderProxy::Flush()
 {
-  mKeyRequest.DisconnectIfExists();
-  mDecodeRequest.DisconnectIfExists();
-  mDecodePromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
-  return MediaDataDecoderProxy::Flush();
+  RefPtr<EMEMediaDataDecoderProxy> self = this;
+  return InvokeAsync(mTaskQueue, __func__, [self, this]() {
+    mKeyRequest.DisconnectIfExists();
+    mDecodeRequest.DisconnectIfExists();
+    mDecodePromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
+    return MediaDataDecoderProxy::Flush();
+  });
 }
 
 RefPtr<ShutdownPromise>
 EMEMediaDataDecoderProxy::Shutdown()
 {
-  mSamplesWaitingForKey = nullptr;
-  mProxy = nullptr;
-  return MediaDataDecoderProxy::Shutdown();
+  RefPtr<EMEMediaDataDecoderProxy> self = this;
+  return InvokeAsync(mTaskQueue, __func__, [self, this]() {
+    mSamplesWaitingForKey = nullptr;
+    mProxy = nullptr;
+    return MediaDataDecoderProxy::Shutdown();
+  });
 }
 
 EMEDecoderModule::EMEDecoderModule(CDMProxy* aProxy, PDMFactory* aPDM)
   : mProxy(aProxy)
   , mPDM(aPDM)
 {
 }
 
@@ -426,17 +444,17 @@ EMEDecoderModule::CreateVideoDecoder(con
 
   MOZ_ASSERT(mPDM);
   RefPtr<MediaDataDecoder> decoder(mPDM->CreateDecoder(aParams));
   if (!decoder) {
     return nullptr;
   }
 
   RefPtr<MediaDataDecoder> emeDecoder(new EMEDecryptor(
-    decoder, mProxy, AbstractThread::GetCurrent()->AsTaskQueue(),
+    decoder, mProxy, aParams.mTaskQueue,
     aParams.mType, aParams.mOnWaitingForKeyEvent));
   return emeDecoder.forget();
 }
 
 already_AddRefed<MediaDataDecoder>
 EMEDecoderModule::CreateAudioDecoder(const CreateDecoderParams& aParams)
 {
   MOZ_ASSERT(aParams.mConfig.mCrypto.mValid);
@@ -461,17 +479,17 @@ EMEDecoderModule::CreateAudioDecoder(con
   RefPtr<MediaDataDecoder> decoder(mPDM->CreateDecoder(aParams));
   if (!decoder) {
     return nullptr;
   }
 
   RefPtr<MediaDataDecoder> emeDecoder(
     new EMEDecryptor(decoder,
                      mProxy,
-                     AbstractThread::GetCurrent()->AsTaskQueue(),
+                     aParams.mTaskQueue,
                      aParams.mType,
                      aParams.mOnWaitingForKeyEvent,
                      std::move(converter)));
   return emeDecoder.forget();
 }
 
 bool
 EMEDecoderModule::SupportsMimeType(const nsACString& aMimeType,