author | JW Wang <jwwang@mozilla.com> |
Sun, 27 Sep 2015 18:48:59 +0800 | |
changeset 265105 | db7c6afb4cb72bb00846c7766c952705c8031d03 |
parent 265104 | f589a524b7a59205117680cb641e1de110bb891d |
child 265106 | 20b1d715338b972874f8bed076a176425dcaec0d |
push id | 65846 |
push user | jwwang@mozilla.com |
push date | Wed, 30 Sep 2015 02:40:13 +0000 |
treeherder | mozilla-inbound@1abba55f3790 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | cpearce |
bugs | 1208922 |
milestone | 44.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
dom/media/MediaDecoderStateMachine.cpp | file | annotate | diff | comparison | revisions | |
dom/media/MediaDecoderStateMachine.h | file | annotate | diff | comparison | revisions |
--- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -297,16 +297,23 @@ MediaDecoderStateMachine::MediaDecoderSt mAudioQueueListener = AudioQueue().PopEvent().Connect( mTaskQueue, this, &MediaDecoderStateMachine::OnAudioPopped); mVideoQueueListener = VideoQueue().PopEvent().Connect( mTaskQueue, this, &MediaDecoderStateMachine::OnVideoPopped); mMetadataManager.Connect(mReader->TimedMetadataEvent(), OwnerThread()); mMediaSink = CreateAudioSink(); + +#ifdef MOZ_EME + mCDMProxyPromise.Begin(mDecoder->RequestCDMProxy()->Then( + OwnerThread(), __func__, this, + &MediaDecoderStateMachine::OnCDMProxyReady, + &MediaDecoderStateMachine::OnCDMProxyNotReady)); +#endif } MediaDecoderStateMachine::~MediaDecoderStateMachine() { MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread."); MOZ_COUNT_DTOR(MediaDecoderStateMachine); mReader = nullptr; @@ -1312,16 +1319,20 @@ void MediaDecoderStateMachine::Shutdown( // threads can start exiting cleanly during the Shutdown call. ScheduleStateMachine(); SetState(DECODER_STATE_SHUTDOWN); mQueuedSeek.RejectIfExists(__func__); mPendingSeek.RejectIfExists(__func__); mCurrentSeek.RejectIfExists(__func__); +#ifdef MOZ_EME + mCDMProxyPromise.DisconnectIfExists(); +#endif + if (IsPlaying()) { StopPlayback(); } Reset(); mMediaSink->Shutdown(); @@ -1400,19 +1411,16 @@ MediaDecoderStateMachine::NotifyWaitingF MOZ_ASSERT(OnTaskQueue()); ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); DECODER_LOG("NotifyWaitingForResourcesStatusChanged"); if (mState == DECODER_STATE_WAIT_FOR_RESOURCES) { // Try again. SetState(DECODER_STATE_DECODING_NONE); ScheduleStateMachine(); - } else if (mState == DECODER_STATE_WAIT_FOR_CDM && - !mReader->IsWaitingOnCDMResource()) { - StartDecoding(); } } void MediaDecoderStateMachine::PlayStateChanged() { MOZ_ASSERT(OnTaskQueue()); ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); @@ -1997,22 +2005,28 @@ MediaDecoderStateMachine::OnMetadataRead } // In general, we wait until we know the duration before notifying the decoder. // However, we notify unconditionally in this case without waiting for the start // time, since the caller might be waiting on metadataloaded to be fired before // feeding in the CDM, which we need to decode the first frame (and // thus get the metadata). We could fix this if we could compute the start // time by demuxing without necessaring decoding. - mNotifyMetadataBeforeFirstFrame = mDuration.Ref().isSome() || mReader->IsWaitingOnCDMResource(); + bool waitingForCDM = +#ifdef MOZ_EME + mInfo.IsEncrypted() && !mCDMProxy; +#else + false; +#endif + mNotifyMetadataBeforeFirstFrame = mDuration.Ref().isSome() || waitingForCDM; if (mNotifyMetadataBeforeFirstFrame) { EnqueueLoadedMetadataEvent(); } - if (mReader->IsWaitingOnCDMResource()) { + if (waitingForCDM) { // Metadata parsing was successful but we're still waiting for CDM caps // to become available so that we can build the correct decryptor/decoder. SetState(DECODER_STATE_WAIT_FOR_CDM); return; } StartDecoding(); @@ -3036,16 +3050,37 @@ void MediaDecoderStateMachine::OnMediaSi return; } // Otherwise notify media decoder/element about this error for it makes // no sense to play an audio-only file without sound output. DecodeError(); } +#ifdef MOZ_EME +void +MediaDecoderStateMachine::OnCDMProxyReady(nsRefPtr<CDMProxy> aProxy) +{ + MOZ_ASSERT(OnTaskQueue()); + mCDMProxyPromise.Complete(); + mCDMProxy = aProxy; + mReader->SetCDMProxy(aProxy); + if (mState == DECODER_STATE_WAIT_FOR_CDM) { + StartDecoding(); + } +} + +void +MediaDecoderStateMachine::OnCDMProxyNotReady() +{ + MOZ_ASSERT(OnTaskQueue()); + mCDMProxyPromise.Complete(); +} +#endif + void MediaDecoderStateMachine::SetAudioCaptured(bool aCaptured) { MOZ_ASSERT(OnTaskQueue()); ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); if (aCaptured == mAudioCaptured) { return;
--- a/dom/media/MediaDecoderStateMachine.h +++ b/dom/media/MediaDecoderStateMachine.h @@ -1244,16 +1244,23 @@ private: // Media data resource from the decoder. nsRefPtr<MediaResource> mResource; MozPromiseRequestHolder<GenericPromise> mMediaSinkPromise; MediaEventListener mAudioQueueListener; MediaEventListener mVideoQueueListener; +#ifdef MOZ_EME + void OnCDMProxyReady(nsRefPtr<CDMProxy> aProxy); + void OnCDMProxyNotReady(); + nsRefPtr<CDMProxy> mCDMProxy; + MozPromiseRequestHolder<MediaDecoder::CDMProxyPromise> mCDMProxyPromise; +#endif + private: // The buffered range. Mirrored from the decoder thread. Mirror<media::TimeIntervals> mBuffered; // The duration according to the demuxer's current estimate, mirrored from the main thread. Mirror<media::NullableTimeUnit> mEstimatedDuration; // The duration explicitly set by JS, mirrored from the main thread.