Bug 1325558 - [EME][Fennec] Handle Sample wait for key for OOP decoding case. draft
authorJames Cheng <jacheng@mozilla.com>
Fri, 23 Dec 2016 15:47:58 +0800
changeset 453805 8089786754147901d484b3bd61efcc4bca5ee494
parent 453804 1156db49e976173fc3cf90d2126456fd1e2bae4b
child 540528 eaa39d1ab20215d0aba2d64ec9515c938280b12f
push id39738
push userbmo:jacheng@mozilla.com
push dateSun, 25 Dec 2016 03:58:33 +0000
bugs1325558
milestone53.0a1
Bug 1325558 - [EME][Fennec] Handle Sample wait for key for OOP decoding case. MozReview-Commit-ID: KqdAdqdpAvX
dom/media/platforms/android/AndroidDecoderModule.cpp
dom/media/platforms/android/MediaCodecDataDecoder.cpp
dom/media/platforms/android/RemoteDataDecoder.cpp
dom/media/platforms/android/RemoteDataDecoder.h
--- a/dom/media/platforms/android/AndroidDecoderModule.cpp
+++ b/dom/media/platforms/android/AndroidDecoderModule.cpp
@@ -195,17 +195,19 @@ AndroidDecoderModule::CreateVideoDecoder
     drmStubId = mProxy->GetMediaDrmStubId();
   }
 
   RefPtr<MediaDataDecoder> decoder = MediaPrefs::PDMAndroidRemoteCodecEnabled() ?
     RemoteDataDecoder::CreateVideoDecoder(config,
                                           format,
                                           aParams.mCallback,
                                           aParams.mImageContainer,
-                                          drmStubId) :
+                                          drmStubId,
+                                          mProxy,
+                                          aParams.mTaskQueue) :
     MediaCodecDataDecoder::CreateVideoDecoder(config,
                                               format,
                                               aParams.mCallback,
                                               aParams.mImageContainer,
                                               drmStubId,
                                               mProxy,
                                               aParams.mTaskQueue);
   return decoder.forget();
@@ -231,17 +233,22 @@ AndroidDecoderModule::CreateAudioDecoder
       config.mChannels,
       &format), nullptr);
 
   nsString drmStubId;
   if (mProxy) {
     drmStubId = mProxy->GetMediaDrmStubId();
   }
   RefPtr<MediaDataDecoder> decoder = MediaPrefs::PDMAndroidRemoteCodecEnabled() ?
-      RemoteDataDecoder::CreateAudioDecoder(config, format, aParams.mCallback, drmStubId) :
+      RemoteDataDecoder::CreateAudioDecoder(config,
+                                            format,
+                                            aParams.mCallback,
+                                            drmStubId,
+                                            mProxy,
+                                            aParams.mTaskQueue) :
       MediaCodecDataDecoder::CreateAudioDecoder(config,
                                                 format,
                                                 aParams.mCallback,
                                                 drmStubId,
                                                 mProxy,
                                                 aParams.mTaskQueue);
   return decoder.forget();
 }
--- a/dom/media/platforms/android/MediaCodecDataDecoder.cpp
+++ b/dom/media/platforms/android/MediaCodecDataDecoder.cpp
@@ -137,19 +137,19 @@ class EMEVideoDataDecoder : public Video
 public:
   EMEVideoDataDecoder(const VideoInfo& aConfig,
                       MediaFormat::Param aFormat,
                       MediaDataDecoderCallback* aCallback,
                       layers::ImageContainer* aImageContainer,
                       const nsString& aDrmStubId,
                       CDMProxy* aProxy,
                       TaskQueue* aTaskQueue)
-   : VideoDataDecoder(aConfig, aFormat, aCallback, aImageContainer, aDrmStubId)
-   , mSamplesWaitingForKey(new SamplesWaitingForKey(this, aCallback,
-                                                    aTaskQueue, aProxy))
+    : VideoDataDecoder(aConfig, aFormat, aCallback, aImageContainer, aDrmStubId)
+    , mSamplesWaitingForKey(new SamplesWaitingForKey(this, aCallback,
+                                                     aTaskQueue, aProxy))
   {
   }
 
   void Input(MediaRawData* aSample) override;
   void Shutdown() override;
 
 private:
   RefPtr<SamplesWaitingForKey> mSamplesWaitingForKey;
@@ -255,19 +255,19 @@ public:
   }
 };
 
 class EMEAudioDataDecoder : public AudioDataDecoder {
 public:
   EMEAudioDataDecoder(const AudioInfo& aConfig, MediaFormat::Param aFormat,
                       MediaDataDecoderCallback* aCallback, const nsString& aDrmStubId,
                       CDMProxy* aProxy, TaskQueue* aTaskQueue)
-   : AudioDataDecoder(aConfig, aFormat, aCallback, aDrmStubId)
-   , mSamplesWaitingForKey(new SamplesWaitingForKey(this, aCallback,
-                                                    aTaskQueue, aProxy))
+    : AudioDataDecoder(aConfig, aFormat, aCallback, aDrmStubId)
+    , mSamplesWaitingForKey(new SamplesWaitingForKey(this, aCallback,
+                                                     aTaskQueue, aProxy))
   {
   }
 
   void Input(MediaRawData* aSample) override;
   void Shutdown() override;
 
 private:
   RefPtr<SamplesWaitingForKey> mSamplesWaitingForKey;
--- a/dom/media/platforms/android/RemoteDataDecoder.cpp
+++ b/dom/media/platforms/android/RemoteDataDecoder.cpp
@@ -94,17 +94,17 @@ public:
   {
     mDecoderCallback = nullptr;
   }
 
 protected:
   MediaDataDecoderCallback* mDecoderCallback;
 };
 
-class RemoteVideoDecoder final : public RemoteDataDecoder
+class RemoteVideoDecoder : public RemoteDataDecoder
 {
 public:
   // Hold an output buffer and render it to the surface when the frame is sent to compositor, or
   // release it if not presented.
   class RenderOrReleaseOutput : public VideoData::Listener
   {
   public:
     RenderOrReleaseOutput(java::CodecProxy::Param aCodec, java::Sample::Param aSample)
@@ -203,20 +203,20 @@ public:
 
     friend class RemoteDataDecoder;
 
   private:
     RemoteVideoDecoder* mDecoder;
   };
 
   RemoteVideoDecoder(const VideoInfo& aConfig,
-                   MediaFormat::Param aFormat,
-                   MediaDataDecoderCallback* aCallback,
-                   layers::ImageContainer* aImageContainer,
-                   const nsString& aDrmStubId)
+                     MediaFormat::Param aFormat,
+                     MediaDataDecoderCallback* aCallback,
+                     layers::ImageContainer* aImageContainer,
+                     const nsString& aDrmStubId)
     : RemoteDataDecoder(MediaData::Type::VIDEO_DATA, aConfig.mMimeType,
                         aFormat, aCallback, aDrmStubId)
     , mImageContainer(aImageContainer)
     , mConfig(aConfig)
   {
   }
 
   RefPtr<InitPromise> Init() override
@@ -310,17 +310,57 @@ private:
 
   layers::ImageContainer* mImageContainer;
   const VideoInfo& mConfig;
   RefPtr<AndroidSurfaceTexture> mSurfaceTexture;
   DurationQueue mInputDurations;
   bool mIsCodecSupportAdaptivePlayback = false;
 };
 
-class RemoteAudioDecoder final : public RemoteDataDecoder
+class RemoteEMEVideoDecoder : public RemoteVideoDecoder {
+public:
+  RemoteEMEVideoDecoder(const VideoInfo& aConfig,
+                        MediaFormat::Param aFormat,
+                        MediaDataDecoderCallback* aCallback,
+                        layers::ImageContainer* aImageContainer,
+                        const nsString& aDrmStubId,
+                        CDMProxy* aProxy,
+                        TaskQueue* aTaskQueue)
+    : RemoteVideoDecoder(aConfig, aFormat, aCallback, aImageContainer, aDrmStubId)
+    , mSamplesWaitingForKey(new SamplesWaitingForKey(this, aCallback,
+                                                     aTaskQueue, aProxy))
+  {
+  }
+
+  void Input(MediaRawData* aSample) override;
+  void Shutdown() override;
+
+private:
+  RefPtr<SamplesWaitingForKey> mSamplesWaitingForKey;
+};
+
+void
+RemoteEMEVideoDecoder::Input(MediaRawData* aSample)
+{
+  if (mSamplesWaitingForKey->WaitIfKeyNotUsable(aSample)) {
+    return;
+  }
+  RemoteVideoDecoder::Input(aSample);
+}
+
+void
+RemoteEMEVideoDecoder::Shutdown()
+{
+  RemoteVideoDecoder::Shutdown();
+
+  mSamplesWaitingForKey->BreakCycles();
+  mSamplesWaitingForKey = nullptr;
+}
+
+class RemoteAudioDecoder : public RemoteDataDecoder
 {
 public:
   RemoteAudioDecoder(const AudioInfo& aConfig,
                      MediaFormat::Param aFormat,
                      MediaDataDecoderCallback* aCallback,
                      const nsString& aDrmStubId)
     : RemoteDataDecoder(MediaData::Type::AUDIO_DATA, aConfig.mMimeType,
                         aFormat, aCallback, aDrmStubId)
@@ -441,33 +481,92 @@ private:
     RemoteAudioDecoder* mDecoder;
     int32_t mOutputChannels;
     int32_t mOutputSampleRate;
   };
 
   const AudioInfo& mConfig;
 };
 
+class RemoteEMEAudioDecoder : public RemoteAudioDecoder {
+public:
+  RemoteEMEAudioDecoder(const AudioInfo& aConfig, MediaFormat::Param aFormat,
+                        MediaDataDecoderCallback* aCallback, const nsString& aDrmStubId,
+                        CDMProxy* aProxy, TaskQueue* aTaskQueue)
+    : RemoteAudioDecoder(aConfig, aFormat, aCallback, aDrmStubId)
+    , mSamplesWaitingForKey(new SamplesWaitingForKey(this, aCallback,
+                                                     aTaskQueue, aProxy))
+  {
+  }
+
+  void Input(MediaRawData* aSample) override;
+  void Shutdown() override;
+
+private:
+  RefPtr<SamplesWaitingForKey> mSamplesWaitingForKey;
+};
+
+void
+RemoteEMEAudioDecoder::Input(MediaRawData* aSample)
+{
+  if (mSamplesWaitingForKey->WaitIfKeyNotUsable(aSample)) {
+    return;
+  }
+  RemoteAudioDecoder::Input(aSample);
+}
+
+void
+RemoteEMEAudioDecoder::Shutdown()
+{
+  RemoteAudioDecoder::Shutdown();
+
+  mSamplesWaitingForKey->BreakCycles();
+  mSamplesWaitingForKey = nullptr;
+}
+
 MediaDataDecoder*
 RemoteDataDecoder::CreateAudioDecoder(const AudioInfo& aConfig,
-                                          MediaFormat::Param aFormat,
-                                          MediaDataDecoderCallback* aCallback,
-                                          const nsString& aDrmStubId)
+                                      MediaFormat::Param aFormat,
+                                      MediaDataDecoderCallback* aCallback,
+                                      const nsString& aDrmStubId,
+                                      CDMProxy* aProxy,
+                                      TaskQueue* aTaskQueue)
 {
-  return new RemoteAudioDecoder(aConfig, aFormat, aCallback, aDrmStubId);
+  if (!aProxy) {
+    return new RemoteAudioDecoder(aConfig, aFormat, aCallback, aDrmStubId);
+  } else {
+    return new RemoteEMEAudioDecoder(aConfig,
+                                     aFormat,
+                                     aCallback,
+                                     aDrmStubId,
+                                     aProxy,
+                                     aTaskQueue);
+  }
 }
 
 MediaDataDecoder*
 RemoteDataDecoder::CreateVideoDecoder(const VideoInfo& aConfig,
-                                          MediaFormat::Param aFormat,
-                                          MediaDataDecoderCallback* aCallback,
-                                          layers::ImageContainer* aImageContainer,
-                                          const nsString& aDrmStubId)
+                                      MediaFormat::Param aFormat,
+                                      MediaDataDecoderCallback* aCallback,
+                                      layers::ImageContainer* aImageContainer,
+                                      const nsString& aDrmStubId,
+                                      CDMProxy* aProxy,
+                                      TaskQueue* aTaskQueue)
 {
-  return new RemoteVideoDecoder(aConfig, aFormat, aCallback, aImageContainer, aDrmStubId);
+  if (!aProxy) {
+    return new RemoteVideoDecoder(aConfig, aFormat, aCallback, aImageContainer, aDrmStubId);
+  } else {
+    return new RemoteEMEVideoDecoder(aConfig,
+                                     aFormat,
+                                     aCallback,
+                                     aImageContainer,
+                                     aDrmStubId,
+                                     aProxy,
+                                     aTaskQueue);
+  }
 }
 
 RemoteDataDecoder::RemoteDataDecoder(MediaData::Type aType,
                                      const nsACString& aMimeType,
                                      MediaFormat::Param aFormat,
                                      MediaDataDecoderCallback* aCallback,
                                      const nsString& aDrmStubId)
   : mType(aType)
--- a/dom/media/platforms/android/RemoteDataDecoder.h
+++ b/dom/media/platforms/android/RemoteDataDecoder.h
@@ -18,23 +18,27 @@
 
 namespace mozilla {
 
 class RemoteDataDecoder : public MediaDataDecoder {
 public:
   static MediaDataDecoder* CreateAudioDecoder(const AudioInfo& aConfig,
                                               java::sdk::MediaFormat::Param aFormat,
                                               MediaDataDecoderCallback* aCallback,
-                                              const nsString& aDrmStubId);
+                                              const nsString& aDrmStubId,
+                                              CDMProxy* aProxy,
+                                              TaskQueue* aTaskQueue);
 
   static MediaDataDecoder* CreateVideoDecoder(const VideoInfo& aConfig,
                                               java::sdk::MediaFormat::Param aFormat,
                                               MediaDataDecoderCallback* aCallback,
                                               layers::ImageContainer* aImageContainer,
-                                              const nsString& aDrmStubId);
+                                              const nsString& aDrmStubId,
+                                              CDMProxy* aProxy,
+                                              TaskQueue* aTaskQueue);
 
   virtual ~RemoteDataDecoder() {}
 
   void Flush() override;
   void Drain() override;
   void Shutdown() override;
   void Input(MediaRawData* aSample) override;
   const char* GetDescriptionName() const override