Bug 476973. Don't get confused by repeated seeks in the Ogg decoder. r=doublec

This commit is contained in:
Robert O'Callahan 2009-05-18 10:03:03 +12:00
parent 4b1e16bc03
commit c2bc1f2907
2 changed files with 76 additions and 6 deletions

View File

@ -1103,6 +1103,10 @@ void nsOggDecodeStateMachine::Decode()
void nsOggDecodeStateMachine::Seek(float aTime) void nsOggDecodeStateMachine::Seek(float aTime)
{ {
nsAutoMonitor mon(mDecoder->GetMonitor()); nsAutoMonitor mon(mDecoder->GetMonitor());
// nsOggDecoder::mPlayState should be SEEKING while we seek, and
// in that case nsOggDecoder shouldn't be calling us.
NS_ASSERTION(mState != DECODER_STATE_SEEKING,
"We shouldn't already be seeking");
mSeekTime = aTime; mSeekTime = aTime;
LOG(PR_LOG_DEBUG, ("Changed state to SEEKING (to %f)", aTime)); LOG(PR_LOG_DEBUG, ("Changed state to SEEKING (to %f)", aTime));
mState = DECODER_STATE_SEEKING; mState = DECODER_STATE_SEEKING;
@ -1330,17 +1334,23 @@ nsresult nsOggDecodeStateMachine::Run()
UpdatePlaybackPosition(frame->mDecodedFrameTime); UpdatePlaybackPosition(frame->mDecodedFrameTime);
PlayVideo(frame); PlayVideo(frame);
} }
// Change state to DECODING now. SeekingStopped will call
// nsOggDecodeStateMachine::Seek to reset our state to SEEKING
// if we need to seek again.
LOG(PR_LOG_DEBUG, ("Changed state from SEEKING (to %f) to DECODING", seekTime));
// mSeekTime should not have changed. While we seek, mPlayState
// should always be PLAY_STATE_SEEKING and no-one will call
// nsOggDecoderStateMachine::Seek.
NS_ASSERTION(seekTime == mSeekTime, "No-one should have changed mSeekTime");
mState = DECODER_STATE_DECODING;
mon.NotifyAll();
mon.Exit(); mon.Exit();
nsCOMPtr<nsIRunnable> stopEvent = nsCOMPtr<nsIRunnable> stopEvent =
NS_NEW_RUNNABLE_METHOD(nsOggDecoder, mDecoder, SeekingStopped); NS_NEW_RUNNABLE_METHOD(nsOggDecoder, mDecoder, SeekingStopped);
NS_DispatchToMainThread(stopEvent, NS_DISPATCH_SYNC); NS_DispatchToMainThread(stopEvent, NS_DISPATCH_SYNC);
mon.Enter(); mon.Enter();
if (mState == DECODER_STATE_SEEKING && mSeekTime == seekTime) {
LOG(PR_LOG_DEBUG, ("Changed state from SEEKING (to %f) to DECODING", seekTime));
mState = DECODER_STATE_DECODING;
mon.NotifyAll();
}
} }
break; break;

View File

@ -0,0 +1,60 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=476973
-->
<head>
<title>Bug 476973 - multiple seeks to the same position shouldn't cause problems</title>
<script type="text/javascript" src="/MochiKit/packed.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=476973">Mozilla Bug 476973</a>
<pre id="test">
<script class="testbody" type="text/javascript">
var v;
var completed = false;
var seekedNonZero = false;
/* This test checkes that two seeks to the same position don't break things.
So we trigger two seeks to 1.0, trigger another when seeking starts,
and when we've seeked successfully to 1.0, we seek back to zero and expect
that to eventually happen.
*/
function start() {
v = document.getElementById('v');
v.currentTime = 1.0;
v.currentTime = 1.0;
}
function startSeeking() {
if (!seekedNonZero) {
v.currentTime = 1.0;
}
}
function seeked() {
if (completed)
return;
if (v.currentTime > 0) {
ok(v.currentTime > 0.9 && v.currentTime < 1.1, "Seek to wrong destination " + v.currentTime);
seekedNonZero = true;
v.currentTime = 0.0;
} else {
ok(seekedNonZero, "Successfully seeked to nonzero");
ok(true, "Seek back to zero was successful");
completed = true;
SimpleTest.finish();
}
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
<video id='v' src='seek.ogv' onseeked='seeked()' onseeking='startSeeking()'
onloadeddata='start()'></video>
</body>
</html>