From fb5a8a3e0d4b4c3f6ad7717a9cd711ecf2e51809 Mon Sep 17 00:00:00 2001 From: Chris Pearce Date: Mon, 27 Mar 2017 13:19:38 +1300 Subject: [PATCH] Bug 1351953 - Send Data to CDM for decrypt and or decode in shmems. r=gerald MozReview-Commit-ID: 2UdGimoOLKr --HG-- extra : rebase_source : 04879d8c1639bf6f14cebc6031d8cc23e05e567a --- dom/media/gmp/ChromiumCDMChild.cpp | 16 +++++++++++++--- dom/media/gmp/ChromiumCDMParent.cpp | 15 ++++++++++----- dom/media/gmp/ChromiumCDMParent.h | 2 ++ dom/media/gmp/GMPTypes.ipdlh | 2 +- dom/media/gmp/PChromiumCDM.ipdl | 2 +- 5 files changed, 27 insertions(+), 10 deletions(-) diff --git a/dom/media/gmp/ChromiumCDMChild.cpp b/dom/media/gmp/ChromiumCDMChild.cpp index 7cf9fdda78b2..dea5169b4856 100644 --- a/dom/media/gmp/ChromiumCDMChild.cpp +++ b/dom/media/gmp/ChromiumCDMChild.cpp @@ -14,6 +14,7 @@ #include "nsPrintfCString.h" #include "base/time.h" #include "GMPUtils.h" +#include "mozilla/ScopeExit.h" namespace mozilla { namespace gmp { @@ -388,8 +389,8 @@ InitInputBuffer(const CDMInputBuffer& aBuffer, nsTArray& aSubSamples, cdm::InputBuffer& aInputBuffer) { - aInputBuffer.data = aBuffer.mData().Elements(); - aInputBuffer.data_size = aBuffer.mData().Length(); + aInputBuffer.data = aBuffer.mData().get(); + aInputBuffer.data_size = aBuffer.mData().Size(); if (aBuffer.mIsEncrypted()) { aInputBuffer.key_id = aBuffer.mKeyId().Elements(); @@ -415,6 +416,11 @@ ChromiumCDMChild::RecvDecrypt(const uint32_t& aId, { MOZ_ASSERT(IsOnMessageLoopThread()); GMP_LOG("ChromiumCDMChild::RecvDecrypt()"); + + auto autoDeallocateShmem = MakeScopeExit([&,this] { + this->DeallocShmem(aBuffer.mData()); + }); + if (!mCDM) { GMP_LOG("ChromiumCDMChild::RecvDecrypt() no CDM"); DecryptFailed(aId, cdm::kDecryptError); @@ -440,7 +446,7 @@ ChromiumCDMChild::RecvDecrypt(const uint32_t& aId, } if (!output.DecryptedBuffer() || - output.DecryptedBuffer()->Size() != aBuffer.mData().Length()) { + output.DecryptedBuffer()->Size() != aBuffer.mData().Size()) { // The sizes of the input and output should exactly match. DecryptFailed(aId, cdm::kDecryptError); return IPC_OK(); @@ -510,6 +516,10 @@ ChromiumCDMChild::RecvDecryptAndDecodeFrame(const CDMInputBuffer& aBuffer) aBuffer.mTimestamp()); MOZ_ASSERT(mDecoderInitialized); + auto autoDeallocateShmem = MakeScopeExit([&, this] { + this->DeallocShmem(aBuffer.mData()); + }); + // The output frame may not have the same timestamp as the frame we put in. // We may need to input a number of frames before we receive output. The // CDM's decoder reorders to ensure frames output are in presentation order. diff --git a/dom/media/gmp/ChromiumCDMParent.cpp b/dom/media/gmp/ChromiumCDMParent.cpp index 6cfdd8fe3abc..c2593209c7f7 100644 --- a/dom/media/gmp/ChromiumCDMParent.cpp +++ b/dom/media/gmp/ChromiumCDMParent.cpp @@ -169,8 +169,8 @@ ChromiumCDMParent::RemoveSession(const nsCString& aSessionId, } } -static bool -InitCDMInputBuffer(gmp::CDMInputBuffer& aBuffer, MediaRawData* aSample) +bool +ChromiumCDMParent::InitCDMInputBuffer(gmp::CDMInputBuffer& aBuffer, MediaRawData* aSample) { const CryptoSample& crypto = aSample->mCrypto; if (crypto.mEncryptedSizes.Length() != crypto.mPlainSizes.Length()) { @@ -178,10 +178,13 @@ InitCDMInputBuffer(gmp::CDMInputBuffer& aBuffer, MediaRawData* aSample) return false; } - nsTArray data; - data.AppendElements(aSample->Data(), aSample->Size()); + Shmem shmem; + if (!AllocShmem(aSample->Size(), Shmem::SharedMemory::TYPE_BASIC, &shmem)) { + return false; + } + memcpy(shmem.get(), aSample->Data(), aSample->Size()); - aBuffer = gmp::CDMInputBuffer(data, + aBuffer = gmp::CDMInputBuffer(shmem, crypto.mKeyId, crypto.mIV, aSample->mTime, @@ -209,6 +212,7 @@ ChromiumCDMParent::Decrypt(MediaRawData* aSample) GMP_LOG( "ChromiumCDMParent::Decrypt(this=%p) failed to send decrypt message", this); + DeallocShmem(buffer.mData()); return DecryptPromise::CreateAndReject(DecryptResult(GenericErr, aSample), __func__); } @@ -721,6 +725,7 @@ ChromiumCDMParent::DecryptAndDecodeFrame(MediaRawData* aSample) GMP_LOG( "ChromiumCDMParent::Decrypt(this=%p) failed to send decrypt message.", this); + DeallocShmem(buffer.mData()); return MediaDataDecoder::DecodePromise::CreateAndReject( MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, "Failed to send decrypt to CDM process."), diff --git a/dom/media/gmp/ChromiumCDMParent.h b/dom/media/gmp/ChromiumCDMParent.h index bf1eb754b531..9760c7f0380f 100644 --- a/dom/media/gmp/ChromiumCDMParent.h +++ b/dom/media/gmp/ChromiumCDMParent.h @@ -127,6 +127,8 @@ protected: void ResolvePromise(uint32_t aPromiseId); + bool InitCDMInputBuffer(gmp::CDMInputBuffer& aBuffer, MediaRawData* aSample); + const uint32_t mPluginId; GMPContentParent* mContentParent; // Note: this pointer is a weak reference because otherwise it would cause diff --git a/dom/media/gmp/GMPTypes.ipdlh b/dom/media/gmp/GMPTypes.ipdlh index e3a4ae583618..0bbc98ce70fe 100644 --- a/dom/media/gmp/GMPTypes.ipdlh +++ b/dom/media/gmp/GMPTypes.ipdlh @@ -61,7 +61,7 @@ struct GMPKeyInformation { }; struct CDMInputBuffer { - uint8_t[] mData; + Shmem mData; uint8_t[] mKeyId; uint8_t[] mIV; int64_t mTimestamp; diff --git a/dom/media/gmp/PChromiumCDM.ipdl b/dom/media/gmp/PChromiumCDM.ipdl index 1f7bb87dd3b1..69d115f0f3e5 100644 --- a/dom/media/gmp/PChromiumCDM.ipdl +++ b/dom/media/gmp/PChromiumCDM.ipdl @@ -87,7 +87,7 @@ parent: async ResolveLoadSessionPromise(uint32_t aPromiseId, bool aSuccessful); // Return values of cdm::ContentDecryptionModule8::Decrypt - async Decrypted(uint32_t aId, uint32_t aStatus, uint8_t[] aData); + async Decrypted(uint32_t aId, uint32_t aStatus, Shmem aData); async OnDecoderInitDone(uint32_t aStatus);