зеркало из https://github.com/mozilla/gecko-dev.git
Bug 469275 - Seeks requested while Wave state machine is in ended state are lost. r+sr=roc
--HG-- extra : rebase_source : 03ead0a2032ac705b2156bb1b02aef33a414c67b
This commit is contained in:
Родитель
1510f855ef
Коммит
105f254748
|
@ -354,6 +354,9 @@ private:
|
|||
// run. This allows coalescing of these events as they can be produced
|
||||
// many times per second.
|
||||
PRPackedBool mPositionChangeQueued;
|
||||
|
||||
// True if paused. Tracks only the play/paused state.
|
||||
PRPackedBool mPaused;
|
||||
};
|
||||
|
||||
nsWaveStateMachine::nsWaveStateMachine(nsWaveDecoder* aDecoder, nsMediaStream* aStream,
|
||||
|
@ -379,7 +382,8 @@ nsWaveStateMachine::nsWaveStateMachine(nsWaveDecoder* aDecoder, nsMediaStream* a
|
|||
mTimeOffset(0),
|
||||
mSeekTime(0.0),
|
||||
mMetadataValid(PR_FALSE),
|
||||
mPositionChangeQueued(PR_FALSE)
|
||||
mPositionChangeQueued(PR_FALSE),
|
||||
mPaused(mNextState == STATE_PAUSED)
|
||||
{
|
||||
mMonitor = nsAutoMonitor::NewMonitor("nsWaveStateMachine");
|
||||
mDownloadStatistics.Start(PR_IntervalNow());
|
||||
|
@ -400,6 +404,7 @@ void
|
|||
nsWaveStateMachine::Play()
|
||||
{
|
||||
nsAutoMonitor monitor(mMonitor);
|
||||
mPaused = PR_FALSE;
|
||||
if (mState == STATE_LOADING_METADATA || mState == STATE_SEEKING) {
|
||||
mNextState = STATE_PLAYING;
|
||||
} else {
|
||||
|
@ -431,6 +436,7 @@ void
|
|||
nsWaveStateMachine::Pause()
|
||||
{
|
||||
nsAutoMonitor monitor(mMonitor);
|
||||
mPaused = PR_TRUE;
|
||||
if (mState == STATE_LOADING_METADATA || mState == STATE_SEEKING) {
|
||||
mNextState = STATE_PAUSED;
|
||||
} else {
|
||||
|
@ -722,14 +728,21 @@ nsWaveStateMachine::Run()
|
|||
}
|
||||
|
||||
if (mState == STATE_SEEKING && mSeekTime == seekTime) {
|
||||
// Special case: if a seek was requested during metadata load,
|
||||
// Special case #1: if a seek was requested during metadata load,
|
||||
// mNextState will have been clobbered. This can only happen when
|
||||
// we're instantiating a decoder to service a seek request after
|
||||
// playback has ended, so we know that the clobbered mNextState
|
||||
// was PAUSED.
|
||||
// Special case #2: if a seek is requested after the state machine
|
||||
// entered STATE_ENDED but before the user has seen the ended
|
||||
// event, playback has not ended as far as the user's
|
||||
// concerned--the state machine needs to return to the last
|
||||
// playback state.
|
||||
State nextState = mNextState;
|
||||
if (nextState == STATE_SEEKING) {
|
||||
nextState = STATE_PAUSED;
|
||||
} else if (nextState == STATE_ENDED) {
|
||||
nextState = mPaused ? STATE_PAUSED : STATE_PLAYING;
|
||||
}
|
||||
ChangeState(nextState);
|
||||
}
|
||||
|
@ -757,14 +770,14 @@ nsWaveStateMachine::Run()
|
|||
monitor.Enter();
|
||||
}
|
||||
|
||||
if (mState != STATE_SHUTDOWN) {
|
||||
if (mState == STATE_ENDED) {
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
NS_NEW_RUNNABLE_METHOD(nsWaveDecoder, mDecoder, PlaybackEnded);
|
||||
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
while (mState != STATE_SHUTDOWN) {
|
||||
monitor.Wait();
|
||||
do {
|
||||
monitor.Wait();
|
||||
} while (mState == STATE_ENDED);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -823,6 +836,9 @@ IsValidStateTransition(State aStartState, State aEndState)
|
|||
return PR_TRUE;
|
||||
break;
|
||||
case STATE_ENDED:
|
||||
if (aEndState == STATE_SEEKING)
|
||||
return PR_TRUE;
|
||||
/* fallthrough */
|
||||
case STATE_ERROR:
|
||||
case STATE_SHUTDOWN:
|
||||
break;
|
||||
|
@ -1428,6 +1444,10 @@ nsWaveDecoder::PlaybackEnded()
|
|||
return;
|
||||
}
|
||||
|
||||
if (!mPlaybackStateMachine->IsEnded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Stop();
|
||||
if (mElement) {
|
||||
mElement->PlaybackEnded();
|
||||
|
|
Загрузка…
Ссылка в новой задаче