Bug 1136873 - Deliver NotifyWaitingForResourcesStatusChanged asynchronously on the state machine task queue. r=mattwoodrow

The previous setup is wacky, and can cause the notification to reach the state
machine before the promise rejection, which causes us to stall intermittently.
We also take the opportunity to be a bit less trigger happy when we fire it
in MediaSourceReader.cpp.
This commit is contained in:
Bobby Holley 2015-03-21 16:32:40 -07:00
parent 40a80320a6
commit 9487e1743a
4 changed files with 17 additions and 29 deletions

View File

@ -1640,9 +1640,11 @@ MediaDecoderStateMachine* MediaDecoder::GetStateMachine() const {
void
MediaDecoder::NotifyWaitingForResourcesStatusChanged()
{
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
if (mDecoderStateMachine) {
mDecoderStateMachine->NotifyWaitingForResourcesStatusChanged();
RefPtr<nsRunnable> task =
NS_NewRunnableMethod(mDecoderStateMachine,
&MediaDecoderStateMachine::NotifyWaitingForResourcesStatusChanged);
mDecoderStateMachine->TaskQueue()->Dispatch(task.forget());
}
}
@ -1740,7 +1742,6 @@ CDMProxy*
MediaDecoder::GetCDMProxy()
{
GetReentrantMonitor().AssertCurrentThreadIn();
MOZ_ASSERT(OnDecodeThread() || NS_IsMainThread());
return mProxy;
}
#endif

View File

@ -1562,32 +1562,19 @@ void MediaDecoderStateMachine::StartDecoding()
void MediaDecoderStateMachine::NotifyWaitingForResourcesStatusChanged()
{
AssertCurrentThreadInMonitor();
DECODER_LOG("NotifyWaitingForResourcesStatusChanged");
RefPtr<nsIRunnable> task(
NS_NewRunnableMethod(this,
&MediaDecoderStateMachine::DoNotifyWaitingForResourcesStatusChanged));
DecodeTaskQueue()->Dispatch(task);
}
void MediaDecoderStateMachine::DoNotifyWaitingForResourcesStatusChanged()
{
NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
MOZ_ASSERT(OnStateMachineThread());
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
DECODER_LOG("DoNotifyWaitingForResourcesStatusChanged");
DECODER_LOG("NotifyWaitingForResourcesStatusChanged");
if (mState == DECODER_STATE_WAIT_FOR_RESOURCES) {
// The reader is no longer waiting for resources (say a hardware decoder),
// we can now proceed to decode metadata.
// Try again.
SetState(DECODER_STATE_DECODING_NONE);
ScheduleStateMachine();
} else if (mState == DECODER_STATE_WAIT_FOR_CDM &&
!mReader->IsWaitingOnCDMResource()) {
SetState(DECODER_STATE_DECODING_FIRSTFRAME);
EnqueueDecodeFirstFrameTask();
}
ScheduleStateMachine();
}
void MediaDecoderStateMachine::PlayInternal()
@ -2214,7 +2201,7 @@ MediaDecoderStateMachine::OnMetadataRead(MetadataHolder* aMetadata)
// 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 NS_OK;
return;
}
SetState(DECODER_STATE_DECODING_FIRSTFRAME);

View File

@ -367,9 +367,8 @@ public:
// be held.
bool IsPlaying() const;
// Dispatch DoNotifyWaitingForResourcesStatusChanged task to the task queue.
// Called when the reader may have acquired the hardware resources required
// to begin decoding. The decoder monitor must be held while calling this.
// to begin decoding.
void NotifyWaitingForResourcesStatusChanged();
// Notifies the state machine that should minimize the number of samples
@ -726,10 +725,6 @@ protected:
// Called by the AudioSink to signal errors.
void OnAudioSinkError();
// The state machine may move into DECODING_METADATA if we are in
// DECODER_STATE_WAIT_FOR_RESOURCES.
void DoNotifyWaitingForResourcesStatusChanged();
// Return true if the video decoder's decode speed can not catch up the
// play time.
bool NeedToSkipToNextKeyframe();

View File

@ -71,7 +71,9 @@ MediaSourceReader::PrepareInitialization()
MSE_DEBUG("trackBuffers=%u", mTrackBuffers.Length());
mEssentialTrackBuffers.AppendElements(mTrackBuffers);
mHasEssentialTrackBuffers = true;
mDecoder->NotifyWaitingForResourcesStatusChanged();
if (!IsWaitingMediaResources()) {
mDecoder->NotifyWaitingForResourcesStatusChanged();
}
}
bool
@ -761,7 +763,10 @@ MediaSourceReader::OnTrackBufferConfigured(TrackBuffer* aTrackBuffer, const Medi
MSE_DEBUG("%p video", aTrackBuffer);
mVideoTrack = aTrackBuffer;
}
mDecoder->NotifyWaitingForResourcesStatusChanged();
if (!IsWaitingMediaResources()) {
mDecoder->NotifyWaitingForResourcesStatusChanged();
}
}
bool