зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1147689 - Pass the session ID(s) of an encrypted frame into EME CDMs - r=cpearce
This commit is contained in:
Родитель
28e06d157a
Коммит
46cbfd3c6b
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -14,6 +14,7 @@ struct GMPDecryptionData {
|
|||
uint8_t[] mIV;
|
||||
uint16_t[] mClearBytes;
|
||||
uint32_t[] mCipherBytes;
|
||||
nsCString[] mSessionIds;
|
||||
};
|
||||
|
||||
struct GMPVideoEncodedFrameData
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче