Bug 588312 - Set video.currentTime to seek time when seek starts - r=kinetik a=blocking2.0

This commit is contained in:
Chris Double 2010-09-10 14:48:36 +12:00
Родитель b36b02f09c
Коммит e53dd0a30f
7 изменённых файлов: 110 добавлений и 82 удалений

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

@ -2027,6 +2027,7 @@ void nsHTMLMediaElement::PlaybackEnded()
void nsHTMLMediaElement::SeekStarted()
{
DispatchAsyncSimpleEvent(NS_LITERAL_STRING("seeking"));
DispatchAsyncSimpleEvent(NS_LITERAL_STRING("timeupdate"));
}
void nsHTMLMediaElement::SeekCompleted()

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

@ -1,4 +1,3 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: ML 1.1/GPL 2.0/LGPL 2.1
@ -980,6 +979,15 @@ nsresult nsBuiltinDecoderStateMachine::Run()
PRInt64 seekTime = mSeekTime;
mDecoder->StopProgressUpdates();
PRBool currentTimeChanged = false;
if (mCurrentFrameTime != seekTime - mStartTime) {
currentTimeChanged = true;
// If in the midst of a seek, report the requested seek time
// as the current time as required by step 8 of 4.8.10.9 'Seeking'
// in the WHATWG spec.
UpdatePlaybackPosition(seekTime);
}
// SeekingStarted will do a UpdateReadyStateForData which will
// inform the element and its users that we have no frames
// to display
@ -989,7 +997,7 @@ nsresult nsBuiltinDecoderStateMachine::Run()
NS_NewRunnableMethod(mDecoder, &nsBuiltinDecoder::SeekingStarted);
NS_DispatchToMainThread(startEvent, NS_DISPATCH_SYNC);
}
if (mCurrentFrameTime != mSeekTime - mStartTime) {
if (currentTimeChanged) {
// The seek target is different than the current playback position,
// we'll need to seek the playback position, so shutdown our decode
// and audio threads.

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

@ -135,6 +135,7 @@ _TEST_FILES = \
test_source.html \
test_source_write.html \
test_standalone.html \
test_timeupdate_seek.html \
test_timeupdate_small_files.html \
test_volume.html \
test_video_to_canvas.html \
@ -154,17 +155,6 @@ _TEST_FILES = \
# Disabled since we don't play Wave files standalone, for now
# test_audioDocumentTitle.html
ifdef MOZ_OGG
ifneq ($(OS_ARCH),WINNT)
# Disabled on windows until we figure out the random failures.
# When this is fixed, make it backend-independent please.
# See bug 475369 and bug 526323
_TEST_FILES += \
test_timeupdate3.html \
$(NULL)
endif
endif
# sample files
_TEST_FILES += \
320x240.ogv \

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

@ -214,7 +214,7 @@ var gAudioTests = [
{ name:"bogus.duh", type:"bogus/duh", duration:123 }
];
// These files ensure our hanlding of 404 errors is consistent across the
// These files ensure our handling of 404 errors is consistent across the
// various backends.
var g404Tests = [
{ name:"404.wav", type:"audio/x-wav" },

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

@ -1,55 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Media test: timeupdate and size</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>
<pre id="test">
<script class="testbody" type="text/javascript">
// Test if the media size during the first timeupdate is correct.
var completed = false;
var seeking = false;
function startTest() {
if (completed)
return false;
var v = document.getElementById('v');
v.currentTime=2.0;
return false;
}
function startSeek() {
if (completed)
return false;
seeking = true;
return false;
}
function timeUpdated() {
if (completed || !seeking)
return false;
var v = document.getElementById('v');
ok(v.currentTime >= 1.8 && v.currentTime <= 2.2,
"Check currentTime of " + v.currentTime + " is within range in timeupdate after seek");
completed = true;
v.pause();
SimpleTest.finish();
return false;
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
<video id='v'
src='seek.ogv'
onloadedmetadata='return startTest();'
onseeking='return startSeek();'
ontimeupdate='return timeUpdated();'></video>
</body>
</html>

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

@ -0,0 +1,80 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Media test: timeupdate and seek</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" />
<script type="text/javascript" src="manifest.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
// Test if the currentTime when a seek is requested is set to
// the requested seek time as per 4.8.10.9 'seeking' in the
// WHATWG spec.
//
// http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#seeking
var manager = new MediaTestManager;
function do_loadedmetadata(e) {
var v = e.target;
if (e._finished)
return false;
v._seekTime = Math.round(v.duration / 2);
v.currentTime=v._seekTime;
return false;
}
function do_seeking(e) {
var v = e.target;
if (v._finished)
return false;
v._seeking = true;
ok(v.currentTime == v._seekTime,
"Check currentTime of " + v.currentTime +
" is requested seek time of " + v._seekTime +
" in " + v._name);
return false;
}
function do_timeupdate(e) {
var v = e.target;
if (v._finished)
return false;
ok(v.currentTime == v._seekTime,
"Check currentTime of " + v.currentTime +
" is requested seek time of " + v._seekTime +
" in " + v._name);
v._finished= true;
v.pause();
v.parentNode.removeChild(v);
manager.finished(v.token);
return false;
}
function startTest(test, token) {
var type = /^video/.test(test.type) ? "video" : "audio";
var v = document.createElement(type);
v.token = token;
manager.started(token);
v.src = test.name;
v._name = test.name;
v._seeking = false;
v._finished = false;
v.addEventListener("loadedmetadata", do_loadedmetadata, false);
v.addEventListener("seeking", do_seeking, false);
v.addEventListener("timeupdate", do_timeupdate, false);
document.body.appendChild(v);
}
manager.runTests(gSeekTests, startTest);
</script>
</pre>
</body>
</html>

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

@ -702,6 +702,20 @@ nsWaveStateMachine::Run()
mSeekTime = NS_MIN(mSeekTime, GetDuration());
float seekTime = mSeekTime;
// Calculate relative offset within PCM data.
PRInt64 position = RoundDownToSample(TimeToBytes(seekTime));
NS_ABORT_IF_FALSE(position >= 0 && position <= GetDataLength(),
"Invalid seek position");
// Convert to absolute offset within stream.
position += mWavePCMOffset;
// If in the midst of a seek, report the requested seek time
// as the current time as required by step 8 of 4.8.10.9 'Seeking'
// in the WHATWG spec.
PRInt64 oldPosition = mPlaybackPosition;
mPlaybackPosition = position;
FirePositionChanged(PR_TRUE);
monitor.Exit();
nsCOMPtr<nsIRunnable> startEvent =
NS_NewRunnableMethod(mDecoder, &nsWaveDecoder::SeekingStarted);
@ -712,22 +726,14 @@ nsWaveStateMachine::Run()
break;
}
// Calculate relative offset within PCM data.
PRInt64 position = RoundDownToSample(TimeToBytes(seekTime));
NS_ABORT_IF_FALSE(position >= 0 && position <= GetDataLength(),
"Invalid seek position");
// Convert to absolute offset within stream.
position += mWavePCMOffset;
monitor.Exit();
nsresult rv;
rv = mStream->Seek(nsISeekableStream::NS_SEEK_SET, position);
monitor.Enter();
if (NS_FAILED(rv)) {
NS_WARNING("Seek failed");
}
monitor.Enter();
if (NS_SUCCEEDED(rv)) {
mPlaybackPosition = position;
mPlaybackPosition = oldPosition;
FirePositionChanged(PR_TRUE);
}
if (mState == STATE_SHUTDOWN) {
@ -758,8 +764,6 @@ nsWaveStateMachine::Run()
ChangeState(nextState);
}
FirePositionChanged(PR_TRUE);
monitor.Exit();
nsCOMPtr<nsIRunnable> stopEvent =
NS_NewRunnableMethod(mDecoder, &nsWaveDecoder::SeekingStopped);