Bug 495300. Trigger 'ended' behaviour when seeking to the end of a media resource. r=doublec

This commit is contained in:
Robert O'Callahan 2009-05-31 22:02:17 +12:00
parent e6471121ea
commit 74b9d63089
4 changed files with 86 additions and 2 deletions

View File

@ -443,6 +443,10 @@ protected:
// thread. // thread.
void SeekingStopped(); void SeekingStopped();
// Seeking has stopped at the end of the resource. Inform the element on the main
// thread.
void SeekingStoppedAtEnd();
// Seeking has started. Inform the element on the main // Seeking has started. Inform the element on the main
// thread. // thread.
void SeekingStarted(); void SeekingStarted();

View File

@ -1614,6 +1614,17 @@ nsresult nsOggDecodeStateMachine::Run()
if (mState == DECODER_STATE_SHUTDOWN) { if (mState == DECODER_STATE_SHUTDOWN) {
continue; continue;
} }
// Now try to decode another frame to see if we're at the end.
do {
mon.Exit();
r = DecodeFrame();
mon.Enter();
} while (mState != DECODER_STATE_SHUTDOWN && r == E_OGGPLAY_TIMEOUT);
HandleDecodeErrors(r);
if (mState == DECODER_STATE_SHUTDOWN)
continue;
QueueDecodedFrames();
} }
// Change state to DECODING now. SeekingStopped will call // Change state to DECODING now. SeekingStopped will call
@ -1624,8 +1635,12 @@ nsresult nsOggDecodeStateMachine::Run()
mon.NotifyAll(); mon.NotifyAll();
mon.Exit(); mon.Exit();
nsCOMPtr<nsIRunnable> stopEvent = nsCOMPtr<nsIRunnable> stopEvent;
NS_NEW_RUNNABLE_METHOD(nsOggDecoder, mDecoder, SeekingStopped); if (mDecodedFrames.GetCount() > 1) {
stopEvent = NS_NEW_RUNNABLE_METHOD(nsOggDecoder, mDecoder, SeekingStopped);
} else {
stopEvent = NS_NEW_RUNNABLE_METHOD(nsOggDecoder, mDecoder, SeekingStoppedAtEnd);
}
NS_DispatchToMainThread(stopEvent, NS_DISPATCH_SYNC); NS_DispatchToMainThread(stopEvent, NS_DISPATCH_SYNC);
mon.Enter(); mon.Enter();
} }
@ -2332,6 +2347,36 @@ void nsOggDecoder::SeekingStopped()
} }
} }
// This is called when seeking stopped *and* we're at the end of the
// media.
void nsOggDecoder::SeekingStoppedAtEnd()
{
if (mShuttingDown)
return;
PRBool fireEnded = PR_FALSE;
{
nsAutoMonitor mon(mMonitor);
// An additional seek was requested while the current seek was
// in operation.
if (mRequestedSeekTime >= 0.0) {
ChangeState(PLAY_STATE_SEEKING);
} else {
ChangeState(PLAY_STATE_ENDED);
fireEnded = PR_TRUE;
}
}
if (mElement) {
UpdateReadyStateForData();
mElement->SeekCompleted();
if (fireEnded) {
mElement->PlaybackEnded();
}
}
}
void nsOggDecoder::SeekingStarted() void nsOggDecoder::SeekingStarted()
{ {
if (mShuttingDown) if (mShuttingDown)

View File

@ -73,6 +73,7 @@ _TEST_FILES += \
test_bug482461.html \ test_bug482461.html \
test_bug493187.html \ test_bug493187.html \
test_bug495145.html \ test_bug495145.html \
test_bug495300.html \
test_can_play_type_ogg.html \ test_can_play_type_ogg.html \
test_closing_connections.html \ test_closing_connections.html \
test_contentDuration1.html \ test_contentDuration1.html \

View File

@ -0,0 +1,34 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=495300
-->
<head>
<title>Bug 495300 - seeking to the end should behave as "ended"</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=495300">Mozilla Bug 495300</a>
<pre id="test">
<script class="testbody" type="text/javascript">
var v;
var completed = false;
function start(event) {
event.target.currentTime = event.target.duration + 1;
}
function didEnd(event) {
ok(true, "Got ended event");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
<video src='seek.ogv' onloadeddata='start(event)' onended='didEnd(event)' controls></video>
</body>
</html>