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
--- 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: