Bug 1144409 - Encrypted event should be fired once per initData; part 2: future initData. r=cpearce

This commit is contained in:
Gerald Squelart 2015-03-22 23:27:00 -04:00
parent 0693105064
commit 4c1646cd0f
6 changed files with 55 additions and 9 deletions

View File

@ -686,6 +686,8 @@ void HTMLMediaElement::AbortExistingLoads()
mSuspendedForPreloadNone = false;
mDownloadSuspendedByCache = false;
mMediaInfo = MediaInfo();
mIsEncrypted = false;
mPendingEncryptedInitData.mInitDatas.Clear();
mSourcePointer = nullptr;
mLastNextFrameStatus = NEXT_FRAME_UNINITIALIZED;
@ -3066,7 +3068,7 @@ void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo,
nsAutoPtr<const MetadataTags> aTags)
{
mMediaInfo = *aInfo;
mIsEncrypted = aInfo->IsEncrypted();
mIsEncrypted = aInfo->IsEncrypted() | mPendingEncryptedInitData.IsEncrypted();
mTags = aTags.forget();
mLoadedDataFired = false;
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
@ -3094,9 +3096,10 @@ void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo,
#ifdef MOZ_EME
// Dispatch a distinct 'encrypted' event for each initData we have.
for (const auto& initData : aInfo->mCrypto.mInitDatas) {
for (const auto& initData : mPendingEncryptedInitData.mInitDatas) {
DispatchEncrypted(initData.mInitData, initData.mType);
}
mPendingEncryptedInitData.mInitDatas.Clear();
#endif
}
@ -4458,6 +4461,13 @@ void
HTMLMediaElement::DispatchEncrypted(const nsTArray<uint8_t>& aInitData,
const nsAString& aInitDataType)
{
if (mReadyState == nsIDOMHTMLMediaElement::HAVE_NOTHING) {
// Ready state not HAVE_METADATA (yet), don't dispatch encrypted now.
// Queueing for later dispatch in MetadataLoaded.
mPendingEncryptedInitData.AddInitData(aInitDataType, aInitData);
return;
}
nsRefPtr<MediaEncryptedEvent> event;
if (IsCORSSameOrigin()) {
event = MediaEncryptedEvent::Constructor(this, aInitDataType, aInitData);

View File

@ -1316,6 +1316,9 @@ protected:
// True if the media has encryption information.
bool mIsEncrypted;
// Init Data that needs to be sent in 'encrypted' events in MetadataLoaded().
EncryptionInfo mPendingEncryptedInitData;
// True if the media's channel's download has been suspended.
bool mDownloadSuspendedByCache;

View File

@ -136,7 +136,7 @@ public:
#ifdef MOZ_EME
// Dispatches a "encrypted" event to the HTMLMediaElement, with the
// provided init data.
// provided init data. Actual dispatch may be delayed until HAVE_METADATA.
// Main thread only.
virtual void DispatchEncrypted(const nsTArray<uint8_t>& aInitData,
const nsAString& aInitDataType) = 0;

View File

@ -106,9 +106,10 @@ public:
class EncryptionInfo {
public:
struct InitData {
InitData(const nsString& aType, nsTArray<uint8_t>&& aInitData)
template<typename AInitDatas>
InitData(const nsAString& aType, AInitDatas&& aInitData)
: mType(aType)
, mInitData(Move(aInitData))
, mInitData(Forward<AInitDatas>(aInitData))
{
}
@ -126,9 +127,10 @@ public:
return !mInitDatas.IsEmpty();
}
void AddInitData(const nsString& aType, nsTArray<uint8_t>&& aInitData)
template<typename AInitDatas>
void AddInitData(const nsAString& aType, AInitDatas&& aInitData)
{
mInitDatas.AppendElement(InitData(aType, Move(aInitData)));
mInitDatas.AppendElement(InitData(aType, Forward<AInitDatas>(aInitData)));
}
void AddInitData(const EncryptionInfo& aInfo)

View File

@ -264,6 +264,34 @@ MP4Reader::Init(MediaDecoderReader* aCloneDonor)
return NS_OK;
}
#ifdef MOZ_EME
class DispatchKeyNeededEvent : public nsRunnable {
public:
DispatchKeyNeededEvent(AbstractMediaDecoder* aDecoder,
nsTArray<uint8_t>& aInitData,
const nsString& aInitDataType)
: mDecoder(aDecoder)
, mInitData(aInitData)
, mInitDataType(aInitDataType)
{
}
NS_IMETHOD Run() {
// Note: Null check the owner, as the decoder could have been shutdown
// since this event was dispatched.
MediaDecoderOwner* owner = mDecoder->GetOwner();
if (owner) {
owner->DispatchEncrypted(mInitData, mInitDataType);
}
mDecoder = nullptr;
return NS_OK;
}
private:
nsRefPtr<AbstractMediaDecoder> mDecoder;
nsTArray<uint8_t> mInitData;
nsString mInitDataType;
};
#endif
void MP4Reader::RequestCodecResource() {
if (mVideo.mDecoder) {
mVideo.mDecoder->AllocateMediaResources();
@ -407,6 +435,11 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo,
return NS_ERROR_FAILURE;
}
// Try and dispatch 'encrypted'. Won't go if ready state still HAVE_NOTHING.
NS_DispatchToMainThread(
new DispatchKeyNeededEvent(mDecoder, initData, NS_LITERAL_STRING("cenc")));
// Add init data to info, will get sent from HTMLMediaElement::MetadataLoaded
// (i.e., when transitioning from HAVE_NOTHING to HAVE_METADATA).
mInfo.mCrypto.AddInitData(NS_LITERAL_STRING("cenc"), Move(initData));
}

View File

@ -275,8 +275,6 @@ private:
layers::LayersBackend mLayersBackendType;
nsTArray<nsTArray<uint8_t>> mInitDataEncountered;
// True if we've read the streams' metadata.
bool mDemuxerInitialized;