summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dom/media/DecodedStream.cpp2
-rw-r--r--dom/media/MediaDecoder.cpp23
-rw-r--r--dom/media/MediaDecoder.h5
-rw-r--r--dom/media/MediaDecoderStateMachine.cpp53
-rw-r--r--dom/media/MediaDecoderStateMachine.h19
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: