Bug 1306314 - Pass decryptor ID to GMPVideoDecoder constructor. r=gerald
authorChris Pearce <cpearce@mozilla.com>
Mon, 14 Nov 2016 11:07:02 +1300
changeset 322390 893b62158c45c65fdb5702866b2c0a6ff5a33cf7
parent 322389 2b0c612e87232b099830ae3b918d2080cc73960c
child 322391 e183a3804fbbb6f25228daacf9cf217548ff0129
push id30951
push usercbook@mozilla.com
push dateTue, 15 Nov 2016 11:25:40 +0000
treeherdermozilla-central@85a9d908e91a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald
bugs1306314
milestone52.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 1306314 - Pass decryptor ID to GMPVideoDecoder constructor. r=gerald Retrieve the ID of the GMPDecryptor from the GMPCDMProxy, and pass that through to the GMPVideoDecoder's constructor. MozReview-Commit-ID: IuNsSroZ9Zu
dom/media/gmp/GMPContentChild.cpp
dom/media/gmp/GMPContentChild.h
dom/media/gmp/GMPContentParent.cpp
dom/media/gmp/GMPContentParent.h
dom/media/gmp/GMPService.cpp
dom/media/gmp/GMPService.h
dom/media/gmp/PGMPContent.ipdl
dom/media/gmp/mozIGeckoMediaPluginService.idl
dom/media/platforms/agnostic/eme/EMEVideoDecoder.cpp
dom/media/platforms/agnostic/eme/EMEVideoDecoder.h
dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp
dom/media/platforms/agnostic/gmp/GMPVideoDecoder.h
--- a/dom/media/gmp/GMPContentChild.cpp
+++ b/dom/media/gmp/GMPContentChild.cpp
@@ -75,17 +75,17 @@ GMPContentChild::AllocPGMPDecryptorChild
 bool
 GMPContentChild::DeallocPGMPDecryptorChild(PGMPDecryptorChild* aActor)
 {
   static_cast<GMPDecryptorChild*>(aActor)->Release();
   return true;
 }
 
 PGMPVideoDecoderChild*
-GMPContentChild::AllocPGMPVideoDecoderChild()
+GMPContentChild::AllocPGMPVideoDecoderChild(const uint32_t& aDecryptorId)
 {
   GMPVideoDecoderChild* actor = new GMPVideoDecoderChild(this);
   actor->AddRef();
   return actor;
 }
 
 bool
 GMPContentChild::DeallocPGMPVideoDecoderChild(PGMPVideoDecoderChild* aActor)
@@ -239,17 +239,18 @@ GMPContentChild::RecvPGMPAudioDecoderCon
   }
 
   vdc->Init(static_cast<GMPAudioDecoder*>(vd));
 
   return true;
 }
 
 bool
-GMPContentChild::RecvPGMPVideoDecoderConstructor(PGMPVideoDecoderChild* aActor)
+GMPContentChild::RecvPGMPVideoDecoderConstructor(PGMPVideoDecoderChild* aActor,
+                                                 const uint32_t& aDecryptorId)
 {
   auto vdc = static_cast<GMPVideoDecoderChild*>(aActor);
 
   void* vd = nullptr;
   GMPErr err = mGMPChild->GetAPI(GMP_API_VIDEO_DECODER, &vdc->Host(), &vd);
   if (err != GMPNoErr || !vd) {
     NS_WARNING("GMPGetAPI call failed trying to construct decoder.");
     return false;
--- a/dom/media/gmp/GMPContentChild.h
+++ b/dom/media/gmp/GMPContentChild.h
@@ -20,26 +20,26 @@ class GMPContentChild : public PGMPConte
 public:
   explicit GMPContentChild(GMPChild* aChild);
   virtual ~GMPContentChild();
 
   MessageLoop* GMPMessageLoop();
 
   bool RecvPGMPAudioDecoderConstructor(PGMPAudioDecoderChild* aActor) override;
   bool RecvPGMPDecryptorConstructor(PGMPDecryptorChild* aActor) override;
-  bool RecvPGMPVideoDecoderConstructor(PGMPVideoDecoderChild* aActor) override;
+  bool RecvPGMPVideoDecoderConstructor(PGMPVideoDecoderChild* aActor, const uint32_t& aDecryptorId) override;
   bool RecvPGMPVideoEncoderConstructor(PGMPVideoEncoderChild* aActor) override;
 
   PGMPAudioDecoderChild* AllocPGMPAudioDecoderChild() override;
   bool DeallocPGMPAudioDecoderChild(PGMPAudioDecoderChild* aActor) override;
 
   PGMPDecryptorChild* AllocPGMPDecryptorChild() override;
   bool DeallocPGMPDecryptorChild(PGMPDecryptorChild* aActor) override;
 
-  PGMPVideoDecoderChild* AllocPGMPVideoDecoderChild() override;
+  PGMPVideoDecoderChild* AllocPGMPVideoDecoderChild(const uint32_t& aDecryptorId) override;
   bool DeallocPGMPVideoDecoderChild(PGMPVideoDecoderChild* aActor) override;
 
   PGMPVideoEncoderChild* AllocPGMPVideoEncoderChild() override;
   bool DeallocPGMPVideoEncoderChild(PGMPVideoEncoderChild* aActor) override;
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
   void ProcessingError(Result aCode, const char* aReason) override;
 
--- a/dom/media/gmp/GMPContentParent.cpp
+++ b/dom/media/gmp/GMPContentParent.cpp
@@ -189,20 +189,21 @@ GMPContentParent::GetGMPAudioDecoder(GMP
   NS_ADDREF(vap);
   *aGMPAD = vap;
   mAudioDecoders.AppendElement(vap);
 
   return NS_OK;
 }
 
 nsresult
-GMPContentParent::GetGMPVideoDecoder(GMPVideoDecoderParent** aGMPVD)
+GMPContentParent::GetGMPVideoDecoder(GMPVideoDecoderParent** aGMPVD,
+                                     uint32_t aDecryptorId)
 {
   // returned with one anonymous AddRef that locks it until Destroy
-  PGMPVideoDecoderParent* pvdp = SendPGMPVideoDecoderConstructor();
+  PGMPVideoDecoderParent* pvdp = SendPGMPVideoDecoderConstructor(aDecryptorId);
   if (!pvdp) {
     return NS_ERROR_FAILURE;
   }
   GMPVideoDecoderParent *vdp = static_cast<GMPVideoDecoderParent*>(pvdp);
   // This addref corresponds to the Proxy pointer the consumer is returned.
   // It's dropped by calling Close() on the interface.
   NS_ADDREF(vdp);
   *aGMPVD = vdp;
@@ -225,17 +226,17 @@ GMPContentParent::GetGMPVideoEncoder(GMP
   NS_ADDREF(vep);
   *aGMPVE = vep;
   mVideoEncoders.AppendElement(vep);
 
   return NS_OK;
 }
 
 PGMPVideoDecoderParent*
-GMPContentParent::AllocPGMPVideoDecoderParent()
+GMPContentParent::AllocPGMPVideoDecoderParent(const uint32_t& aDecryptorId)
 {
   GMPVideoDecoderParent* vdp = new GMPVideoDecoderParent(this);
   NS_ADDREF(vdp);
   return vdp;
 }
 
 bool
 GMPContentParent::DeallocPGMPVideoDecoderParent(PGMPVideoDecoderParent* aActor)
--- a/dom/media/gmp/GMPContentParent.h
+++ b/dom/media/gmp/GMPContentParent.h
@@ -22,17 +22,18 @@ class GMPVideoEncoderParent;
 class GMPContentParent final : public PGMPContentParent,
                                public GMPSharedMem
 {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPContentParent)
 
   explicit GMPContentParent(GMPParent* aParent = nullptr);
 
-  nsresult GetGMPVideoDecoder(GMPVideoDecoderParent** aGMPVD);
+  nsresult GetGMPVideoDecoder(GMPVideoDecoderParent** aGMPVD,
+                              uint32_t aDecryptorId);
   void VideoDecoderDestroyed(GMPVideoDecoderParent* aDecoder);
 
   nsresult GetGMPVideoEncoder(GMPVideoEncoderParent** aGMPVE);
   void VideoEncoderDestroyed(GMPVideoEncoderParent* aEncoder);
 
   nsresult GetGMPDecryptor(GMPDecryptorParent** aGMPKS);
   void DecryptorDestroyed(GMPDecryptorParent* aSession);
 
@@ -61,17 +62,17 @@ public:
     return mPluginId;
   }
 
 private:
   ~GMPContentParent();
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
-  PGMPVideoDecoderParent* AllocPGMPVideoDecoderParent() override;
+  PGMPVideoDecoderParent* AllocPGMPVideoDecoderParent(const uint32_t& aDecryptorId) override;
   bool DeallocPGMPVideoDecoderParent(PGMPVideoDecoderParent* aActor) override;
 
   PGMPVideoEncoderParent* AllocPGMPVideoEncoderParent() override;
   bool DeallocPGMPVideoEncoderParent(PGMPVideoEncoderParent* aActor) override;
 
   PGMPDecryptorParent* AllocPGMPDecryptorParent() override;
   bool DeallocPGMPDecryptorParent(PGMPDecryptorParent* aActor) override;
 
--- a/dom/media/gmp/GMPService.cpp
+++ b/dom/media/gmp/GMPService.cpp
@@ -344,54 +344,58 @@ GeckoMediaPluginService::GetGMPAudioDeco
 
   return NS_OK;
 }
 
 class GetGMPContentParentForVideoDecoderDone : public GetGMPContentParentCallback
 {
 public:
   explicit GetGMPContentParentForVideoDecoderDone(UniquePtr<GetGMPVideoDecoderCallback>&& aCallback,
-                                                  GMPCrashHelper* aHelper)
+                                                  GMPCrashHelper* aHelper,
+                                                  uint32_t aDecryptorId)
    : mCallback(Move(aCallback))
    , mHelper(aHelper)
+   , mDecryptorId(aDecryptorId)
   {
   }
 
   void Done(GMPContentParent* aGMPParent) override
   {
     GMPVideoDecoderParent* gmpVDP = nullptr;
     GMPVideoHostImpl* videoHost = nullptr;
-    if (aGMPParent && NS_SUCCEEDED(aGMPParent->GetGMPVideoDecoder(&gmpVDP))) {
+    if (aGMPParent && NS_SUCCEEDED(aGMPParent->GetGMPVideoDecoder(&gmpVDP, mDecryptorId))) {
       videoHost = &gmpVDP->Host();
       gmpVDP->SetCrashHelper(mHelper);
     }
     mCallback->Done(gmpVDP, videoHost);
   }
 
 private:
   UniquePtr<GetGMPVideoDecoderCallback> mCallback;
   RefPtr<GMPCrashHelper> mHelper;
+  const uint32_t mDecryptorId;
 };
 
 NS_IMETHODIMP
-GeckoMediaPluginService::GetGMPVideoDecoder(GMPCrashHelper* aHelper,
-                                            nsTArray<nsCString>* aTags,
-                                            const nsACString& aNodeId,
-                                            UniquePtr<GetGMPVideoDecoderCallback>&& aCallback)
+GeckoMediaPluginService::GetDecryptingGMPVideoDecoder(GMPCrashHelper* aHelper,
+                                                      nsTArray<nsCString>* aTags,
+                                                      const nsACString& aNodeId,
+                                                      UniquePtr<GetGMPVideoDecoderCallback>&& aCallback,
+                                                      uint32_t aDecryptorId)
 {
   MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
   NS_ENSURE_ARG(aTags && aTags->Length() > 0);
   NS_ENSURE_ARG(aCallback);
 
   if (mShuttingDownOnGMPThread) {
     return NS_ERROR_FAILURE;
   }
 
   UniquePtr<GetGMPContentParentCallback> callback(
-    new GetGMPContentParentForVideoDecoderDone(Move(aCallback), aHelper));
+    new GetGMPContentParentForVideoDecoderDone(Move(aCallback), aHelper, aDecryptorId));
   if (!GetContentParentFrom(aHelper,
                             aNodeId,
                             NS_LITERAL_CSTRING(GMP_API_VIDEO_DECODER),
                             *aTags,
                             Move(callback))) {
     return NS_ERROR_FAILURE;
   }
 
--- a/dom/media/gmp/GMPService.h
+++ b/dom/media/gmp/GMPService.h
@@ -64,20 +64,21 @@ public:
   static already_AddRefed<GeckoMediaPluginService> GetGeckoMediaPluginService();
 
   virtual nsresult Init();
 
   NS_DECL_THREADSAFE_ISUPPORTS
 
   // mozIGeckoMediaPluginService
   NS_IMETHOD GetThread(nsIThread** aThread) override;
-  NS_IMETHOD GetGMPVideoDecoder(GMPCrashHelper* aHelper,
-                                nsTArray<nsCString>* aTags,
-                                const nsACString& aNodeId,
-                                UniquePtr<GetGMPVideoDecoderCallback>&& aCallback)
+  NS_IMETHOD GetDecryptingGMPVideoDecoder(GMPCrashHelper* aHelper,
+                                          nsTArray<nsCString>* aTags,
+                                          const nsACString& aNodeId,
+                                          UniquePtr<GetGMPVideoDecoderCallback>&& aCallback,
+                                          uint32_t aDecryptorId)
     override;
   NS_IMETHOD GetGMPVideoEncoder(GMPCrashHelper* aHelper,
                                 nsTArray<nsCString>* aTags,
                                 const nsACString& aNodeId,
                                 UniquePtr<GetGMPVideoEncoderCallback>&& aCallback)
     override;
   NS_IMETHOD GetGMPAudioDecoder(GMPCrashHelper* aHelper,
                                 nsTArray<nsCString>* aTags,
@@ -85,16 +86,26 @@ public:
                                 UniquePtr<GetGMPAudioDecoderCallback>&& aCallback)
     override;
   NS_IMETHOD GetGMPDecryptor(GMPCrashHelper* aHelper,
                              nsTArray<nsCString>* aTags,
                              const nsACString& aNodeId,
                              UniquePtr<GetGMPDecryptorCallback>&& aCallback)
     override;
 
+  // Helper for backwards compatibility with WebRTC/tests.
+  NS_IMETHOD
+  GetGMPVideoDecoder(GMPCrashHelper* aHelper,
+                     nsTArray<nsCString>* aTags,
+                     const nsACString& aNodeId,
+                     UniquePtr<GetGMPVideoDecoderCallback>&& aCallback) override
+  {
+    return GetDecryptingGMPVideoDecoder(aHelper, aTags, aNodeId, Move(aCallback), 0);
+  }
+
   int32_t AsyncShutdownTimeoutMs();
 
   NS_IMETHOD RunPluginCrashCallbacks(uint32_t aPluginId,
                                      const nsACString& aPluginName) override;
 
   RefPtr<AbstractThread> GetAbstractGMPThread();
 
   void ConnectCrashHelper(uint32_t aPluginId, GMPCrashHelper* aHelper);
--- a/dom/media/gmp/PGMPContent.ipdl
+++ b/dom/media/gmp/PGMPContent.ipdl
@@ -20,14 +20,14 @@ intr protocol PGMPContent
   manages PGMPAudioDecoder;
   manages PGMPDecryptor;
   manages PGMPVideoDecoder;
   manages PGMPVideoEncoder;
 
 child:
   async PGMPAudioDecoder();
   async PGMPDecryptor();
-  async PGMPVideoDecoder();
+  async PGMPVideoDecoder(uint32_t aDecryptorId);
   async PGMPVideoEncoder();
 };
 
 } // namespace gmp
 } // namespace mozilla
--- a/dom/media/gmp/mozIGeckoMediaPluginService.idl
+++ b/dom/media/gmp/mozIGeckoMediaPluginService.idl
@@ -89,16 +89,29 @@ interface mozIGeckoMediaPluginService : 
    */
   [noscript]
   void getGMPVideoDecoder(in GMPCrashHelperPtr helper,
                           in TagArray tags,
                           [optional] in ACString nodeId,
                           in GetGMPVideoDecoderCallback callback);
 
   /**
+   * Gets a video decoder as per getGMPVideoDecoder, except it is linked to
+   * with a corresponding GMPDecryptor via the decryptor's ID.
+   * This is a temporary measure, until we can implement a Chromium CDM
+   * GMP protocol which does both decryption and decoding.
+   */
+  [noscript]
+  void getDecryptingGMPVideoDecoder(in GMPCrashHelperPtr helper,
+                                    in TagArray tags,
+                                    in ACString nodeId,
+                                    in GetGMPVideoDecoderCallback callback,
+                                    in uint32_t decryptorId);
+
+  /**
    * Get a video encoder that supports the specified tags.
    * The array of tags should at least contain a codec tag, and optionally
    * other tags.
    * Callable only on GMP thread.
    * This is an asynchronous operation, the Done method of the callback object
    * will be called on the GMP thread with the result (which might be null in
    * the case of failure). This method always takes ownership of the callback
    * object, but if this method returns an error then the Done method of the
--- a/dom/media/platforms/agnostic/eme/EMEVideoDecoder.cpp
+++ b/dom/media/platforms/agnostic/eme/EMEVideoDecoder.cpp
@@ -27,16 +27,17 @@ EMEVideoCallbackAdapter::Error(GMPErr aE
 
 EMEVideoDecoder::EMEVideoDecoder(CDMProxy* aProxy,
                                  const GMPVideoDecoderParams& aParams)
   : GMPVideoDecoder(GMPVideoDecoderParams(aParams).WithAdapter(
                     new EMEVideoCallbackAdapter(aParams.mCallback,
                                                 VideoInfo(aParams.mConfig.mDisplay),
                                                 aParams.mImageContainer)))
   , mProxy(aProxy)
+  , mDecryptorId(aProxy->GetDecryptorId())
 {}
 
 void
 EMEVideoDecoder::InitTags(nsTArray<nsCString>& aTags)
 {
   VideoInfo config = GetConfig();
   if (MP4Decoder::IsH264(config.mMimeType)) {
     aTags.AppendElement(NS_LITERAL_CSTRING("h264"));
--- a/dom/media/platforms/agnostic/eme/EMEVideoDecoder.h
+++ b/dom/media/platforms/agnostic/eme/EMEVideoDecoder.h
@@ -28,16 +28,18 @@ public:
 
 class EMEVideoDecoder : public GMPVideoDecoder {
 public:
   EMEVideoDecoder(CDMProxy* aProxy, const GMPVideoDecoderParams& aParams);
 
 private:
   void InitTags(nsTArray<nsCString>& aTags) override;
   nsCString GetNodeId() override;
+  uint32_t DecryptorId() const override { return mDecryptorId; }
   GMPUniquePtr<GMPVideoEncodedFrame> CreateFrame(MediaRawData* aSample) override;
 
   RefPtr<CDMProxy> mProxy;
+  uint32_t mDecryptorId;
 };
 
 } // namespace mozilla
 
 #endif // EMEVideoDecoder_h_
--- a/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp
+++ b/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp
@@ -306,17 +306,21 @@ GMPVideoDecoder::Init()
   mMPS = do_GetService("@mozilla.org/gecko-media-plugin-service;1");
   MOZ_ASSERT(mMPS);
 
   RefPtr<InitPromise> promise(mInitPromise.Ensure(__func__));
 
   nsTArray<nsCString> tags;
   InitTags(tags);
   UniquePtr<GetGMPVideoDecoderCallback> callback(new GMPInitDoneCallback(this));
-  if (NS_FAILED(mMPS->GetGMPVideoDecoder(mCrashHelper, &tags, GetNodeId(), Move(callback)))) {
+  if (NS_FAILED(mMPS->GetDecryptingGMPVideoDecoder(mCrashHelper,
+                                                   &tags,
+                                                   GetNodeId(),
+                                                   Move(callback),
+                                                   DecryptorId()))) {
     mInitPromise.Reject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
   }
 
   return promise;
 }
 
 void
 GMPVideoDecoder::Input(MediaRawData* aSample)
--- a/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.h
+++ b/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.h
@@ -77,16 +77,17 @@ public:
   const char* GetDescriptionName() const override
   {
     return "GMP video decoder";
   }
 
 protected:
   virtual void InitTags(nsTArray<nsCString>& aTags);
   virtual nsCString GetNodeId();
+  virtual uint32_t DecryptorId() const { return 0; }
   virtual GMPUniquePtr<GMPVideoEncodedFrame> CreateFrame(MediaRawData* aSample);
   virtual const VideoInfo& GetConfig() const;
 
 private:
 
   class GMPInitDoneCallback : public GetGMPVideoDecoderCallback
   {
   public: