Bug 1454630 - P2. Use new PDMFactory whenever encryption type change. r=bryce,cpearce

If the content being played was first non-encrypted, the PDMFactory would have been set without a CDMProxy. As such, it is necessary to use a new PDMFactory when the encryption type changes (from clear to encrypted).

Rather than attempting to detect if the encryption status has changed, simply use two PDMFactory, one with CDMProxy set and one without (for clear content)

Also, never attempt to recycle a decoder if the encryption type changed (used only on Android)

The TrackBuffersManager would have already handle the dispatching of the encrypted event when parsing the new init segment. As such, nothing more is necessary.

MozReview-Commit-ID: Jn14P2F6N5V

--HG--
extra : rebase_source : afe254fa8c4b835b15d9d48bb52d832f28196b7e
This commit is contained in:
Jean-Yves Avenard 2018-05-27 18:42:25 +02:00
parent b0af7c4063
commit 09c18364f7
2 changed files with 24 additions and 13 deletions

View File

@ -801,12 +801,15 @@ MediaResult
MediaFormatReader::DecoderFactory::DoCreateDecoder(Data& aData)
{
auto& ownerData = aData.mOwnerData;
auto& decoder = mOwner->GetDecoderData(aData.mTrack);
auto& platform =
decoder.IsEncrypted() ? mOwner->mEncryptedPlatform : mOwner->mPlatform;
if (!mOwner->mPlatform) {
mOwner->mPlatform = new PDMFactory();
if (mOwner->IsEncrypted()) {
if (!platform) {
platform = new PDMFactory();
if (decoder.IsEncrypted()) {
MOZ_ASSERT(mOwner->mCDMProxy);
mOwner->mPlatform->SetCDMProxy(mOwner->mCDMProxy);
platform->SetCDMProxy(mOwner->mCDMProxy);
}
}
@ -818,7 +821,7 @@ MediaFormatReader::DecoderFactory::DoCreateDecoder(Data& aData)
switch (aData.mTrack) {
case TrackInfo::kAudioTrack: {
aData.mDecoder = mOwner->mPlatform->CreateDecoder({
aData.mDecoder = platform->CreateDecoder({
*ownerData.GetCurrentInfo()->GetAsAudioInfo(),
ownerData.mTaskQueue,
mOwner->mCrashHelper,
@ -833,7 +836,7 @@ MediaFormatReader::DecoderFactory::DoCreateDecoder(Data& aData)
case TrackType::kVideoTrack: {
// Decoders use the layers backend to decide if they can use hardware decoding,
// so specify LAYERS_NONE if we want to forcibly disable it.
aData.mDecoder = mOwner->mPlatform->CreateDecoder(
aData.mDecoder = platform->CreateDecoder(
{ *ownerData.GetCurrentInfo()->GetAsVideoInfo(),
ownerData.mTaskQueue,
mOwner->mKnowsCompositor,
@ -1428,6 +1431,7 @@ MediaFormatReader::TearDownDecoders()
mDecoderFactory = nullptr;
mPlatform = nullptr;
mEncryptedPlatform = nullptr;
mVideoFrameContainer = nullptr;
ReleaseResources();
@ -1530,9 +1534,9 @@ MediaFormatReader::SetCDMProxy(CDMProxy* aProxy)
mCDMProxy = aProxy;
if (IsEncrypted() && !mCDMProxy) {
if (!mCDMProxy) {
// Release old PDMFactory which contains an EMEDecoderModule.
mPlatform = nullptr;
mEncryptedPlatform = nullptr;
}
if (!mInitDone || mSetCDMForTracks.isEmpty() || !mCDMProxy) {
@ -1752,8 +1756,8 @@ MediaFormatReader::MaybeResolveMetadataPromise()
bool
MediaFormatReader::IsEncrypted() const
{
return (HasAudio() && mInfo.mAudio.mCrypto.mValid) ||
(HasVideo() && mInfo.mVideo.mCrypto.mValid);
return (HasAudio() && mAudio.GetCurrentInfo()->mCrypto.mValid) ||
(HasVideo() && mVideo.GetCurrentInfo()->mCrypto.mValid);
}
void
@ -2406,11 +2410,13 @@ MediaFormatReader::HandleDemuxedSamples(
if (info && decoder.mLastStreamSourceID != info->GetID()) {
nsTArray<RefPtr<MediaRawData>> samples;
if (decoder.mDecoder) {
bool recyclable = StaticPrefs::MediaDecoderRecycleEnabled() &&
decoder.mDecoder->SupportDecoderRecycling();
bool recyclable =
StaticPrefs::MediaDecoderRecycleEnabled() &&
decoder.mDecoder->SupportDecoderRecycling() &&
(*info)->mCrypto.mValid == decoder.GetCurrentInfo()->mCrypto.mValid;
if (!recyclable && decoder.mTimeThreshold.isNothing() &&
(decoder.mNextStreamSourceID.isNothing() ||
decoder.mNextStreamSourceID.ref() != info->GetID())) {
decoder.mNextStreamSourceID.ref() != info->GetID())) {
LOG("%s stream id has changed from:%d to:%d, draining decoder.",
TrackTypeToStr(aTrack),
decoder.mLastStreamSourceID,

View File

@ -339,6 +339,7 @@ private:
size_t SizeOfQueue(TrackType aTrack);
RefPtr<PDMFactory> mPlatform;
RefPtr<PDMFactory> mEncryptedPlatform;
enum class DrainState
{
@ -587,6 +588,10 @@ private:
}
return mOriginalInfo.get();
}
bool IsEncrypted() const
{
return GetCurrentInfo()->mCrypto.mValid;
}
// Used by the MDSM for logging purposes.
Atomic<size_t> mSizeOfQueue;