Index: Source/core/html/HTMLMediaElement.cpp |
diff --git a/Source/core/html/HTMLMediaElement.cpp b/Source/core/html/HTMLMediaElement.cpp |
index 2a8bc6b446321e6740ccabdf0c2f7afa8509fcaa..297200ac63334d0e5ee4d36028048b6a16e59a94 100644 |
--- a/Source/core/html/HTMLMediaElement.cpp |
+++ b/Source/core/html/HTMLMediaElement.cpp |
@@ -324,6 +324,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum |
, m_duration(std::numeric_limits<double>::quiet_NaN()) |
, m_lastTimeUpdateEventWallTime(0) |
, m_lastTimeUpdateEventMovieTime(std::numeric_limits<double>::max()) |
+ , m_defaultPlaybackStartPosition(0) |
, m_loadState(WaitingForSource) |
, m_deferredLoadState(NotDeferred) |
, m_deferredLoadTimer(this, &HTMLMediaElement::deferredLoadTimerFired) |
@@ -1817,6 +1818,11 @@ void HTMLMediaElement::setReadyState(ReadyState state) |
if (isHTMLVideoElement()) |
scheduleEvent(EventTypeNames::resize); |
scheduleEvent(EventTypeNames::loadedmetadata); |
+ |
+ if (m_defaultPlaybackStartPosition > 0) |
+ seek(m_defaultPlaybackStartPosition); |
+ |
+ m_defaultPlaybackStartPosition = 0; |
if (hasMediaControls()) |
mediaControls()->reset(); |
if (renderer()) |
@@ -1917,17 +1923,13 @@ void HTMLMediaElement::prepareToPlay() |
startDeferredLoad(); |
} |
-void HTMLMediaElement::seek(double time, ExceptionState& exceptionState) |
+void HTMLMediaElement::seek(double time) |
{ |
WTF_LOG(Media, "HTMLMediaElement::seek(%p, %f)", this, time); |
- // 4.8.10.9 Seeking |
- |
- // 1 - If the media element's readyState is HAVE_NOTHING, then raise an InvalidStateError exception. |
- if (m_readyState == HAVE_NOTHING) { |
- exceptionState.throwDOMException(InvalidStateError, "The element's readyState is HAVE_NOTHING."); |
+ // 2 - If the media element's readyState is HAVE_NOTHING, abort these steps. |
+ if (m_readyState == HAVE_NOTHING) |
return; |
- } |
// If the media engine has been told to postpone loading data, let it go ahead now. |
if (m_preload < MediaPlayer::Auto && m_readyState < HAVE_FUTURE_DATA) |
@@ -1935,23 +1937,24 @@ void HTMLMediaElement::seek(double time, ExceptionState& exceptionState) |
// Get the current time before setting m_seeking, m_lastSeekTime is returned once it is set. |
refreshCachedTime(); |
- double now = currentTime(); |
+ // This is needed to avoid getting default playback start position from currentTime(). |
+ double now = m_cachedTime; |
- // 2 - If the element's seeking IDL attribute is true, then another instance of this algorithm is |
+ // 3 - If the element's seeking IDL attribute is true, then another instance of this algorithm is |
// already running. Abort that other instance of the algorithm without waiting for the step that |
// it is running to complete. |
// Nothing specific to be done here. |
- // 3 - Set the seeking IDL attribute to true. |
+ // 4 - Set the seeking IDL attribute to true. |
// The flag will be cleared when the engine tells us the time has actually changed. |
bool previousSeekStillPending = m_seeking; |
m_seeking = true; |
- // 5 - If the new playback position is later than the end of the media resource, then let it be the end |
+ // 6 - If the new playback position is later than the end of the media resource, then let it be the end |
// of the media resource instead. |
time = std::min(time, duration()); |
- // 6 - If the new playback position is less than the earliest possible position, let it be that position instead. |
+ // 7 - If the new playback position is less than the earliest possible position, let it be that position instead. |
time = std::max(time, 0.0); |
// Ask the media engine for the time value in the movie's time scale before comparing with current time. This |
@@ -1965,7 +1968,7 @@ void HTMLMediaElement::seek(double time, ExceptionState& exceptionState) |
time = mediaTime; |
} |
- // 7 - If the (possibly now changed) new playback position is not in one of the ranges given in the |
+ // 8 - If the (possibly now changed) new playback position is not in one of the ranges given in the |
// seekable attribute, then let it be the position in one of the ranges given in the seekable attribute |
// that is the nearest to the new playback position. ... If there are no ranges given in the seekable |
// attribute then set the seeking IDL attribute to false and abort these steps. |
@@ -1998,13 +2001,13 @@ void HTMLMediaElement::seek(double time, ExceptionState& exceptionState) |
m_lastSeekTime = time; |
m_sentEndEvent = false; |
- // 8 - Queue a task to fire a simple event named seeking at the element. |
+ // 10 - Queue a task to fire a simple event named seeking at the element. |
scheduleEvent(EventTypeNames::seeking); |
- // 9 - Set the current playback position to the given new playback position |
+ // 11 - Set the current playback position to the given new playback position. |
webMediaPlayer()->seek(time); |
- // 10-14 are handled, if necessary, when the engine signals a readystate change or otherwise |
+ // 14-17 are handled, if necessary, when the engine signals a readystate change or otherwise |
// satisfies seek completion and signals a time change. |
} |
@@ -2012,14 +2015,13 @@ void HTMLMediaElement::finishSeek() |
{ |
WTF_LOG(Media, "HTMLMediaElement::finishSeek(%p)", this); |
- // 4.8.10.9 Seeking completion |
- // 12 - Set the seeking IDL attribute to false. |
+ // 14 - Set the seeking IDL attribute to false. |
m_seeking = false; |
- // 13 - Queue a task to fire a simple event named timeupdate at the element. |
+ // 16 - Queue a task to fire a simple event named timeupdate at the element. |
scheduleTimeupdateEvent(false); |
- // 14 - Queue a task to fire a simple event named seeked at the element. |
+ // 17 - Queue a task to fire a simple event named seeked at the element. |
scheduleEvent(EventTypeNames::seeked); |
setDisplayMode(Video); |
@@ -2057,6 +2059,9 @@ void HTMLMediaElement::invalidateCachedTime() |
// playback state |
double HTMLMediaElement::currentTime() const |
{ |
+ if (m_defaultPlaybackStartPosition) |
+ return m_defaultPlaybackStartPosition; |
+ |
if (m_readyState == HAVE_NOTHING) |
return 0; |
@@ -2086,7 +2091,15 @@ void HTMLMediaElement::setCurrentTime(double time, ExceptionState& exceptionStat |
exceptionState.throwDOMException(InvalidStateError, "The element is slaved to a MediaController."); |
return; |
} |
- seek(time, exceptionState); |
+ |
+ // If the media element's readyState is HAVE_NOTHING, then set the default |
+ // playback start position to that time. |
+ if (m_readyState == HAVE_NOTHING) { |
+ m_defaultPlaybackStartPosition = time; |
+ return; |
+ } |
+ |
+ seek(time); |
} |
double HTMLMediaElement::duration() const |
@@ -2225,7 +2238,7 @@ void HTMLMediaElement::playInternal() |
scheduleDelayedAction(LoadMediaResource); |
if (endedPlayback()) |
- seek(0, IGNORE_EXCEPTION); |
+ seek(0); |
if (m_mediaController) |
m_mediaController->bringElementUpToSpeed(this); |
@@ -3083,7 +3096,7 @@ void HTMLMediaElement::mediaPlayerTimeChanged() |
if (loop() && !m_mediaController) { |
m_sentEndEvent = false; |
// then seek to the earliest possible position of the media resource and abort these steps. |
- seek(0, IGNORE_EXCEPTION); |
+ seek(0); |
} else { |
// If the media element does not have a current media controller, and the media element |
// has still ended playback, and the direction of playback is still forwards, and paused |
@@ -3137,7 +3150,7 @@ void HTMLMediaElement::durationChanged(double duration, bool requestSeek) |
renderer()->updateFromElement(); |
if (requestSeek) |
- seek(duration, IGNORE_EXCEPTION); |
+ seek(duration); |
} |
void HTMLMediaElement::mediaPlayerPlaybackStateChanged() |
@@ -3168,10 +3181,10 @@ void HTMLMediaElement::mediaPlayerRequestSeek(double time) |
{ |
// The player is the source of this seek request. |
if (m_mediaController) { |
- m_mediaController->setCurrentTime(time, IGNORE_EXCEPTION); |
+ m_mediaController->setCurrentTime(time); |
return; |
} |
- setCurrentTime(time, IGNORE_EXCEPTION); |
+ setCurrentTime(time, ASSERT_NO_EXCEPTION); |
} |
// MediaPlayerPresentation methods |
@@ -3870,7 +3883,7 @@ void HTMLMediaElement::applyMediaFragmentURI() |
if (m_fragmentStartTime != MediaPlayer::invalidTime()) { |
m_sentEndEvent = false; |
UseCounter::count(document(), UseCounter::HTMLMediaElementSeekToFragmentStart); |
- seek(m_fragmentStartTime, IGNORE_EXCEPTION); |
+ seek(m_fragmentStartTime); |
} |
} |