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
Родитель 592042f9c0
Коммит 97c6b9c07b
2 изменённых файлов: 76 добавлений и 6 удалений

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

@ -1103,6 +1103,10 @@ void nsOggDecodeStateMachine::Decode()
void nsOggDecodeStateMachine::Seek(float aTime)
{
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;
LOG(PR_LOG_DEBUG, ("Changed state to SEEKING (to %f)", aTime));
mState = DECODER_STATE_SEEKING;
@ -1330,17 +1334,23 @@ nsresult nsOggDecodeStateMachine::Run()
UpdatePlaybackPosition(frame->mDecodedFrameTime);
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();
nsCOMPtr<nsIRunnable> stopEvent =
NS_NEW_RUNNABLE_METHOD(nsOggDecoder, mDecoder, SeekingStopped);
NS_DispatchToMainThread(stopEvent, NS_DISPATCH_SYNC);
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;

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

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