Bug 1147689 - Pass the session ID(s) of an encrypted frame into EME CDMs - r=cpearce

This commit is contained in:
Edwin Flores 2015-03-26 22:57:36 +13:00
parent 28e06d157a
commit 46cbfd3c6b
11 changed files with 121 additions and 5 deletions

View File

@ -194,4 +194,15 @@ CDMCaps::AutoLock::GetKeyStatusesForSession(const nsAString& aSessionId,
}
}
void
CDMCaps::AutoLock::GetSessionIdsForKeyId(const CencKeyId& aKeyId,
nsTArray<nsCString>& aOutSessionIds)
{
for (const auto& keyStatus : mData.mKeyStatuses) {
if (keyStatus.mId == aKeyId) {
aOutSessionIds.AppendElement(NS_ConvertUTF16toUTF8(keyStatus.mSessionId));
}
}
}
} // namespace mozilla

View File

@ -68,6 +68,9 @@ public:
void GetKeyStatusesForSession(const nsAString& aSessionId,
nsTArray<KeyStatus>& aOutKeyStatuses);
void GetSessionIdsForKeyId(const CencKeyId& aKeyId,
nsTArray<nsCString>& aOutSessionIds);
// Sets the capabilities of the CDM. aCaps is the logical OR of the
// GMP_EME_CAP_* flags from gmp-decryption.h.
void SetCaps(uint64_t aCaps);

View File

@ -591,6 +591,14 @@ CDMProxy::gmp_Decrypted(uint32_t aId,
NS_WARNING("GMPDecryptorChild returned incorrect job ID");
}
void
CDMProxy::GetSessionIdsForKeyId(const nsTArray<uint8_t>& aKeyId,
nsTArray<nsCString>& aSessionIds)
{
CDMCaps::AutoLock caps(Capabilites());
caps.GetSessionIdsForKeyId(aKeyId, aSessionIds);
}
void
CDMProxy::Terminated()
{

View File

@ -166,6 +166,9 @@ public:
// Main thread only.
void OnKeyStatusesChange(const nsAString& aSessionId);
void GetSessionIdsForKeyId(const nsTArray<uint8_t>& aKeyId,
nsTArray<nsCString>& aSessionIds);
#ifdef DEBUG
bool IsOnGMPThread();
#endif

View File

@ -749,6 +749,18 @@ MP4Reader::Update(TrackType aTrack)
mFoundSPSForTelemetry = AccumulateSPSTelemetry(extradata);
}
if (sample && sample->mMp4Sample && sample->mMp4Sample->crypto.valid) {
CryptoSample& crypto = sample->mMp4Sample->crypto;
MOZ_ASSERT(crypto.session_ids.IsEmpty());
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
nsRefPtr<CDMProxy> proxy = mDecoder->GetCDMProxy();
MOZ_ASSERT(proxy);
proxy->GetSessionIdsForKeyId(crypto.key, crypto.session_ids);
}
if (sample) {
decoder.mDecoder->Input(sample->mMp4Sample.forget());
if (aTrack == kVideo) {

View File

@ -147,7 +147,8 @@ GMPDecryptorParent::Decrypt(uint32_t aId,
GMPDecryptionData data(aCrypto.key,
aCrypto.iv,
aCrypto.plain_sizes,
aCrypto.encrypted_sizes);
aCrypto.encrypted_sizes,
aCrypto.session_ids);
unused << SendDecrypt(aId, aBuffer, data);
}

View File

@ -14,15 +14,17 @@ GMPEncryptedBufferDataImpl::GMPEncryptedBufferDataImpl(const CryptoSample& aCryp
, mIV(aCrypto.iv)
, mClearBytes(aCrypto.plain_sizes)
, mCipherBytes(aCrypto.encrypted_sizes)
, mSessionIdList(aCrypto.session_ids)
{
}
GMPEncryptedBufferDataImpl::GMPEncryptedBufferDataImpl(const GMPDecryptionData& aData)
: mKeyId(aData.mKeyId())
, mIV(aData.mIV())
, mClearBytes(aData.mClearBytes())
, mCipherBytes(aData.mCipherBytes())
, mSessionIdList(aData.mSessionIds())
{
mKeyId = aData.mKeyId();
mIV = aData.mIV();
mClearBytes = aData.mClearBytes();
mCipherBytes = aData.mCipherBytes();
MOZ_ASSERT(mClearBytes.Length() == mCipherBytes.Length());
}
@ -37,6 +39,7 @@ GMPEncryptedBufferDataImpl::RelinquishData(GMPDecryptionData& aData)
aData.mIV() = Move(mIV);
aData.mClearBytes() = Move(mClearBytes);
aData.mCipherBytes() = Move(mCipherBytes);
mSessionIdList.RelinquishData(aData.mSessionIds());
}
const uint8_t*
@ -75,6 +78,12 @@ GMPEncryptedBufferDataImpl::CipherBytes() const
return mCipherBytes.Elements();
}
const GMPStringList*
GMPEncryptedBufferDataImpl::SessionIds() const
{
return &mSessionIdList;
}
uint32_t
GMPEncryptedBufferDataImpl::NumSubsamples() const
{
@ -84,5 +93,39 @@ GMPEncryptedBufferDataImpl::NumSubsamples() const
return std::min<uint32_t>(mClearBytes.Length(), mCipherBytes.Length());
}
GMPStringListImpl::GMPStringListImpl(const nsTArray<nsCString>& aStrings)
: mStrings(aStrings)
{
}
const uint32_t
GMPStringListImpl::Size() const
{
return mStrings.Length();
}
void
GMPStringListImpl::StringAt(uint32_t aIndex,
const char** aOutString,
uint32_t *aOutLength) const
{
if (NS_WARN_IF(aIndex >= Size())) {
return;
}
*aOutString = mStrings[aIndex].BeginReading();
*aOutLength = mStrings[aIndex].Length();
}
void
GMPStringListImpl::RelinquishData(nsTArray<nsCString>& aStrings)
{
aStrings = Move(mStrings);
}
GMPStringListImpl::~GMPStringListImpl()
{
}
} // namespace gmp
} // namespace mozilla

View File

@ -14,6 +14,20 @@
namespace mozilla {
namespace gmp {
class GMPStringListImpl : public GMPStringList
{
public:
GMPStringListImpl(const nsTArray<nsCString>& aStrings);
virtual const uint32_t Size() const override;
virtual void StringAt(uint32_t aIndex,
const char** aOutString, uint32_t *aOutLength) const override;
virtual ~GMPStringListImpl() override;
void RelinquishData(nsTArray<nsCString>& aStrings);
private:
nsTArray<nsCString> mStrings;
};
class GMPEncryptedBufferDataImpl : public GMPEncryptedBufferMetadata {
private:
typedef mp4_demuxer::CryptoSample CryptoSample;
@ -31,12 +45,15 @@ public:
virtual uint32_t NumSubsamples() const override;
virtual const uint16_t* ClearBytes() const override;
virtual const uint32_t* CipherBytes() const override;
virtual const GMPStringList* SessionIds() const override;
private:
nsTArray<uint8_t> mKeyId;
nsTArray<uint8_t> mIV;
nsTArray<uint16_t> mClearBytes;
nsTArray<uint32_t> mCipherBytes;
GMPStringListImpl mSessionIdList;
};
class GMPBufferImpl : public GMPBuffer {

View File

@ -14,6 +14,7 @@ struct GMPDecryptionData {
uint8_t[] mIV;
uint16_t[] mClearBytes;
uint32_t[] mCipherBytes;
nsCString[] mSessionIds;
};
struct GMPVideoEncodedFrameData

View File

@ -19,6 +19,16 @@
#include "gmp-platform.h"
class GMPStringList {
public:
virtual const uint32_t Size() const = 0;
virtual void StringAt(uint32_t aIndex,
const char** aOutString, uint32_t* aOutLength) const = 0;
virtual ~GMPStringList() { }
};
class GMPEncryptedBufferMetadata {
public:
// Key ID to identify the decryption key.
@ -41,6 +51,10 @@ public:
virtual const uint32_t* CipherBytes() const = 0;
virtual ~GMPEncryptedBufferMetadata() {}
// The set of MediaKeySession IDs associated with this decryption key in
// the current stream.
virtual const GMPStringList* SessionIds() const = 0;
};
class GMPBuffer {

View File

@ -11,6 +11,7 @@
#include "nsRefPtr.h"
#include "nsString.h"
#include "nsTArray.h"
#include "nsString.h"
namespace stagefright
{
@ -83,6 +84,8 @@ public:
nsTArray<uint16_t> plain_sizes;
nsTArray<uint32_t> encrypted_sizes;
nsTArray<uint8_t> iv;
nsTArray<nsCString> session_ids;
};
class TrackConfig