Bug 1059052 - centralize state transitions of MediaDecoderStateMachine. r=cpearce

This commit is contained in:
JW Wang 2014-08-28 02:46:00 +02:00
Родитель 1462ca80fc
Коммит effb885bd5
2 изменённых файлов: 40 добавлений и 14 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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);