Bug 1287670 - Improve cohesion of MDSM::InitiateSeek(). r=kaku
MozReview-Commit-ID: BgaTUXFik9a
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -754,17 +754,16 @@ MediaDecoderStateMachine::MaybeFinishDec
return false;
}
FinishDecodeFirstFrame();
if (!mQueuedSeek.Exists()) {
return false;
}
// We can now complete the pending seek.
- SetState(DECODER_STATE_SEEKING);
InitiateSeek(Move(mQueuedSeek));
return true;
}
void
MediaDecoderStateMachine::OnVideoDecoded(MediaData* aVideoSample,
TimeStamp aDecodeStartTime)
{
@@ -1262,17 +1261,16 @@ void MediaDecoderStateMachine::StartDeco
// the first samples in order to determine the media start time,
// we have the start time from last time we loaded.
// FinishDecodeFirstFrame will be launched upon completion of the seek when
// we have data ready to play.
MOZ_ASSERT(mQueuedSeek.Exists() && mSentFirstFrameLoadedEvent,
"Return from dormant must have queued seek");
}
if (mQueuedSeek.Exists()) {
- SetState(DECODER_STATE_SEEKING);
InitiateSeek(Move(mQueuedSeek));
return;
}
}
mDecodeStartTime = TimeStamp::Now();
CheckIfDecodeComplete();
@@ -1515,22 +1513,20 @@ MediaDecoderStateMachine::Seek(SeekTarge
DECODER_LOG("Seek() Not Enough Data to continue at this stage, queuing seek");
mQueuedSeek.RejectIfExists(__func__);
mQueuedSeek.mTarget = aTarget;
return mQueuedSeek.mPromise.Ensure(__func__);
}
mQueuedSeek.RejectIfExists(__func__);
DECODER_LOG("Changed state to SEEKING (to %lld)", aTarget.GetTime().ToMicroseconds());
- SetState(DECODER_STATE_SEEKING);
SeekJob seekJob;
seekJob.mTarget = aTarget;
- InitiateSeek(Move(seekJob));
- return mCurrentSeek.mPromise.Ensure(__func__);
+ return InitiateSeek(Move(seekJob));
}
RefPtr<MediaDecoder::SeekPromise>
MediaDecoderStateMachine::InvokeSeek(SeekTarget aTarget)
{
return InvokeAsync(OwnerThread(), this, __func__,
&MediaDecoderStateMachine::Seek, aTarget);
}
@@ -1600,65 +1596,69 @@ MediaDecoderStateMachine::DispatchDecode
if (needIdle) {
DECODER_LOG("Dispatching SetIdle() audioQueue=%lld videoQueue=%lld",
GetDecodedAudioDuration(),
VideoQueue().Duration());
mReader->SetIdle();
}
}
-void
+RefPtr<MediaDecoder::SeekPromise>
MediaDecoderStateMachine::InitiateSeek(SeekJob aSeekJob)
{
MOZ_ASSERT(OnTaskQueue());
+ SetState(DECODER_STATE_SEEKING);
+
// Discard the existing seek task.
DiscardSeekTaskIfExist();
mSeekTaskRequest.DisconnectIfExists();
// SeekTask will register its callbacks to MediaDecoderReaderWrapper.
CancelMediaDecoderReaderWrapperCallback();
// Create a new SeekTask instance for the incoming seek task.
- MOZ_ASSERT(!mCurrentSeek.Exists());
- mCurrentSeek = Move(aSeekJob);
- if (mCurrentSeek.mTarget.IsAccurate() || mCurrentSeek.mTarget.IsFast()) {
+ if (aSeekJob.mTarget.IsAccurate() || aSeekJob.mTarget.IsFast()) {
mSeekTask = new AccurateSeekTask(mDecoderID, OwnerThread(),
- mReader.get(), mCurrentSeek.mTarget,
+ mReader.get(), aSeekJob.mTarget,
mInfo, Duration(), GetMediaTime());
- } else if (mCurrentSeek.mTarget.IsNextFrame()) {
+ } else if (aSeekJob.mTarget.IsNextFrame()) {
mSeekTask = new NextFrameSeekTask(mDecoderID, OwnerThread(), mReader.get(),
- mCurrentSeek.mTarget, mInfo, Duration(),
+ aSeekJob.mTarget, mInfo, Duration(),
GetMediaTime(), AudioQueue(), VideoQueue());
} else {
MOZ_DIAGNOSTIC_ASSERT(false, "Cannot handle this seek task.");
}
// Stop playback now to ensure that while we're outside the monitor
// dispatching SeekingStarted, playback doesn't advance and mess with
// mCurrentPosition that we've setting to seekTime here.
StopPlayback();
- // mCurrentSeek.mTarget.mTime might be different from
+ // aSeekJob.mTarget.mTime might be different from
// mSeekTask->GetSeekTarget().mTime because the seek task might clamp the seek
// target to [0, duration]. We want to update the playback position to the
// clamped value.
UpdatePlaybackPositionInternal(mSeekTask->GetSeekTarget().GetTime().ToMicroseconds());
- mOnSeekingStart.Notify(mCurrentSeek.mTarget.mEventVisibility);
+ mOnSeekingStart.Notify(aSeekJob.mTarget.mEventVisibility);
// Reset our state machine and decoding pipeline before seeking.
if (mSeekTask->NeedToResetMDSM()) { Reset(); }
// Do the seek.
mSeekTaskRequest.Begin(mSeekTask->Seek(Duration())
->Then(OwnerThread(), __func__, this,
&MediaDecoderStateMachine::OnSeekTaskResolved,
&MediaDecoderStateMachine::OnSeekTaskRejected));
+
+ MOZ_ASSERT(!mCurrentSeek.Exists());
+ mCurrentSeek = Move(aSeekJob);
+ return mCurrentSeek.mPromise.Ensure(__func__);
}
void
MediaDecoderStateMachine::OnSeekTaskResolved(SeekTaskResolveValue aValue)
{
MOZ_ASSERT(OnTaskQueue());
MOZ_ASSERT(mState == DECODER_STATE_SEEKING);
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -504,18 +504,17 @@ protected:
// Dispatches a LoadedMetadataEvent.
// This is threadsafe and can be called on any thread.
// The decoder monitor must be held.
void EnqueueLoadedMetadataEvent();
void EnqueueFirstFrameLoadedEvent();
// Clears any previous seeking state and initiates a new seek on the decoder.
- // The decoder monitor must be held.
- void InitiateSeek(SeekJob aSeekJob);
+ RefPtr<MediaDecoder::SeekPromise> InitiateSeek(SeekJob aSeekJob);
// Clears any previous seeking state and initiates a seek on the decoder to
// resync the video and audio positions, when recovering from video decoding
// being suspended in background or from audio and video decoding being
// suspended due to the decoder limit.
void InitiateDecodeRecoverySeek(TrackSet aTracks);
nsresult DispatchAudioDecodeTaskIfNeeded();