Bug 1145203 - Unify FlushDecoding, ResetDecode, and ResetPlayback into a single Reset() method. r=mattwoodrow

This commit is contained in:
Bobby Holley 2015-03-19 09:53:01 -07:00
parent d31de95621
commit fcac4e1548
2 changed files with 34 additions and 71 deletions

View File

@ -1499,8 +1499,8 @@ void MediaDecoderStateMachine::SetDormant(bool aDormant)
if (IsPlaying()) {
StopPlayback();
}
StopAudioThread();
FlushDecoding();
Reset();
// Note that we do not wait for the decode task queue to go idle before
// queuing the ReleaseMediaResources task - instead, we disconnect promises,
@ -1625,38 +1625,6 @@ void MediaDecoderStateMachine::PlayInternal()
ScheduleStateMachine();
}
void MediaDecoderStateMachine::ResetPlayback()
{
MOZ_ASSERT(OnStateMachineThread());
// We should be reseting because we're seeking, shutting down, or
// entering dormant state. We could also be in the process of going dormant,
// and have just switched to exiting dormant before we finished entering
// dormant, hence the DECODING_NONE case below.
AssertCurrentThreadInMonitor();
MOZ_ASSERT(mState == DECODER_STATE_SEEKING ||
mState == DECODER_STATE_SHUTDOWN ||
mState == DECODER_STATE_DORMANT ||
mState == DECODER_STATE_DECODING_NONE);
// Audio thread should've been stopped at the moment. Otherwise, AudioSink
// might be accessing AudioQueue outside of the decoder monitor while we
// are clearing the queue and causes crash for no samples to be popped.
MOZ_ASSERT(!mAudioSink);
mVideoFrameEndTime = -1;
mDecodedVideoEndTime = -1;
mAudioStartTime = -1;
mAudioEndTime = -1;
mDecodedAudioEndTime = -1;
mAudioCompleted = false;
AudioQueue().Reset();
VideoQueue().Reset();
mFirstVideoFrameAfterSeek = nullptr;
mDropAudioUntilNextDiscontinuity = true;
mDropVideoUntilNextDiscontinuity = true;
}
void MediaDecoderStateMachine::NotifyDataArrived(const char* aBuffer,
uint32_t aLength,
int64_t aOffset)
@ -1897,14 +1865,8 @@ MediaDecoderStateMachine::InitiateSeek()
mCurrentSeek.mTarget.mEventVisibility);
NS_DispatchToMainThread(startEvent, NS_DISPATCH_NORMAL);
// The seek target is different than the current playback position,
// we'll need to seek the playback position, so shutdown our decode
// thread and audio sink.
StopAudioThread();
ResetPlayback();
// Put a reset in the pipe before seek.
ResetDecode();
// Reset our state machine and decoding pipeline before seeking.
Reset();
// Do the seek.
mSeekRequest.Begin(ProxyMediaCall(DecodeTaskQueue(), mReader.get(), __func__,
@ -2612,8 +2574,7 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
StopPlayback();
}
StopAudioThread();
FlushDecoding();
Reset();
// Put a task in the decode queue to shutdown the reader.
// the queue to spin down.
@ -2785,27 +2746,38 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
}
void
MediaDecoderStateMachine::FlushDecoding()
MediaDecoderStateMachine::Reset()
{
MOZ_ASSERT(OnStateMachineThread());
AssertCurrentThreadInMonitor();
DECODER_LOG("MediaDecoderStateMachine::Reset");
// Put a task in the decode queue to abort any decoding operations.
// The reader is not supposed to put any tasks to deliver samples into
// the queue after this runs (unless we request another sample from it).
ResetDecode();
// We should be resetting because we're seeking, shutting down, or entering
// dormant state. We could also be in the process of going dormant, and have
// just switched to exiting dormant before we finished entering dormant,
// hence the DECODING_NONE case below.
MOZ_ASSERT(mState == DECODER_STATE_SEEKING ||
mState == DECODER_STATE_SHUTDOWN ||
mState == DECODER_STATE_DORMANT ||
mState == DECODER_STATE_DECODING_NONE);
// We must reset playback so that all references to frames queued
// in the state machine are dropped, else subsequent calls to Shutdown()
// or ReleaseMediaResources() can fail on B2G.
ResetPlayback();
}
// Stop the audio thread. Otherwise, AudioSink might be accessing AudioQueue
// outside of the decoder monitor while we are clearing the queue and causes
// crash for no samples to be popped.
StopAudioThread();
void
MediaDecoderStateMachine::ResetDecode()
{
MOZ_ASSERT(OnStateMachineThread());
AssertCurrentThreadInMonitor();
mVideoFrameEndTime = -1;
mDecodedVideoEndTime = -1;
mAudioStartTime = -1;
mAudioEndTime = -1;
mDecodedAudioEndTime = -1;
mAudioCompleted = false;
AudioQueue().Reset();
VideoQueue().Reset();
mFirstVideoFrameAfterSeek = nullptr;
mDropAudioUntilNextDiscontinuity = true;
mDropVideoUntilNextDiscontinuity = true;
mDecodeToSeekTarget = false;
mMetadataRequest.DisconnectIfExists();
mAudioDataRequest.DisconnectIfExists();
@ -2814,8 +2786,6 @@ MediaDecoderStateMachine::ResetDecode()
mVideoWaitRequest.DisconnectIfExists();
mSeekRequest.DisconnectIfExists();
mDecodeToSeekTarget = false;
RefPtr<nsRunnable> resetTask =
NS_NewRunnableMethod(mReader, &MediaDecoderReader::ResetDecode);
DecodeTaskQueue()->Dispatch(resetTask);

View File

@ -406,8 +406,9 @@ public:
WaitRequestRef(aRejection.mType).Complete();
}
// Resets all state related to decoding, emptying all buffers etc.
void ResetDecode();
// Resets all state related to decoding and playback, emptying all buffers
// and aborting all pending operations on the decode task queue.
void Reset();
private:
void AcquireMonitorAndInvokeDecodeError();
@ -511,14 +512,6 @@ protected:
// Dispatches an asynchronous event to update the media element's ready state.
void UpdateReadyState();
// Resets playback timing data. Called when we seek, on the decode thread.
void ResetPlayback();
// Orders the Reader to stop decoding, and blocks until the Reader
// has stopped decoding and finished delivering samples, then calls
// ResetPlayback() to discard all enqueued data.
void FlushDecoding();
// Called when AudioSink reaches the end. |mPlayStartTime| and
// |mPlayDuration| are updated to provide a good base for calculating video
// stream time.