From ee6ccb58560543aa2aa7867c7393e6cd9011befc Mon Sep 17 00:00:00 2001 From: JW Wang Date: Thu, 28 May 2015 14:16:42 +0800 Subject: [PATCH] Bug 1163467. Part 4 - move MediaDecoder::UpdateStreamBlockingForStateMachinePlaying to MediaDecoderStateMachine. r=roc. --- dom/media/DecodedStream.cpp | 2 + dom/media/MediaDecoder.cpp | 23 ----------- dom/media/MediaDecoder.h | 5 --- dom/media/MediaDecoderStateMachine.cpp | 53 +++++++++++++++++++++++++- dom/media/MediaDecoderStateMachine.h | 18 ++------- 5 files changed, 57 insertions(+), 44 deletions(-) diff --git a/dom/media/DecodedStream.cpp b/dom/media/DecodedStream.cpp index d4883986478..9945dbcfa1b 100644 --- a/dom/media/DecodedStream.cpp +++ b/dom/media/DecodedStream.cpp @@ -86,6 +86,8 @@ DecodedStreamData::DecodedStreamData(int64_t aInitialTime, { mListener = new DecodedStreamGraphListener(mStream); mStream->AddListener(mListener); + // Block the stream until the initialization is done. + mStream->ChangeExplicitBlockerCount(1); } DecodedStreamData::~DecodedStreamData() diff --git a/dom/media/MediaDecoder.cpp b/dom/media/MediaDecoder.cpp index 747a46bb644..7e2240814cc 100644 --- a/dom/media/MediaDecoder.cpp +++ b/dom/media/MediaDecoder.cpp @@ -304,28 +304,6 @@ void MediaDecoder::UpdateStreamBlockingForPlayState() } } -void MediaDecoder::UpdateStreamBlockingForStateMachinePlaying() -{ - GetReentrantMonitor().AssertCurrentThreadIn(); - if (!GetDecodedStream()) { - return; - } - bool blockForStateMachineNotPlaying = - mDecoderStateMachine && !mDecoderStateMachine->IsPlaying(); - if (blockForStateMachineNotPlaying != GetDecodedStream()->mHaveBlockedForStateMachineNotPlaying) { - GetDecodedStream()->mHaveBlockedForStateMachineNotPlaying = blockForStateMachineNotPlaying; - int32_t delta = blockForStateMachineNotPlaying ? 1 : -1; - if (NS_IsMainThread()) { - GetDecodedStream()->mStream->ChangeExplicitBlockerCount(delta); - } else { - nsCOMPtr runnable = - NS_NewRunnableMethodWithArg(GetDecodedStream()->mStream.get(), - &MediaStream::ChangeExplicitBlockerCount, delta); - NS_DispatchToMainThread(runnable); - } - } -} - void MediaDecoder::RecreateDecodedStream(int64_t aStartTimeUSecs, MediaStreamGraph* aGraph) { @@ -334,7 +312,6 @@ void MediaDecoder::RecreateDecodedStream(int64_t aStartTimeUSecs, DECODER_LOG("RecreateDecodedStream aStartTimeUSecs=%lld!", aStartTimeUSecs); mDecodedStream.RecreateData(aStartTimeUSecs, aGraph); - UpdateStreamBlockingForStateMachinePlaying(); UpdateStreamBlockingForPlayState(); } diff --git a/dom/media/MediaDecoder.h b/dom/media/MediaDecoder.h index 4d358c69ba4..27fc886c197 100644 --- a/dom/media/MediaDecoder.h +++ b/dom/media/MediaDecoder.h @@ -405,11 +405,6 @@ public: */ void RecreateDecodedStream(int64_t aStartTimeUSecs, MediaStreamGraph* aGraph = nullptr); - /** - * Call this when mDecoderStateMachine or mDecoderStateMachine->IsPlaying() changes. - * Decoder monitor must be held. - */ - void UpdateStreamBlockingForStateMachinePlaying(); DecodedStreamData* GetDecodedStream() { diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index 0bf43635ce8..41b48553bbb 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -422,6 +422,19 @@ static bool ZeroDurationAtLastChunk(VideoSegment& aInput) return lastVideoStratTime == aInput.GetDuration(); } +static void +UpdateStreamBlocking(MediaStream* aStream, bool aBlocking) +{ + int32_t delta = aBlocking ? 1 : -1; + if (NS_IsMainThread()) { + aStream->ChangeExplicitBlockerCount(delta); + } else { + nsCOMPtr r = NS_NewRunnableMethodWithArg( + aStream, &MediaStream::ChangeExplicitBlockerCount, delta); + AbstractThread::MainThread()->Dispatch(r.forget()); + } +} + void MediaDecoderStateMachine::SendStreamData() { MOZ_ASSERT(OnTaskQueue()); @@ -463,6 +476,11 @@ void MediaDecoderStateMachine::SendStreamData() } mediaStream->FinishAddTracks(); stream->mStreamInitialized = true; + + // Make sure stream blocking is updated before sending stream data so we + // don't 'leak' data when the stream is supposed to be blocked. + UpdateStreamBlockingForStateMachinePlaying(); + UpdateStreamBlocking(mediaStream, false); } if (mInfo.HasAudio()) { @@ -1271,7 +1289,7 @@ void MediaDecoderStateMachine::StopPlayback() // so it can pause audio playback. mDecoder->GetReentrantMonitor().NotifyAll(); NS_ASSERTION(!IsPlaying(), "Should report not playing at end of StopPlayback()"); - mDecoder->UpdateStreamBlockingForStateMachinePlaying(); + UpdateStreamBlockingForStateMachinePlaying(); DispatchDecodeTasksIfNeeded(); } @@ -1309,7 +1327,7 @@ void MediaDecoderStateMachine::MaybeStartPlayback() NS_ENSURE_SUCCESS_VOID(rv); mDecoder->GetReentrantMonitor().NotifyAll(); - mDecoder->UpdateStreamBlockingForStateMachinePlaying(); + UpdateStreamBlockingForStateMachinePlaying(); DispatchDecodeTasksIfNeeded(); } @@ -3487,6 +3505,37 @@ uint32_t MediaDecoderStateMachine::GetAmpleVideoFrames() const : std::max(sVideoQueueDefaultSize, MIN_VIDEO_QUEUE_SIZE); } +void MediaDecoderStateMachine::DispatchAudioCaptured() +{ + nsRefPtr self = this; + nsCOMPtr r = NS_NewRunnableFunction([self] () -> void + { + MOZ_ASSERT(self->OnTaskQueue()); + ReentrantMonitorAutoEnter mon(self->mDecoder->GetReentrantMonitor()); + if (!self->mAudioCaptured) { + self->mAudioCaptured = true; + self->ScheduleStateMachine(); + } + }); + TaskQueue()->Dispatch(r.forget()); +} + +void MediaDecoderStateMachine::UpdateStreamBlockingForStateMachinePlaying() +{ + AssertCurrentThreadInMonitor(); + + auto stream = mDecoder->GetDecodedStream(); + if (!stream) { + return; + } + + bool blocking = !IsPlaying(); + if (blocking != stream->mHaveBlockedForStateMachineNotPlaying) { + stream->mHaveBlockedForStateMachineNotPlaying = blocking; + UpdateStreamBlocking(stream->mStream, blocking); + } +} + } // namespace mozilla // avoid redefined macro in unified build diff --git a/dom/media/MediaDecoderStateMachine.h b/dom/media/MediaDecoderStateMachine.h index 566e1183d9d..9e2a12ab62c 100644 --- a/dom/media/MediaDecoderStateMachine.h +++ b/dom/media/MediaDecoderStateMachine.h @@ -145,20 +145,7 @@ public: return mState; } - void DispatchAudioCaptured() - { - nsRefPtr self = this; - nsCOMPtr r = NS_NewRunnableFunction([self] () -> void - { - MOZ_ASSERT(self->OnTaskQueue()); - ReentrantMonitorAutoEnter mon(self->mDecoder->GetReentrantMonitor()); - if (!self->mAudioCaptured) { - self->mAudioCaptured = true; - self->ScheduleStateMachine(); - } - }); - TaskQueue()->Dispatch(r.forget()); - } + void DispatchAudioCaptured(); // Check if the decoder needs to become dormant state. bool IsDormantNeeded(); @@ -171,6 +158,9 @@ private: // constructor immediately after the task queue is created. void InitializationTask(); + // Call this IsPlaying() changes. Decoder monitor must be held. + void UpdateStreamBlockingForStateMachinePlaying(); + void Shutdown(); public: