| Index: third_party/WebKit/WebCore/html/HTMLMediaElement.cpp | 
| =================================================================== | 
| --- third_party/WebKit/WebCore/html/HTMLMediaElement.cpp	(revision 11154) | 
| +++ third_party/WebKit/WebCore/html/HTMLMediaElement.cpp	(working copy) | 
| @@ -76,7 +76,6 @@ | 
| , m_begun(false) | 
| , m_loadedFirstFrame(false) | 
| , m_autoplaying(true) | 
| -    , m_currentLoop(0) | 
| , m_volume(1.0f) | 
| , m_muted(false) | 
| , m_paused(true) | 
| @@ -85,7 +84,6 @@ | 
| , m_previousProgress(0) | 
| , m_previousProgressTime(numeric_limits<double>::max()) | 
| , m_sentStalledEvent(false) | 
| -    , m_bufferingRate(0) | 
| , m_loadNestingLevel(0) | 
| , m_terminateLoadBelowNestingLevel(0) | 
| , m_pausedInternal(false) | 
| @@ -299,14 +297,6 @@ | 
| return m_networkState; | 
| } | 
|  | 
| -float HTMLMediaElement::bufferingRate() | 
| -{ | 
| -    if (!m_player) | 
| -        return 0; | 
| -    return m_bufferingRate; | 
| -    //return m_player->dataRate(); | 
| -} | 
| - | 
| String HTMLMediaElement::canPlayType(const String& mimeType) const | 
| { | 
| MediaPlayer::SupportsType support = MediaPlayer::supportsType(ContentType(mimeType)); | 
| @@ -352,7 +342,6 @@ | 
|  | 
| m_progressEventTimer.stop(); | 
| m_sentStalledEvent = false; | 
| -    m_bufferingRate = 0; | 
|  | 
| m_loadTimer.stop(); | 
|  | 
| @@ -384,7 +373,6 @@ | 
| m_player->pause(); | 
| m_player->seek(0); | 
| } | 
| -        m_currentLoop = 0; | 
| dispatchEventForType(eventNames().emptiedEvent, false, true); | 
| if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) | 
| goto end; | 
| @@ -471,7 +459,6 @@ | 
| m_error = MediaError::create(MediaError::MEDIA_ERR_NETWORK); | 
| m_begun = false; | 
| m_progressEventTimer.stop(); | 
| -        m_bufferingRate = 0; | 
|  | 
| initAndDispatchProgressEvent(eventNames().errorEvent); | 
| if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) | 
| @@ -490,7 +477,6 @@ | 
| m_networkState = LOADING; | 
|  | 
| if (state >= MediaPlayer::LoadedMetaData && m_networkState < LOADED_METADATA) { | 
| -        m_player->seek(effectiveStart()); | 
| m_networkState = LOADED_METADATA; | 
|  | 
| dispatchEventForType(eventNames().durationchangeEvent, false, true); | 
| @@ -535,7 +521,6 @@ | 
| m_begun = false; | 
| m_networkState = LOADED; | 
| m_progressEventTimer.stop(); | 
| -        m_bufferingRate = 0; | 
| initAndDispatchProgressEvent(eventNames().loadEvent); | 
| } | 
| } | 
| @@ -596,12 +581,9 @@ | 
| unsigned progress = m_player->bytesLoaded(); | 
| double time = WTF::currentTime(); | 
| double timedelta = time - m_previousProgressTime; | 
| -    if (timedelta) | 
| -        m_bufferingRate = (float)(0.8 * m_bufferingRate + 0.2 * ((float)(progress - m_previousProgress)) / timedelta); | 
|  | 
| if (progress == m_previousProgress) { | 
| if (timedelta > 3.0 && !m_sentStalledEvent) { | 
| -            m_bufferingRate = 0; | 
| initAndDispatchProgressEvent(eventNames().stalledEvent); | 
| m_sentStalledEvent = true; | 
| } | 
| @@ -621,23 +603,10 @@ | 
| ec = INVALID_STATE_ERR; | 
| return; | 
| } | 
| + | 
| +    time = min(time, duration()); | 
| +    time = max(time, 0.0f); | 
|  | 
| -    // 2 | 
| -    float minTime; | 
| -    if (currentLoop() == 0) | 
| -        minTime = effectiveStart(); | 
| -    else | 
| -        minTime = effectiveLoopStart(); | 
| - | 
| -    // 3 | 
| -    float maxTime = currentLoop() == playCount() - 1 ? effectiveEnd() : effectiveLoopEnd(); | 
| - | 
| -    // 4 | 
| -    time = min(time, maxTime); | 
| - | 
| -    // 5 | 
| -    time = max(time, minTime); | 
| - | 
| // 6 | 
| RefPtr<TimeRanges> seekableRanges = seekable(); | 
| if (!seekableRanges->contain(time)) { | 
| @@ -657,10 +626,8 @@ | 
| // 10 | 
| // As soon as the user agent has established whether or not the media data for the new playback position is available, | 
| // and, if it is, decoded enough data to play back that position, the seeking DOM attribute must be set to false. | 
| -    if (m_player) { | 
| -        m_player->setEndTime(maxTime); | 
| +    if (m_player) | 
| m_player->seek(time); | 
| -    } | 
| } | 
|  | 
| HTMLMediaElement::ReadyState HTMLMediaElement::readyState() const | 
| @@ -768,8 +735,7 @@ | 
| } | 
| ExceptionCode unused; | 
| if (endedPlayback()) { | 
| -        m_currentLoop = 0; | 
| -        seek(effectiveStart(), unused); | 
| +        seek(0, unused); | 
| } | 
| setPlaybackRate(defaultPlaybackRate(), unused); | 
|  | 
| @@ -815,77 +781,16 @@ | 
| updatePlayState(); | 
| } | 
|  | 
| -unsigned HTMLMediaElement::playCount() const | 
| +bool HTMLMediaElement::loop() const | 
| { | 
| -    bool ok; | 
| -    unsigned count = getAttribute(playcountAttr).string().toUInt(&ok); | 
| -    return (count > 0 && ok) ? count : 1; | 
| +    return hasAttribute(loopAttr); | 
| } | 
|  | 
| -void HTMLMediaElement::setPlayCount(unsigned count, ExceptionCode& ec) | 
| +void HTMLMediaElement::setLoop(bool b) | 
| { | 
| -    if (!count) { | 
| -        ec = INDEX_SIZE_ERR; | 
| -        return; | 
| -    } | 
| -    setAttribute(playcountAttr, String::number(count)); | 
| -    checkIfSeekNeeded(); | 
| +    setBooleanAttribute(loopAttr, b); | 
| } | 
|  | 
| -float HTMLMediaElement::start() const | 
| -{ | 
| -    return getTimeOffsetAttribute(startAttr, 0); | 
| -} | 
| - | 
| -void HTMLMediaElement::setStart(float time) | 
| -{ | 
| -    setTimeOffsetAttribute(startAttr, time); | 
| -    checkIfSeekNeeded(); | 
| -} | 
| - | 
| -float HTMLMediaElement::end() const | 
| -{ | 
| -    return getTimeOffsetAttribute(endAttr, std::numeric_limits<float>::infinity()); | 
| -} | 
| - | 
| -void HTMLMediaElement::setEnd(float time) | 
| -{ | 
| -    setTimeOffsetAttribute(endAttr, time); | 
| -    checkIfSeekNeeded(); | 
| -} | 
| - | 
| -float HTMLMediaElement::loopStart() const | 
| -{ | 
| -    return getTimeOffsetAttribute(loopstartAttr, start()); | 
| -} | 
| - | 
| -void HTMLMediaElement::setLoopStart(float time) | 
| -{ | 
| -    setTimeOffsetAttribute(loopstartAttr, time); | 
| -    checkIfSeekNeeded(); | 
| -} | 
| - | 
| -float HTMLMediaElement::loopEnd() const | 
| -{ | 
| -    return getTimeOffsetAttribute(loopendAttr, end()); | 
| -} | 
| - | 
| -void HTMLMediaElement::setLoopEnd(float time) | 
| -{ | 
| -    setTimeOffsetAttribute(loopendAttr, time); | 
| -    checkIfSeekNeeded(); | 
| -} | 
| - | 
| -unsigned HTMLMediaElement::currentLoop() const | 
| -{ | 
| -    return m_currentLoop; | 
| -} | 
| - | 
| -void HTMLMediaElement::setCurrentLoop(unsigned currentLoop) | 
| -{ | 
| -    m_currentLoop = currentLoop; | 
| -} | 
| - | 
| bool HTMLMediaElement::controls() const | 
| { | 
| Frame* frame = document()->frame(); | 
| @@ -1008,40 +913,6 @@ | 
| return mediaSrc; | 
| } | 
|  | 
| -void HTMLMediaElement::checkIfSeekNeeded() | 
| -{ | 
| -    // 3.14.9.5. Offsets into the media resource | 
| -    // 1 | 
| -    if (playCount() <= m_currentLoop) | 
| -        m_currentLoop = playCount() - 1; | 
| - | 
| -    // 2 | 
| -    if (networkState() <= LOADING) | 
| -        return; | 
| - | 
| -    // 3 | 
| -    ExceptionCode ec; | 
| -    float time = currentTime(); | 
| -    if (!m_currentLoop && time < effectiveStart()) | 
| -        seek(effectiveStart(), ec); | 
| - | 
| -    // 4 | 
| -    if (m_currentLoop && time < effectiveLoopStart()) | 
| -        seek(effectiveLoopStart(), ec); | 
| - | 
| -    // 5 | 
| -    if (m_currentLoop < playCount() - 1 && time > effectiveLoopEnd()) { | 
| -        seek(effectiveLoopStart(), ec); | 
| -        m_currentLoop++; | 
| -    } | 
| - | 
| -    // 6 | 
| -    if (m_currentLoop == playCount() - 1 && time > effectiveEnd()) | 
| -        seek(effectiveEnd(), ec); | 
| - | 
| -    updatePlayState(); | 
| -} | 
| - | 
| void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*) | 
| { | 
| beginProcessingMediaPlayerCallback(); | 
| @@ -1050,17 +921,16 @@ | 
| m_seeking = false; | 
|  | 
| float now = currentTime(); | 
| -    if (m_currentLoop < playCount() - 1 && now >= effectiveLoopEnd()) { | 
| -        ExceptionCode ec; | 
| -        seek(effectiveLoopStart(), ec); | 
| -        m_currentLoop++; | 
| -        dispatchEventForType(eventNames().timeupdateEvent, false, true); | 
| +    if (now >= duration()) { | 
| +        if (loop()) { | 
| +            ExceptionCode ec; | 
| +            seek(0, ec); | 
| +            dispatchEventForType(eventNames().timeupdateEvent, false, true); | 
| +        } else { | 
| +            dispatchEventForType(eventNames().timeupdateEvent, false, true); | 
| +            dispatchEventForType(eventNames().endedEvent, false, true); | 
| +        } | 
| } | 
| - | 
| -    if (m_currentLoop == playCount() - 1 && now >= effectiveEnd()) { | 
| -        dispatchEventForType(eventNames().timeupdateEvent, false, true); | 
| -        dispatchEventForType(eventNames().endedEvent, false, true); | 
| -    } | 
|  | 
| updatePlayState(); | 
|  | 
| @@ -1104,34 +974,6 @@ | 
| return TimeRanges::create(0, m_player->maxTimeSeekable()); | 
| } | 
|  | 
| -float HTMLMediaElement::effectiveStart() const | 
| -{ | 
| -    if (!m_player) | 
| -        return 0; | 
| -    return min(start(), m_player->duration()); | 
| -} | 
| - | 
| -float HTMLMediaElement::effectiveEnd() const | 
| -{ | 
| -    if (!m_player) | 
| -        return 0; | 
| -    return min(max(end(), max(start(), loopStart())), m_player->duration()); | 
| -} | 
| - | 
| -float HTMLMediaElement::effectiveLoopStart() const | 
| -{ | 
| -    if (!m_player) | 
| -        return 0; | 
| -    return min(loopStart(), m_player->duration()); | 
| -} | 
| - | 
| -float HTMLMediaElement::effectiveLoopEnd() const | 
| -{ | 
| -    if (!m_player) | 
| -        return 0; | 
| -    return min(max(start(), max(loopStart(), loopEnd())), m_player->duration()); | 
| -} | 
| - | 
| bool HTMLMediaElement::activelyPlaying() const | 
| { | 
| return !paused() && readyState() >= CAN_PLAY && !endedPlayback(); // && !stoppedDueToErrors() && !pausedForUserInteraction(); | 
| @@ -1139,7 +981,7 @@ | 
|  | 
| bool HTMLMediaElement::endedPlayback() const | 
| { | 
| -    return networkState() >= LOADED_METADATA && currentTime() >= effectiveEnd() && currentLoop() == playCount() - 1; | 
| +    return networkState() >= LOADED_METADATA && currentTime() >= duration() && !loop(); | 
| } | 
|  | 
| void HTMLMediaElement::updateVolume() | 
| @@ -1170,9 +1012,7 @@ | 
| return; | 
| } | 
|  | 
| -    m_player->setEndTime(currentLoop() == playCount() - 1 ? effectiveEnd() : effectiveLoopEnd()); | 
| - | 
| -    bool shouldBePlaying = activelyPlaying() && currentTime() < effectiveEnd(); | 
| +    bool shouldBePlaying = activelyPlaying(); | 
| if (shouldBePlaying && m_player->paused()) | 
| m_player->play(); | 
| else if (!shouldBePlaying && !m_player->paused()) | 
|  |