| Index: Source/core/html/HTMLMediaElement.cpp
|
| diff --git a/Source/core/html/HTMLMediaElement.cpp b/Source/core/html/HTMLMediaElement.cpp
|
| index 7b44dceddd57cf80b13fa6e549962093e87bb1bd..3b5c903ee3321c7fec65d2beac61a7b3951eb168 100644
|
| --- a/Source/core/html/HTMLMediaElement.cpp
|
| +++ b/Source/core/html/HTMLMediaElement.cpp
|
| @@ -247,6 +247,8 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum
|
| , m_lastTimeUpdateEventWallTime(0)
|
| , m_lastTimeUpdateEventMovieTime(std::numeric_limits<double>::max())
|
| , m_loadState(WaitingForSource)
|
| + , m_deferredLoadState(NotDeferred)
|
| + , m_deferredLoadTimer(this, &HTMLMediaElement::deferredLoadTimerFired)
|
| , m_webLayer(0)
|
| , m_preload(MediaPlayer::Auto)
|
| , m_displayMode(Unknown)
|
| @@ -271,7 +273,6 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum
|
| , m_closedCaptionsVisible(false)
|
| , m_completelyLoaded(false)
|
| , m_havePreparedToPlay(false)
|
| - , m_delayingLoadForPreloadNone(false)
|
| , m_tracksAreReady(true)
|
| , m_haveVisibleTextTrack(false)
|
| , m_processingPreferenceChange(false)
|
| @@ -641,6 +642,7 @@ void HTMLMediaElement::prepareForLoad()
|
| // Perform the cleanup required for the resource load algorithm to run.
|
| stopPeriodicTimers();
|
| m_loadTimer.stop();
|
| + cancelDeferredLoad();
|
| // FIXME: Figure out appropriate place to reset LoadTextTrackResource if necessary and set m_pendingActionFlags to 0 here.
|
| m_pendingActionFlags &= ~LoadMediaResource;
|
| m_sentEndEvent = false;
|
| @@ -896,7 +898,7 @@ void HTMLMediaElement::loadResource(const KURL& url, ContentType& contentType, c
|
|
|
| if (!m_havePreparedToPlay && !autoplay() && m_preload == MediaPlayer::None) {
|
| WTF_LOG(Media, "HTMLMediaElement::loadResource : Delaying load because preload == 'none'");
|
| - m_delayingLoadForPreloadNone = true;
|
| + deferLoad();
|
| } else {
|
| startPlayerLoad();
|
| }
|
| @@ -940,19 +942,79 @@ void HTMLMediaElement::setPlayerPreload()
|
| {
|
| m_player->setPreload(m_preload);
|
|
|
| - if (m_delayingLoadForPreloadNone && m_preload != MediaPlayer::None)
|
| - startDelayedLoad();
|
| + if (loadIsDeferred() && m_preload != MediaPlayer::None)
|
| + startDeferredLoad();
|
| }
|
|
|
| -void HTMLMediaElement::startDelayedLoad()
|
| +bool HTMLMediaElement::loadIsDeferred() const
|
| {
|
| - ASSERT(m_delayingLoadForPreloadNone);
|
| + return m_deferredLoadState != NotDeferred;
|
| +}
|
| +
|
| +void HTMLMediaElement::deferLoad()
|
| +{
|
| + // This implements the "optional" step 3 from the resource fetch algorithm.
|
| + ASSERT(!m_deferredLoadTimer.isActive());
|
| + ASSERT(m_deferredLoadState == NotDeferred);
|
| + // 1. Set the networkState to NETWORK_IDLE.
|
| + // 2. Queue a task to fire a simple event named suspend at the element.
|
| + changeNetworkStateFromLoadingToIdle();
|
| + // 3. Queue a task to set the element's delaying-the-load-event
|
| + // flag to false. This stops delaying the load event.
|
| + m_deferredLoadTimer.startOneShot(0, FROM_HERE);
|
| + // 4. Wait for the task to be run.
|
| + m_deferredLoadState = WaitingForStopDelayingLoadEventTask;
|
| + // Continued in executeDeferredLoad().
|
| +}
|
| +
|
| +void HTMLMediaElement::cancelDeferredLoad()
|
| +{
|
| + m_deferredLoadTimer.stop();
|
| + m_deferredLoadState = NotDeferred;
|
| +}
|
|
|
| - m_delayingLoadForPreloadNone = false;
|
| +void HTMLMediaElement::executeDeferredLoad()
|
| +{
|
| + ASSERT(m_deferredLoadState >= WaitingForTrigger);
|
| +
|
| + // resource fetch algorithm step 3 - continued from deferLoad().
|
| +
|
| + // 5. Wait for an implementation-defined event (e.g. the user requesting that the media element begin playback).
|
| + // This is assumed to be whatever 'event' ended up calling this method.
|
| + cancelDeferredLoad();
|
| + // 6. Set the element's delaying-the-load-event flag back to true (this
|
| + // delays the load event again, in case it hasn't been fired yet).
|
| + setShouldDelayLoadEvent(true);
|
| + // 7. Set the networkState to NETWORK_LOADING.
|
| + m_networkState = NETWORK_LOADING;
|
| +
|
| + startProgressEventTimer();
|
|
|
| startPlayerLoad();
|
| }
|
|
|
| +void HTMLMediaElement::startDeferredLoad()
|
| +{
|
| + if (m_deferredLoadState == WaitingForTrigger) {
|
| + executeDeferredLoad();
|
| + return;
|
| + }
|
| + ASSERT(m_deferredLoadState == WaitingForStopDelayingLoadEventTask);
|
| + m_deferredLoadState = ExecuteOnStopDelayingLoadEventTask;
|
| +}
|
| +
|
| +void HTMLMediaElement::deferredLoadTimerFired(Timer<HTMLMediaElement>*)
|
| +{
|
| + setShouldDelayLoadEvent(false);
|
| +
|
| + if (m_deferredLoadState == ExecuteOnStopDelayingLoadEventTask) {
|
| + executeDeferredLoad();
|
| + return;
|
| + }
|
| + ASSERT(m_deferredLoadState == WaitingForStopDelayingLoadEventTask);
|
| + m_deferredLoadState = WaitingForTrigger;
|
| +}
|
| +
|
| WebMediaPlayer::LoadType HTMLMediaElement::loadType() const
|
| {
|
| if (m_mediaSource)
|
| @@ -1582,11 +1644,13 @@ void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
|
|
|
| void HTMLMediaElement::changeNetworkStateFromLoadingToIdle()
|
| {
|
| + ASSERT(m_player);
|
| m_progressEventTimer.stop();
|
|
|
| // Schedule one last progress event so we guarantee that at least one is fired
|
| // for files that load very quickly.
|
| - scheduleEvent(EventTypeNames::progress);
|
| + if (m_player->didLoadingProgress())
|
| + scheduleEvent(EventTypeNames::progress);
|
| scheduleEvent(EventTypeNames::suspend);
|
| m_networkState = NETWORK_IDLE;
|
| }
|
| @@ -1750,8 +1814,8 @@ void HTMLMediaElement::prepareToPlay()
|
| return;
|
| m_havePreparedToPlay = true;
|
|
|
| - if (m_delayingLoadForPreloadNone)
|
| - startDelayedLoad();
|
| + if (loadIsDeferred())
|
| + startDeferredLoad();
|
| }
|
|
|
| void HTMLMediaElement::seek(double time, ExceptionState& exceptionState)
|
| @@ -3139,7 +3203,7 @@ void HTMLMediaElement::clearMediaPlayer(int flags)
|
|
|
| closeMediaSource();
|
|
|
| - m_delayingLoadForPreloadNone = false;
|
| + cancelDeferredLoad();
|
|
|
| #if ENABLE(WEB_AUDIO)
|
| if (m_audioSourceNode)
|
|
|