diff options
-rw-r--r-- | dom/media/DecodedStream.cpp | 2 | ||||
-rw-r--r-- | dom/media/MediaDecoder.cpp | 23 | ||||
-rw-r--r-- | dom/media/MediaDecoder.h | 5 | ||||
-rw-r--r-- | dom/media/MediaDecoderStateMachine.cpp | 53 | ||||
-rw-r--r-- | dom/media/MediaDecoderStateMachine.h | 19 |
5 files changed, 58 insertions, 44 deletions
diff --git a/dom/media/DecodedStream.cpp b/dom/media/DecodedStream.cpp index 1302709fd..b2e15a6b3 100644 --- a/dom/media/DecodedStream.cpp +++ b/dom/media/DecodedStream.cpp @@ -85,6 +85,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 f43eadec5..561c057a3 100644 --- a/dom/media/MediaDecoder.cpp +++ b/dom/media/MediaDecoder.cpp @@ -315,28 +315,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<nsIRunnable> runnable = - NS_NewRunnableMethodWithArg<int32_t>(GetDecodedStream()->mStream.get(), - &MediaStream::ChangeExplicitBlockerCount, delta); - NS_DispatchToMainThread(runnable); - } - } -} - void MediaDecoder::RecreateDecodedStream(int64_t aStartTimeUSecs) { MOZ_ASSERT(NS_IsMainThread()); @@ -344,7 +322,6 @@ void MediaDecoder::RecreateDecodedStream(int64_t aStartTimeUSecs) DECODER_LOG("RecreateDecodedStream aStartTimeUSecs=%lld!", aStartTimeUSecs); mDecodedStream.RecreateData(aStartTimeUSecs, MediaStreamGraph::GetInstance()); - UpdateStreamBlockingForStateMachinePlaying(); UpdateStreamBlockingForPlayState(); } diff --git a/dom/media/MediaDecoder.h b/dom/media/MediaDecoder.h index 62cc296ac..abaa9d7b5 100644 --- a/dom/media/MediaDecoder.h +++ b/dom/media/MediaDecoder.h @@ -400,11 +400,6 @@ public: * Decoder monitor must be held. */ void RecreateDecodedStream(int64_t aStartTimeUSecs); - /** - * 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 86c2ee6d3..227453acf 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -426,6 +426,19 @@ static void WriteVideoToMediaStream(MediaStream* aStream, aOutput->AppendFrame(image.forget(), duration, aIntrinsicSize); } +static void +UpdateStreamBlocking(MediaStream* aStream, bool aBlocking) +{ + int32_t delta = aBlocking ? 1 : -1; + if (NS_IsMainThread()) { + aStream->ChangeExplicitBlockerCount(delta); + } else { + nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArg<int32_t>( + aStream, &MediaStream::ChangeExplicitBlockerCount, delta); + AbstractThread::MainThread()->Dispatch(r.forget()); + } +} + void MediaDecoderStateMachine::SendStreamData() { MOZ_ASSERT(OnTaskQueue()); @@ -467,6 +480,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()) { @@ -1256,7 +1274,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(); } @@ -1294,7 +1312,7 @@ void MediaDecoderStateMachine::MaybeStartPlayback() NS_ENSURE_SUCCESS_VOID(rv); mDecoder->GetReentrantMonitor().NotifyAll(); - mDecoder->UpdateStreamBlockingForStateMachinePlaying(); + UpdateStreamBlockingForStateMachinePlaying(); DispatchDecodeTasksIfNeeded(); } @@ -3490,6 +3508,37 @@ void MediaDecoderStateMachine::OnAudioSinkError() DecodeError(); } +void MediaDecoderStateMachine::DispatchAudioCaptured() +{ + nsRefPtr<MediaDecoderStateMachine> self = this; + nsCOMPtr<nsIRunnable> 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 89ee36c01..9a14dee2f 100644 --- a/dom/media/MediaDecoderStateMachine.h +++ b/dom/media/MediaDecoderStateMachine.h @@ -150,20 +150,7 @@ public: return mState; } - void DispatchAudioCaptured() - { - nsRefPtr<MediaDecoderStateMachine> self = this; - nsCOMPtr<nsIRunnable> 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(); @@ -175,6 +162,10 @@ private: // task that gets run on the task queue, and is dispatched from the MDSM // constructor immediately after the task queue is created. void InitializationTask(); + + // Call this IsPlaying() changes. Decoder monitor must be held. + void UpdateStreamBlockingForStateMachinePlaying(); + void Shutdown(); public: |