From 7435f302de423fbe16e3691d3176937041a08668 Mon Sep 17 00:00:00 2001 From: JW Wang Date: Sun, 27 Sep 2015 21:37:48 +0800 Subject: [PATCH] Bug 1209864. Part 1 - make all methods run on the main thread and remove usage of the decoder monitor. r=roc. --- dom/media/MediaDecoderStateMachine.cpp | 15 +++++----- dom/media/MediaDecoderStateMachine.h | 17 +++++++++++ dom/media/omx/MediaOmxCommonDecoder.cpp | 39 ++++++++++++++++++++----- dom/media/omx/MediaOmxCommonDecoder.h | 1 + 4 files changed, 57 insertions(+), 15 deletions(-) diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index 375081455cee..130846ebb9fa 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -223,6 +223,7 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder, mSentPlaybackEndedEvent(false), mStreamSink(new DecodedStream(mTaskQueue, mAudioQueue, mVideoQueue)), mResource(aDecoder->GetResource()), + mAudioOffloading(false), mBuffered(mTaskQueue, TimeIntervals(), "MediaDecoderStateMachine::mBuffered (Mirror)"), mEstimatedDuration(mTaskQueue, NullableTimeUnit(), @@ -1088,15 +1089,13 @@ void MediaDecoderStateMachine::MaybeStartPlayback() } bool playStatePermits = mPlayState == MediaDecoder::PLAY_STATE_PLAYING; - if (!playStatePermits || mIsAudioPrerolling || mIsVideoPrerolling) { + if (!playStatePermits || mIsAudioPrerolling || + mIsVideoPrerolling || mAudioOffloading) { DECODER_LOG("Not starting playback [playStatePermits: %d, " - "mIsAudioPrerolling: %d, mIsVideoPrerolling: %d]", - (int) playStatePermits, (int) mIsAudioPrerolling, (int) mIsVideoPrerolling); - return; - } - - if (mDecoder->CheckDecoderCanOffloadAudio()) { - DECODER_LOG("Offloading playback"); + "mIsAudioPrerolling: %d, mIsVideoPrerolling: %d, " + "mAudioOffloading: %d]", + (int)playStatePermits, (int)mIsAudioPrerolling, + (int)mIsVideoPrerolling, (int)mAudioOffloading); return; } diff --git a/dom/media/MediaDecoderStateMachine.h b/dom/media/MediaDecoderStateMachine.h index 8eb301174aab..f0f6eebc58f3 100644 --- a/dom/media/MediaDecoderStateMachine.h +++ b/dom/media/MediaDecoderStateMachine.h @@ -205,6 +205,19 @@ public: OwnerThread()->Dispatch(r.forget()); } + void DispatchAudioOffloading(bool aAudioOffloading) + { + nsRefPtr self = this; + nsCOMPtr r = NS_NewRunnableFunction([=] () { + ReentrantMonitorAutoEnter mon(self->mDecoder->GetReentrantMonitor()); + if (self->mAudioOffloading != aAudioOffloading) { + self->mAudioOffloading = aAudioOffloading; + self->ScheduleStateMachine(); + } + }); + OwnerThread()->Dispatch(r.forget()); + } + // Drop reference to decoder. Only called during shutdown dance. void BreakCycles() { MOZ_ASSERT(NS_IsMainThread()); @@ -1242,6 +1255,10 @@ private: MediaEventListener mAudioQueueListener; MediaEventListener mVideoQueueListener; + // True if audio is offloading. + // Playback will not start when audio is offloading. + bool mAudioOffloading; + #ifdef MOZ_EME void OnCDMProxyReady(nsRefPtr aProxy); void OnCDMProxyNotReady(); diff --git a/dom/media/omx/MediaOmxCommonDecoder.cpp b/dom/media/omx/MediaOmxCommonDecoder.cpp index f0128d48ab5b..4f32ab7ce824 100644 --- a/dom/media/omx/MediaOmxCommonDecoder.cpp +++ b/dom/media/omx/MediaOmxCommonDecoder.cpp @@ -41,13 +41,38 @@ MediaOmxCommonDecoder::~MediaOmxCommonDecoder() {} void MediaOmxCommonDecoder::SetPlatformCanOffloadAudio(bool aCanOffloadAudio) { - ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); - mCanOffloadAudio = aCanOffloadAudio; + if (!aCanOffloadAudio) { + return; + } + + // Stop MDSM from playing to avoid startup glitch (bug 1053186). + GetStateMachine()->DispatchAudioOffloading(true); + + // Modify mCanOffloadAudio in the main thread. + nsRefPtr self = this; + nsCOMPtr r = NS_NewRunnableFunction([=] () { + self->mCanOffloadAudio = true; + }); + AbstractThread::MainThread()->Dispatch(r.forget()); +} + +void +MediaOmxCommonDecoder::DisableStateMachineAudioOffloading() +{ + MOZ_ASSERT(NS_IsMainThread()); + if (mCanOffloadAudio) { + // mCanOffloadAudio is true implies we've called + // |GetStateMachine()->DispatchAudioOffloading(true)| in + // SetPlatformCanOffloadAudio(). We need to turn off audio offloading + // for MDSM so it can start playback. + GetStateMachine()->DispatchAudioOffloading(false); + } } bool MediaOmxCommonDecoder::CheckDecoderCanOffloadAudio() { + MOZ_ASSERT(NS_IsMainThread()); return (mCanOffloadAudio && !mFallbackToStateMachine && !mIsCaptured && mPlaybackRate == 1.0); } @@ -64,10 +89,10 @@ MediaOmxCommonDecoder::FirstFrameLoaded(nsAutoPtr aInfo, MediaDecoder::FirstFrameLoaded(aInfo, aEventVisibility); - ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); if (!CheckDecoderCanOffloadAudio()) { DECODER_LOG(LogLevel::Debug, ("In %s Offload Audio check failed", __PRETTY_FUNCTION__)); + DisableStateMachineAudioOffloading(); return; } @@ -75,6 +100,7 @@ MediaOmxCommonDecoder::FirstFrameLoaded(nsAutoPtr aInfo, mAudioOffloadPlayer = new AudioOffloadPlayer(this); #endif if (!mAudioOffloadPlayer) { + DisableStateMachineAudioOffloading(); return; } @@ -85,6 +111,7 @@ MediaOmxCommonDecoder::FirstFrameLoaded(nsAutoPtr aInfo, mFallbackToStateMachine = true; DECODER_LOG(LogLevel::Debug, ("In %s Unable to start offload audio %d." "Switching to normal mode", __PRETTY_FUNCTION__, err)); + DisableStateMachineAudioOffloading(); return; } PauseStateMachine(); @@ -105,7 +132,6 @@ void MediaOmxCommonDecoder::PauseStateMachine() { MOZ_ASSERT(NS_IsMainThread()); - GetReentrantMonitor().AssertCurrentThreadIn(); DECODER_LOG(LogLevel::Debug, ("%s", __PRETTY_FUNCTION__)); if (mShuttingDown) { @@ -123,7 +149,6 @@ void MediaOmxCommonDecoder::ResumeStateMachine() { MOZ_ASSERT(NS_IsMainThread()); - ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); DECODER_LOG(LogLevel::Debug, ("%s current time %f", __PRETTY_FUNCTION__, mLogicalPosition)); if (mShuttingDown) { @@ -134,6 +159,8 @@ MediaOmxCommonDecoder::ResumeStateMachine() return; } + GetStateMachine()->DispatchAudioOffloading(false); + mFallbackToStateMachine = true; mAudioOffloadPlayer = nullptr; SeekTarget target = SeekTarget(mLogicalPosition, @@ -231,8 +258,6 @@ MediaOmxCommonDecoder::CurrentPosition() if (!mAudioOffloadPlayer) { return MediaDecoder::CurrentPosition(); } - - ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); return mAudioOffloadPlayer->GetMediaTimeUs(); } diff --git a/dom/media/omx/MediaOmxCommonDecoder.h b/dom/media/omx/MediaOmxCommonDecoder.h index eadf2eb43d87..f231b3a0c664 100644 --- a/dom/media/omx/MediaOmxCommonDecoder.h +++ b/dom/media/omx/MediaOmxCommonDecoder.h @@ -50,6 +50,7 @@ protected: virtual ~MediaOmxCommonDecoder(); void PauseStateMachine(); void ResumeStateMachine(); + void DisableStateMachineAudioOffloading(); MediaOmxCommonReader* mReader;