Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(606)

Side by Side Diff: third_party/WebKit/Source/core/html/HTMLMediaElement.cpp

Issue 2581533002: MSE: Fix logic bugs with high precision duration (Closed)
Patch Set: Feedback Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights
3 * reserved. 3 * reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 1644 matching lines...) Expand 10 before | Expand all | Expand 10 after
1655 1655
1656 selectInitialTracksIfNecessary(); 1656 selectInitialTracksIfNecessary();
1657 1657
1658 MediaFragmentURIParser fragmentParser(m_currentSrc); 1658 MediaFragmentURIParser fragmentParser(m_currentSrc);
1659 m_fragmentEndTime = fragmentParser.endTime(); 1659 m_fragmentEndTime = fragmentParser.endTime();
1660 1660
1661 // Set the current playback position and the official playback position to 1661 // Set the current playback position and the official playback position to
1662 // the earliest possible position. 1662 // the earliest possible position.
1663 setOfficialPlaybackPosition(earliestPossiblePosition()); 1663 setOfficialPlaybackPosition(earliestPossiblePosition());
1664 1664
1665 m_duration = duration(); 1665 m_duration = m_webMediaPlayer->duration();
1666 scheduleEvent(EventTypeNames::durationchange); 1666 scheduleEvent(EventTypeNames::durationchange);
1667 1667
1668 if (isHTMLVideoElement()) 1668 if (isHTMLVideoElement())
1669 scheduleEvent(EventTypeNames::resize); 1669 scheduleEvent(EventTypeNames::resize);
1670 scheduleEvent(EventTypeNames::loadedmetadata); 1670 scheduleEvent(EventTypeNames::loadedmetadata);
1671 1671
1672 bool jumped = false; 1672 bool jumped = false;
1673 if (m_defaultPlaybackStartPosition > 0) { 1673 if (m_defaultPlaybackStartPosition > 0) {
1674 seek(m_defaultPlaybackStartPosition); 1674 seek(m_defaultPlaybackStartPosition);
1675 jumped = true; 1675 jumped = true;
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
1954 } 1954 }
1955 1955
1956 double HTMLMediaElement::officialPlaybackPosition() const { 1956 double HTMLMediaElement::officialPlaybackPosition() const {
1957 // Hold updates to official playback position while paused or waiting for more 1957 // Hold updates to official playback position while paused or waiting for more
1958 // data. The underlying media player may continue to make small advances in 1958 // data. The underlying media player may continue to make small advances in
1959 // currentTime (e.g. as samples in the last rendered audio buffer are played 1959 // currentTime (e.g. as samples in the last rendered audio buffer are played
1960 // played out), but advancing currentTime while paused/waiting sends a mixed 1960 // played out), but advancing currentTime while paused/waiting sends a mixed
1961 // signal about the state of playback. 1961 // signal about the state of playback.
1962 bool waitingForData = m_readyState <= kHaveCurrentData; 1962 bool waitingForData = m_readyState <= kHaveCurrentData;
1963 if (m_officialPlaybackPositionNeedsUpdate && !m_paused && !waitingForData) { 1963 if (m_officialPlaybackPositionNeedsUpdate && !m_paused && !waitingForData) {
1964 // Internal player position may advance slightly beyond duration because 1964 setOfficialPlaybackPosition(currentPlaybackPosition());
1965 // many files use imprecise duration. Clamp official position to duration.
1966 double newPosition = std::min(duration(), currentPlaybackPosition());
1967 setOfficialPlaybackPosition(newPosition);
1968 } 1965 }
1969 1966
1970 #if LOG_OFFICIAL_TIME_STATUS 1967 #if LOG_OFFICIAL_TIME_STATUS
1971 static const double minCachedDeltaForWarning = 0.01; 1968 static const double minCachedDeltaForWarning = 0.01;
1972 double delta = 1969 double delta =
1973 std::abs(m_officialPlaybackPosition - currentPlaybackPosition()); 1970 std::abs(m_officialPlaybackPosition - currentPlaybackPosition());
1974 if (delta > minCachedDeltaForWarning) { 1971 if (delta > minCachedDeltaForWarning) {
1975 BLINK_MEDIA_LOG << "currentTime(" << (void*)this 1972 BLINK_MEDIA_LOG << "currentTime(" << (void*)this
1976 << ") - WARNING, cached time is " << delta 1973 << ") - WARNING, cached time is " << delta
1977 << "seconds off of media time when paused/waiting"; 1974 << "seconds off of media time when paused/waiting";
1978 } 1975 }
1979 #endif 1976 #endif
1980 1977
1981 return m_officialPlaybackPosition; 1978 return m_officialPlaybackPosition;
1982 } 1979 }
1983 1980
1984 void HTMLMediaElement::setOfficialPlaybackPosition(double position) const { 1981 void HTMLMediaElement::setOfficialPlaybackPosition(double position) const {
1985 #if LOG_OFFICIAL_TIME_STATUS 1982 #if LOG_OFFICIAL_TIME_STATUS
1986 BLINK_MEDIA_LOG << "setOfficialPlaybackPosition(" << (void*)this 1983 BLINK_MEDIA_LOG << "setOfficialPlaybackPosition(" << (void*)this
1987 << ") was:" << m_officialPlaybackPosition 1984 << ") was:" << m_officialPlaybackPosition
1988 << " now:" << position; 1985 << " now:" << position;
1989 #endif 1986 #endif
1990 1987
1991 m_officialPlaybackPosition = position; 1988 // Internal player position may advance slightly beyond duration because
1989 // many files use imprecise duration. Clamp official position to duration when
1990 // known. Duration may be unknown when readyState < HAVE_METADATA.
1991 m_officialPlaybackPosition =
1992 std::isnan(duration()) ? position : std::min(duration(), position);
1993
1994 if (m_officialPlaybackPosition != position) {
1995 BLINK_MEDIA_LOG << "setOfficialPlaybackPosition(" << (void*)this
1996 << ") position:" << position
1997 << " truncated to duration:" << m_officialPlaybackPosition;
1998 }
1992 1999
1993 // Once set, official playback position should hold steady until the next 2000 // Once set, official playback position should hold steady until the next
1994 // stable state. We approximate this by using a microtask to mark the 2001 // stable state. We approximate this by using a microtask to mark the
1995 // need for an update after the current (micro)task has completed. When 2002 // need for an update after the current (micro)task has completed. When
1996 // needed, the update is applied in the next call to 2003 // needed, the update is applied in the next call to
1997 // officialPlaybackPosition(). 2004 // officialPlaybackPosition().
1998 m_officialPlaybackPositionNeedsUpdate = false; 2005 m_officialPlaybackPositionNeedsUpdate = false;
1999 Microtask::enqueueMicrotask( 2006 Microtask::enqueueMicrotask(
2000 WTF::bind(&HTMLMediaElement::requireOfficialPlaybackPositionUpdate, 2007 WTF::bind(&HTMLMediaElement::requireOfficialPlaybackPositionUpdate,
2001 wrapWeakPersistent(this))); 2008 wrapWeakPersistent(this)));
(...skipping 21 matching lines...) Expand all
2023 // playback start position to that time. 2030 // playback start position to that time.
2024 if (m_readyState == kHaveNothing) { 2031 if (m_readyState == kHaveNothing) {
2025 m_defaultPlaybackStartPosition = time; 2032 m_defaultPlaybackStartPosition = time;
2026 return; 2033 return;
2027 } 2034 }
2028 2035
2029 seek(time); 2036 seek(time);
2030 } 2037 }
2031 2038
2032 double HTMLMediaElement::duration() const { 2039 double HTMLMediaElement::duration() const {
2033 // FIXME: remove m_webMediaPlayer check once we figure out how 2040 return m_duration;
2034 // m_webMediaPlayer is going out of sync with readystate.
2035 // m_webMediaPlayer is cleared but readystate is not set to kHaveNothing.
2036 if (!m_webMediaPlayer || m_readyState < kHaveMetadata)
2037 return std::numeric_limits<double>::quiet_NaN();
2038
2039 // FIXME: Refactor so m_duration is kept current (in both MSE and
2040 // non-MSE cases) once we have transitioned from kHaveNothing ->
2041 // kHaveMetadata. Currently, m_duration may be out of date for at least MSE
2042 // case because MediaSource and SourceBuffer do not notify the element
2043 // directly upon duration changes caused by endOfStream, remove, or append
2044 // operations; rather the notification is triggered by the WebMediaPlayer
2045 // implementation observing that the underlying engine has updated duration
2046 // and notifying the element to consult its MediaSource for current
2047 // duration. See http://crbug.com/266644
2048
2049 if (m_mediaSource)
2050 return m_mediaSource->duration();
2051
2052 return webMediaPlayer()->duration();
2053 } 2041 }
2054 2042
2055 bool HTMLMediaElement::paused() const { 2043 bool HTMLMediaElement::paused() const {
2056 return m_paused; 2044 return m_paused;
2057 } 2045 }
2058 2046
2059 double HTMLMediaElement::defaultPlaybackRate() const { 2047 double HTMLMediaElement::defaultPlaybackRate() const {
2060 return m_defaultPlaybackRate; 2048 return m_defaultPlaybackRate;
2061 } 2049 }
2062 2050
(...skipping 1000 matching lines...) Expand 10 before | Expand all | Expand 10 after
3063 } 3051 }
3064 // Queue a task to fire a simple event named ended at the media element. 3052 // Queue a task to fire a simple event named ended at the media element.
3065 scheduleEvent(EventTypeNames::ended); 3053 scheduleEvent(EventTypeNames::ended);
3066 } 3054 }
3067 } 3055 }
3068 updatePlayState(); 3056 updatePlayState();
3069 } 3057 }
3070 3058
3071 void HTMLMediaElement::durationChanged() { 3059 void HTMLMediaElement::durationChanged() {
3072 BLINK_MEDIA_LOG << "durationChanged(" << (void*)this << ")"; 3060 BLINK_MEDIA_LOG << "durationChanged(" << (void*)this << ")";
3061
3062 // durationChanged() is triggered by media player.
3063 CHECK(m_webMediaPlayer);
3064 double newDuration = m_webMediaPlayer->duration();
3065
3073 // If the duration is changed such that the *current playback position* ends 3066 // If the duration is changed such that the *current playback position* ends
3074 // up being greater than the time of the end of the media resource, then the 3067 // up being greater than the time of the end of the media resource, then the
3075 // user agent must also seek to the time of the end of the media resource. 3068 // user agent must also seek to the time of the end of the media resource.
3076 durationChanged(duration(), currentPlaybackPosition() > duration()); 3069 durationChanged(newDuration, currentPlaybackPosition() > newDuration);
3077 } 3070 }
3078 3071
3079 void HTMLMediaElement::durationChanged(double duration, bool requestSeek) { 3072 void HTMLMediaElement::durationChanged(double duration, bool requestSeek) {
3080 BLINK_MEDIA_LOG << "durationChanged(" << (void*)this << ", " << duration 3073 BLINK_MEDIA_LOG << "durationChanged(" << (void*)this << ", " << duration
3081 << ", " << boolString(requestSeek) << ")"; 3074 << ", " << boolString(requestSeek) << ")";
3082 3075
3083 // Abort if duration unchanged. 3076 // Abort if duration unchanged.
3084 if (m_duration == duration) 3077 if (m_duration == duration)
3085 return; 3078 return;
3086 3079
(...skipping 1046 matching lines...) Expand 10 before | Expand all | Expand 10 after
4133 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE); 4126 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE);
4134 } 4127 }
4135 4128
4136 void HTMLMediaElement::viewportFillDebouncerTimerFired(TimerBase*) { 4129 void HTMLMediaElement::viewportFillDebouncerTimerFired(TimerBase*) {
4137 m_mostlyFillingViewport = true; 4130 m_mostlyFillingViewport = true;
4138 if (m_webMediaPlayer) 4131 if (m_webMediaPlayer)
4139 m_webMediaPlayer->becameDominantVisibleContent(m_mostlyFillingViewport); 4132 m_webMediaPlayer->becameDominantVisibleContent(m_mostlyFillingViewport);
4140 } 4133 }
4141 4134
4142 } // namespace blink 4135 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698