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 488767 40f7fbd43f5189d6710be9a96bc852f73debf6ac
parent 488766 93312ff3f1808a9e79a961d879c340eee99a22b1
child 488768 970b4aaccd355a7512297b26c198441937fc9328
push id246
push userfmarier@mozilla.com
push dateSat, 13 Oct 2018 00:15:40 +0000
reviewersbryce
bugs1496529
milestone64.0a1
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,