From effb885bd5299dc03b797143c076842f5d40f0fc Mon Sep 17 00:00:00 2001 From: JW Wang Date: Thu, 28 Aug 2014 02:46:00 +0200 Subject: [PATCH] Bug 1059052 - centralize state transitions of MediaDecoderStateMachine. r=cpearce --- content/media/MediaDecoderStateMachine.cpp | 52 ++++++++++++++++------ content/media/MediaDecoderStateMachine.h | 2 + 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/content/media/MediaDecoderStateMachine.cpp b/content/media/MediaDecoderStateMachine.cpp index 66655dd6859a..3d6e9ee51572 100644 --- a/content/media/MediaDecoderStateMachine.cpp +++ b/content/media/MediaDecoderStateMachine.cpp @@ -1049,7 +1049,7 @@ MediaDecoderStateMachine::CheckIfDecodeComplete() if (!IsVideoDecoding() && !IsAudioDecoding()) { // We've finished decoding all active streams, // so move to COMPLETED state. - mState = DECODER_STATE_COMPLETED; + SetState(DECODER_STATE_COMPLETED); DispatchDecodeTasksIfNeeded(); ScheduleStateMachine(); } @@ -1220,6 +1220,30 @@ MediaDecoderOwner::NextFrameStatus MediaDecoderStateMachine::GetNextFrameStatus( return MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE; } +static const char* const gMachineStateStr[] = { + "NONE", + "DECODING_METADATA", + "WAIT_FOR_RESOURCES", + "DORMANT", + "DECODING", + "SEEKING", + "BUFFERING", + "COMPLETED", + "SHUTDOWN" +}; + +void MediaDecoderStateMachine::SetState(State aState) +{ + AssertCurrentThreadInMonitor(); + if (mState == aState) { + return; + } + DECODER_LOG("Change machine state from %s to %s", + gMachineStateStr[mState], gMachineStateStr[aState]); + + mState = aState; +} + void MediaDecoderStateMachine::SetVolume(double volume) { NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); @@ -1327,13 +1351,13 @@ void MediaDecoderStateMachine::SetDormant(bool aDormant) if (aDormant) { ScheduleStateMachine(); - mState = DECODER_STATE_DORMANT; + SetState(DECODER_STATE_DORMANT); mDecoder->GetReentrantMonitor().NotifyAll(); } else if ((aDormant != true) && (mState == DECODER_STATE_DORMANT)) { ScheduleStateMachine(); mStartTime = 0; mCurrentFrameTime = 0; - mState = DECODER_STATE_DECODING_NONE; + SetState(DECODER_STATE_DECODING_NONE); mDecoder->GetReentrantMonitor().NotifyAll(); } } @@ -1348,7 +1372,7 @@ void MediaDecoderStateMachine::Shutdown() // Change state before issuing shutdown request to threads so those // threads can start exiting cleanly during the Shutdown call. DECODER_LOG("Changed state to SHUTDOWN"); - mState = DECODER_STATE_SHUTDOWN; + SetState(DECODER_STATE_SHUTDOWN); mScheduler->ScheduleAndShutdown(); if (mAudioSink) { mAudioSink->PrepareToShutdown(); @@ -1364,7 +1388,7 @@ void MediaDecoderStateMachine::StartDecoding() if (mState == DECODER_STATE_DECODING) { return; } - mState = DECODER_STATE_DECODING; + SetState(DECODER_STATE_DECODING); mDecodeStartTime = TimeStamp::Now(); @@ -1388,7 +1412,7 @@ void MediaDecoderStateMachine::StartWaitForResources() NS_ASSERTION(OnStateMachineThread() || OnDecodeThread(), "Should be on state machine or decode thread."); AssertCurrentThreadInMonitor(); - mState = DECODER_STATE_WAIT_FOR_RESOURCES; + SetState(DECODER_STATE_WAIT_FOR_RESOURCES); DECODER_LOG("StartWaitForResources"); } @@ -1402,7 +1426,7 @@ void MediaDecoderStateMachine::NotifyWaitingForResourcesStatusChanged() DECODER_LOG("NotifyWaitingForResourcesStatusChanged"); // The reader is no longer waiting for resources (say a hardware decoder), // we can now proceed to decode metadata. - mState = DECODER_STATE_DECODING_NONE; + SetState(DECODER_STATE_DECODING_NONE); ScheduleStateMachine(); } @@ -1415,7 +1439,7 @@ void MediaDecoderStateMachine::Play() ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); if (mState == DECODER_STATE_BUFFERING) { DECODER_LOG("Changed state from BUFFERING to DECODING"); - mState = DECODER_STATE_DECODING; + SetState(DECODER_STATE_DECODING); mDecodeStartTime = TimeStamp::Now(); } // Once we start playing, we don't want to minimize our prerolling, as we @@ -1500,7 +1524,7 @@ void MediaDecoderStateMachine::Seek(const SeekTarget& aTarget) mSeekTarget = SeekTarget(seekTime, aTarget.mType); DECODER_LOG("Changed state to SEEKING (to %lld)", mSeekTarget.mTime); - mState = DECODER_STATE_SEEKING; + SetState(DECODER_STATE_SEEKING); if (mDecoder->GetDecodedStream()) { mDecoder->RecreateDecodedStream(seekTime - mStartTime); } @@ -1757,7 +1781,7 @@ MediaDecoderStateMachine::StartAudioThread() nsresult rv = mAudioSink->Init(); if (NS_FAILED(rv)) { DECODER_WARN("Changed state to SHUTDOWN because audio sink initialization failed"); - mState = DECODER_STATE_SHUTDOWN; + SetState(DECODER_STATE_SHUTDOWN); mScheduler->ScheduleAndShutdown(); return rv; } @@ -1836,7 +1860,7 @@ MediaDecoderStateMachine::DecodeError() // and the HTMLMediaElement, so that our pipeline can start exiting // cleanly during the sync dispatch below. DECODER_WARN("Decode error, changed state to SHUTDOWN due to error"); - mState = DECODER_STATE_SHUTDOWN; + SetState(DECODER_STATE_SHUTDOWN); mScheduler->ScheduleAndShutdown(); mDecoder->GetReentrantMonitor().NotifyAll(); @@ -2161,7 +2185,7 @@ MediaDecoderStateMachine::SeekCompleted() stopEvent = NS_NewRunnableMethod(mDecoder, &MediaDecoder::SeekingStoppedAtEnd); // Explicitly set our state so we don't decode further, and so // we report playback ended to the media element. - mState = DECODER_STATE_COMPLETED; + SetState(DECODER_STATE_COMPLETED); DispatchDecodeTasksIfNeeded(); } else { DECODER_LOG("Changed state from SEEKING (to %lld) to DECODING", seekTime); @@ -2327,7 +2351,7 @@ nsresult MediaDecoderStateMachine::RunStateMachine() } case DECODER_STATE_DECODING_NONE: { - mState = DECODER_STATE_DECODING_METADATA; + SetState(DECODER_STATE_DECODING_METADATA); // Ensure we have a decode thread to decode metadata. return EnqueueDecodeMetadataTask(); } @@ -2914,7 +2938,7 @@ void MediaDecoderStateMachine::StartBuffering() // will check the current state and decide whether to tell // the element we're buffering or not. UpdateReadyState(); - mState = DECODER_STATE_BUFFERING; + SetState(DECODER_STATE_BUFFERING); DECODER_LOG("Changed state from DECODING to BUFFERING, decoded for %.3lfs", decodeDuration.ToSeconds()); #ifdef PR_LOGGING diff --git a/content/media/MediaDecoderStateMachine.h b/content/media/MediaDecoderStateMachine.h index a11d765d76f3..13cb0c4799e5 100644 --- a/content/media/MediaDecoderStateMachine.h +++ b/content/media/MediaDecoderStateMachine.h @@ -355,6 +355,8 @@ protected: void AssertCurrentThreadInMonitor() const { mDecoder->GetReentrantMonitor().AssertCurrentThreadIn(); } + void SetState(State aState); + // Inserts MediaData* samples into their respective MediaQueues. // aSample must not be null. void Push(AudioData* aSample);