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

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

Issue 2425463002: Improve HTMLMediaElement::currentTime() (Closed)
Patch Set: comment fix Created 4 years, 1 month 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 10 matching lines...) Expand all
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */ 25 */
26 26
27 #include "core/html/HTMLMediaElement.h" 27 #include "core/html/HTMLMediaElement.h"
28 28
29 #include "bindings/core/v8/ExceptionState.h" 29 #include "bindings/core/v8/ExceptionState.h"
30 #include "bindings/core/v8/ExceptionStatePlaceholder.h" 30 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
31 #include "bindings/core/v8/Microtask.h"
31 #include "bindings/core/v8/ScriptController.h" 32 #include "bindings/core/v8/ScriptController.h"
32 #include "bindings/core/v8/ScriptEventListener.h" 33 #include "bindings/core/v8/ScriptEventListener.h"
33 #include "bindings/core/v8/ScriptPromiseResolver.h" 34 #include "bindings/core/v8/ScriptPromiseResolver.h"
34 #include "core/HTMLNames.h" 35 #include "core/HTMLNames.h"
35 #include "core/css/MediaList.h" 36 #include "core/css/MediaList.h"
36 #include "core/dom/Attribute.h" 37 #include "core/dom/Attribute.h"
37 #include "core/dom/DOMException.h" 38 #include "core/dom/DOMException.h"
38 #include "core/dom/ElementTraversal.h" 39 #include "core/dom/ElementTraversal.h"
39 #include "core/dom/ElementVisibilityObserver.h" 40 #include "core/dom/ElementVisibilityObserver.h"
40 #include "core/dom/Fullscreen.h" 41 #include "core/dom/Fullscreen.h"
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 #ifndef BLINK_MEDIA_LOG 102 #ifndef BLINK_MEDIA_LOG
102 #define BLINK_MEDIA_LOG DVLOG(3) 103 #define BLINK_MEDIA_LOG DVLOG(3)
103 #endif 104 #endif
104 105
105 #ifndef LOG_MEDIA_EVENTS 106 #ifndef LOG_MEDIA_EVENTS
106 // Default to not logging events because so many are generated they can 107 // Default to not logging events because so many are generated they can
107 // overwhelm the rest of the logging. 108 // overwhelm the rest of the logging.
108 #define LOG_MEDIA_EVENTS 0 109 #define LOG_MEDIA_EVENTS 0
109 #endif 110 #endif
110 111
111 #ifndef LOG_CACHED_TIME_WARNINGS 112 #ifndef LOG_OFFICIAL_TIME_STATUS
112 // Default to not logging warnings about excessive drift in the cached media 113 // Default to not logging status of official time because it adds a fair amount
113 // time because it adds a fair amount of overhead and logging. 114 // of overhead and logging.
114 #define LOG_CACHED_TIME_WARNINGS 0 115 #define LOG_OFFICIAL_TIME_STATUS 0
115 #endif 116 #endif
116 117
117 namespace blink { 118 namespace blink {
118 119
119 using namespace HTMLNames; 120 using namespace HTMLNames;
120 121
121 using WeakMediaElementSet = HeapHashSet<WeakMember<HTMLMediaElement>>; 122 using WeakMediaElementSet = HeapHashSet<WeakMember<HTMLMediaElement>>;
122 using DocumentElementSetMap = 123 using DocumentElementSetMap =
123 HeapHashMap<WeakMember<Document>, Member<WeakMediaElementSet>>; 124 HeapHashMap<WeakMember<Document>, Member<WeakMediaElementSet>>;
124 125
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 m_playbackRate(1.0f), 417 m_playbackRate(1.0f),
417 m_defaultPlaybackRate(1.0f), 418 m_defaultPlaybackRate(1.0f),
418 m_networkState(kNetworkEmpty), 419 m_networkState(kNetworkEmpty),
419 m_readyState(kHaveNothing), 420 m_readyState(kHaveNothing),
420 m_readyStateMaximum(kHaveNothing), 421 m_readyStateMaximum(kHaveNothing),
421 m_volume(1.0f), 422 m_volume(1.0f),
422 m_lastSeekTime(0), 423 m_lastSeekTime(0),
423 m_previousProgressTime(std::numeric_limits<double>::max()), 424 m_previousProgressTime(std::numeric_limits<double>::max()),
424 m_duration(std::numeric_limits<double>::quiet_NaN()), 425 m_duration(std::numeric_limits<double>::quiet_NaN()),
425 m_lastTimeUpdateEventWallTime(0), 426 m_lastTimeUpdateEventWallTime(0),
426 m_lastTimeUpdateEventMovieTime(0), 427 m_lastTimeUpdateEventMovieTime(std::numeric_limits<double>::quiet_NaN()),
427 m_defaultPlaybackStartPosition(0), 428 m_defaultPlaybackStartPosition(0),
428 m_loadState(WaitingForSource), 429 m_loadState(WaitingForSource),
429 m_deferredLoadState(NotDeferred), 430 m_deferredLoadState(NotDeferred),
430 m_deferredLoadTimer(this, &HTMLMediaElement::deferredLoadTimerFired), 431 m_deferredLoadTimer(this, &HTMLMediaElement::deferredLoadTimerFired),
431 m_webLayer(nullptr), 432 m_webLayer(nullptr),
432 m_displayMode(Unknown), 433 m_displayMode(Unknown),
433 m_cachedTime(std::numeric_limits<double>::quiet_NaN()), 434 m_officialPlaybackPosition(std::numeric_limits<double>::quiet_NaN()),
435 m_officialPlaybackPositionNeedsUpdate(true),
434 m_fragmentEndTime(std::numeric_limits<double>::quiet_NaN()), 436 m_fragmentEndTime(std::numeric_limits<double>::quiet_NaN()),
435 m_pendingActionFlags(0), 437 m_pendingActionFlags(0),
436 m_lockedPendingUserGesture(false), 438 m_lockedPendingUserGesture(false),
437 m_playing(false), 439 m_playing(false),
438 m_shouldDelayLoadEvent(false), 440 m_shouldDelayLoadEvent(false),
439 m_haveFiredLoadedData(false), 441 m_haveFiredLoadedData(false),
440 m_autoplaying(true), 442 m_autoplaying(true),
441 m_muted(false), 443 m_muted(false),
442 m_paused(true), 444 m_paused(true),
443 m_seeking(false), 445 m_seeking(false),
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 "The play() request was interrupted by a new load request."); 839 "The play() request was interrupted by a new load request.");
838 } 840 }
839 841
840 // 4.7 - If seeking is true, set it to false. 842 // 4.7 - If seeking is true, set it to false.
841 m_seeking = false; 843 m_seeking = false;
842 844
843 // 4.8 - Set the current playback position to 0. 845 // 4.8 - Set the current playback position to 0.
844 // Set the official playback position to 0. 846 // Set the official playback position to 0.
845 // If this changed the official playback position, then queue a task 847 // If this changed the official playback position, then queue a task
846 // to fire a simple event named timeupdate at the media element. 848 // to fire a simple event named timeupdate at the media element.
847 // FIXME: Add support for firing this event.
848
849 // 4.9 - Set the initial playback position to 0. 849 // 4.9 - Set the initial playback position to 0.
850 // FIXME: Make this less subtle. The position only becomes 0 because the 850 setOfficialPlaybackPosition(0);
851 // ready state is HAVE_NOTHING. 851 scheduleTimeupdateEvent(false);
852 invalidateCachedTime();
853 852
854 // 4.10 - Set the timeline offset to Not-a-Number (NaN). 853 // 4.10 - Set the timeline offset to Not-a-Number (NaN).
855 // 4.11 - Update the duration attribute to Not-a-Number (NaN). 854 // 4.11 - Update the duration attribute to Not-a-Number (NaN).
856 855
857 cueTimeline().updateActiveCues(0); 856 cueTimeline().updateActiveCues(0);
858 } else if (!m_paused) { 857 } else if (!m_paused) {
859 // TODO(foolip): There is a proposal to always reset the paused state 858 // TODO(foolip): There is a proposal to always reset the paused state
860 // in the media element load algorithm, to avoid a bogus play() promise 859 // in the media element load algorithm, to avoid a bogus play() promise
861 // rejection: https://github.com/whatwg/html/issues/869 860 // rejection: https://github.com/whatwg/html/issues/869
862 // This is where that change would have an effect, and it is measured to 861 // This is where that change would have an effect, and it is measured to
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after
1628 // attribute to change to a value lower than kHaveFutureData, then a waiting 1627 // attribute to change to a value lower than kHaveFutureData, then a waiting
1629 // will be fired at the element. 1628 // will be fired at the element.
1630 if (wasPotentiallyPlaying && m_readyState < kHaveFutureData) 1629 if (wasPotentiallyPlaying && m_readyState < kHaveFutureData)
1631 scheduleEvent(EventTypeNames::waiting); 1630 scheduleEvent(EventTypeNames::waiting);
1632 1631
1633 // 4.8.10.9 steps 12-14 1632 // 4.8.10.9 steps 12-14
1634 if (m_readyState >= kHaveCurrentData) 1633 if (m_readyState >= kHaveCurrentData)
1635 finishSeek(); 1634 finishSeek();
1636 } else { 1635 } else {
1637 if (wasPotentiallyPlaying && m_readyState < kHaveFutureData) { 1636 if (wasPotentiallyPlaying && m_readyState < kHaveFutureData) {
1637 // Force an update to official playback position. Automatic updates from
1638 // currentPlaybackPosition() will be blocked while m_readyState remains
1639 // < kHaveFutureData. This blocking is desired after 'waiting' has been
1640 // fired, but its good to update it one final time to accurately reflect
1641 // movie time at the moment we ran out of data to play.
mlamouri (slow - plz ping) 2016/10/26 15:32:54 movie time?
chcunningham 2016/10/26 19:29:41 we call it movie time in scheduleTimeupdateEvent..
1642 setOfficialPlaybackPosition(currentPlaybackPosition());
1643
1638 // 4.8.10.8 1644 // 4.8.10.8
1639 scheduleTimeupdateEvent(false); 1645 scheduleTimeupdateEvent(false);
1640 scheduleEvent(EventTypeNames::waiting); 1646 scheduleEvent(EventTypeNames::waiting);
1641 } 1647 }
1642 } 1648 }
1643 1649
1650 // Once enough of the media data has been fetched to determine the duration of
1651 // the media resource, its dimensions, and other metadata...
1644 if (m_readyState >= kHaveMetadata && oldState < kHaveMetadata) { 1652 if (m_readyState >= kHaveMetadata && oldState < kHaveMetadata) {
1645 createPlaceholderTracksIfNecessary(); 1653 createPlaceholderTracksIfNecessary();
1646 1654
1647 selectInitialTracksIfNecessary(); 1655 selectInitialTracksIfNecessary();
1648 1656
1649 MediaFragmentURIParser fragmentParser(m_currentSrc); 1657 MediaFragmentURIParser fragmentParser(m_currentSrc);
1650 m_fragmentEndTime = fragmentParser.endTime(); 1658 m_fragmentEndTime = fragmentParser.endTime();
1651 1659
1660 // Set the current playback position and the official playback position to
1661 // the earliest possible position.
1662 setOfficialPlaybackPosition(earliestPossiblePosition());
1663
1652 m_duration = duration(); 1664 m_duration = duration();
1653 scheduleEvent(EventTypeNames::durationchange); 1665 scheduleEvent(EventTypeNames::durationchange);
1654 1666
1655 if (isHTMLVideoElement()) 1667 if (isHTMLVideoElement())
1656 scheduleEvent(EventTypeNames::resize); 1668 scheduleEvent(EventTypeNames::resize);
1657 scheduleEvent(EventTypeNames::loadedmetadata); 1669 scheduleEvent(EventTypeNames::loadedmetadata);
1658 1670
1659 bool jumped = false; 1671 bool jumped = false;
1660 if (m_defaultPlaybackStartPosition > 0) { 1672 if (m_defaultPlaybackStartPosition > 0) {
1661 seek(m_defaultPlaybackStartPosition); 1673 seek(m_defaultPlaybackStartPosition);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1723 // creating a new one in this case. 1735 // creating a new one in this case.
1724 if (!m_autoplayVisibilityObserver) { 1736 if (!m_autoplayVisibilityObserver) {
1725 m_autoplayVisibilityObserver = new ElementVisibilityObserver( 1737 m_autoplayVisibilityObserver = new ElementVisibilityObserver(
1726 this, 1738 this,
1727 WTF::bind(&HTMLMediaElement::onVisibilityChangedForAutoplay, 1739 WTF::bind(&HTMLMediaElement::onVisibilityChangedForAutoplay,
1728 wrapWeakPersistent(this))); 1740 wrapWeakPersistent(this)));
1729 m_autoplayVisibilityObserver->start(); 1741 m_autoplayVisibilityObserver->start();
1730 } 1742 }
1731 } else { 1743 } else {
1732 m_paused = false; 1744 m_paused = false;
1733 invalidateCachedTime();
1734 scheduleEvent(EventTypeNames::play); 1745 scheduleEvent(EventTypeNames::play);
1735 scheduleNotifyPlaying(); 1746 scheduleNotifyPlaying();
1736 m_autoplaying = false; 1747 m_autoplaying = false;
1737 } 1748 }
1738 } 1749 }
1739 } 1750 }
1740 1751
1741 scheduleEvent(EventTypeNames::canplaythrough); 1752 scheduleEvent(EventTypeNames::canplaythrough);
1742 1753
1743 shouldUpdateDisplayState = true; 1754 shouldUpdateDisplayState = true;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1799 // m_webMediaPlayer is going out of sync with readystate. 1810 // m_webMediaPlayer is going out of sync with readystate.
1800 // m_webMediaPlayer is cleared but readystate is not set to HAVE_NOTHING. 1811 // m_webMediaPlayer is cleared but readystate is not set to HAVE_NOTHING.
1801 if (!m_webMediaPlayer || m_readyState == kHaveNothing) 1812 if (!m_webMediaPlayer || m_readyState == kHaveNothing)
1802 return; 1813 return;
1803 1814
1804 // Ignore preload none and start load if necessary. 1815 // Ignore preload none and start load if necessary.
1805 setIgnorePreloadNone(); 1816 setIgnorePreloadNone();
1806 1817
1807 // Get the current time before setting m_seeking, m_lastSeekTime is returned 1818 // Get the current time before setting m_seeking, m_lastSeekTime is returned
1808 // once it is set. 1819 // once it is set.
1809 refreshCachedTime(); 1820 double now = currentTime();
1810 // This is needed to avoid getting default playback start position from
1811 // currentTime().
1812 double now = m_cachedTime;
1813 1821
1814 // 3 - If the element's seeking IDL attribute is true, then another instance 1822 // 3 - If the element's seeking IDL attribute is true, then another instance
1815 // of this algorithm is already running. Abort that other instance of the 1823 // of this algorithm is already running. Abort that other instance of the
1816 // algorithm without waiting for the step that it is running to complete. 1824 // algorithm without waiting for the step that it is running to complete.
1817 // Nothing specific to be done here. 1825 // Nothing specific to be done here.
1818 1826
1819 // 4 - Set the seeking IDL attribute to true. 1827 // 4 - Set the seeking IDL attribute to true.
1820 // The flag will be cleared when the engine tells us the time has actually 1828 // The flag will be cleared when the engine tells us the time has actually
1821 // changed. 1829 // changed.
1822 m_seeking = true; 1830 m_seeking = true;
1823 1831
1824 // 6 - If the new playback position is later than the end of the media 1832 // 6 - If the new playback position is later than the end of the media
1825 // resource, then let it be the end of the media resource instead. 1833 // resource, then let it be the end of the media resource instead.
1826 time = std::min(time, duration()); 1834 time = std::min(time, duration());
1827 1835
1828 // 7 - If the new playback position is less than the earliest possible 1836 // 7 - If the new playback position is less than the earliest possible
1829 // position, let it be that position instead. 1837 // position, let it be that position instead.
1830 time = std::max(time, 0.0); 1838 time = std::max(time, earliestPossiblePosition());
mlamouri (slow - plz ping) 2016/10/26 15:32:54 "let it be that position instead" could win the ti
chcunningham 2016/10/26 19:29:41 Lol, agree
1831 1839
1832 // Ask the media engine for the time value in the movie's time scale before 1840 // Ask the media engine for the time value in the movie's time scale before
1833 // comparing with current time. This is necessary because if the seek time is 1841 // comparing with current time. This is necessary because if the seek time is
1834 // not equal to currentTime but the delta is less than the movie's time scale, 1842 // not equal to currentTime but the delta is less than the movie's time scale,
1835 // we will ask the media engine to "seek" to the current movie time, which may 1843 // we will ask the media engine to "seek" to the current movie time, which may
1836 // be a noop and not generate a timechanged callback. This means m_seeking 1844 // be a noop and not generate a timechanged callback. This means m_seeking
1837 // will never be cleared and we will never fire a 'seeked' event. 1845 // will never be cleared and we will never fire a 'seeked' event.
1838 double mediaTime = webMediaPlayer()->mediaTimeForTimeValue(time); 1846 double mediaTime = webMediaPlayer()->mediaTimeForTimeValue(time);
1839 if (time != mediaTime) { 1847 if (time != mediaTime) {
1840 BLINK_MEDIA_LOG << "seek(" << (void*)this << ", " << time 1848 BLINK_MEDIA_LOG << "seek(" << (void*)this << ", " << time
(...skipping 29 matching lines...) Expand all
1870 // 14-17 are handled, if necessary, when the engine signals a readystate 1878 // 14-17 are handled, if necessary, when the engine signals a readystate
1871 // change or otherwise satisfies seek completion and signals a time change. 1879 // change or otherwise satisfies seek completion and signals a time change.
1872 } 1880 }
1873 1881
1874 void HTMLMediaElement::finishSeek() { 1882 void HTMLMediaElement::finishSeek() {
1875 BLINK_MEDIA_LOG << "finishSeek(" << (void*)this << ")"; 1883 BLINK_MEDIA_LOG << "finishSeek(" << (void*)this << ")";
1876 1884
1877 // 14 - Set the seeking IDL attribute to false. 1885 // 14 - Set the seeking IDL attribute to false.
1878 m_seeking = false; 1886 m_seeking = false;
1879 1887
1888 // Force an update to officialPlaybackPosition. Periodic updates generally
1889 // handle this, but may be skipped paused or waiting for data.
1890 setOfficialPlaybackPosition(currentPlaybackPosition());
mlamouri (slow - plz ping) 2016/10/26 15:32:54 You did this somewhere above too. Can we deal with
chcunningham 2016/10/26 19:29:41 I'm not in love with it, but I'm not sure how to i
1891
1880 // 16 - Queue a task to fire a simple event named timeupdate at the element. 1892 // 16 - Queue a task to fire a simple event named timeupdate at the element.
1881 scheduleTimeupdateEvent(false); 1893 scheduleTimeupdateEvent(false);
1882 1894
1883 // 17 - Queue a task to fire a simple event named seeked at the element. 1895 // 17 - Queue a task to fire a simple event named seeked at the element.
1884 scheduleEvent(EventTypeNames::seeked); 1896 scheduleEvent(EventTypeNames::seeked);
1885 1897
1886 setDisplayMode(Video); 1898 setDisplayMode(Video);
1887 } 1899 }
1888 1900
1889 HTMLMediaElement::ReadyState HTMLMediaElement::getReadyState() const { 1901 HTMLMediaElement::ReadyState HTMLMediaElement::getReadyState() const {
1890 return m_readyState; 1902 return m_readyState;
1891 } 1903 }
1892 1904
1893 bool HTMLMediaElement::hasVideo() const { 1905 bool HTMLMediaElement::hasVideo() const {
1894 return webMediaPlayer() && webMediaPlayer()->hasVideo(); 1906 return webMediaPlayer() && webMediaPlayer()->hasVideo();
1895 } 1907 }
1896 1908
1897 bool HTMLMediaElement::hasAudio() const { 1909 bool HTMLMediaElement::hasAudio() const {
1898 return webMediaPlayer() && webMediaPlayer()->hasAudio(); 1910 return webMediaPlayer() && webMediaPlayer()->hasAudio();
1899 } 1911 }
1900 1912
1901 bool HTMLMediaElement::seeking() const { 1913 bool HTMLMediaElement::seeking() const {
1902 return m_seeking; 1914 return m_seeking;
1903 } 1915 }
1904 1916
1905 void HTMLMediaElement::refreshCachedTime() const { 1917 // https://www.w3.org/TR/html51/semantics-embedded-content.html#earliest-possibl e-position
1906 if (!webMediaPlayer() || m_readyState < kHaveMetadata) 1918 // The earliest possible position is not explicitly exposed in the API; it
1907 return; 1919 // corresponds to the start time of the first range in the seekable attribute’s
1920 // TimeRanges object, if any, or the current playback position otherwise.
1921 double HTMLMediaElement::earliestPossiblePosition() const {
1922 TimeRanges* seekableRanges = seekable();
1923 if (seekableRanges && seekableRanges->length() > 0)
1924 return seekableRanges->start(0, ASSERT_NO_EXCEPTION);
1908 1925
1909 m_cachedTime = webMediaPlayer()->currentTime(); 1926 return currentPlaybackPosition();
1910 } 1927 }
1911 1928
1912 void HTMLMediaElement::invalidateCachedTime() { 1929 double HTMLMediaElement::currentPlaybackPosition() const {
1913 BLINK_MEDIA_LOG << "invalidateCachedTime(" << (void*)this << ")"; 1930 // "Official" playback position won't take updates from "current" playback
1914 m_cachedTime = std::numeric_limits<double>::quiet_NaN(); 1931 // position until m_readyState > kHaveMetadata, but other callers (e.g.
1932 // pauseInternal) may still request currentPlaybackPosition at any time.
1933 if (m_readyState == kHaveNothing)
1934 return std::numeric_limits<double>::quiet_NaN();
1935
1936 if (webMediaPlayer())
1937 return webMediaPlayer()->currentTime();
1938
1939 if (m_readyState >= kHaveMetadata) {
1940 LOG(WARNING) << __func__ << " readyState = " << m_readyState
1941 << " but no webMeidaPlayer to provide currentPlaybackPosition";
1942 }
1943
1944 return 0;
1915 } 1945 }
1916 1946
1917 // playback state 1947 double HTMLMediaElement::officialPlaybackPosition() const {
1948 // Hold updates to official playback position while paused or waiting for more
1949 // data. The underlying media player may continue to make small advances in
1950 // currentTime (e.g. as samples in the last rendered audio buffer are played
1951 // played out), but advancing currentTime while paused/waiting sends a mixed
1952 // signal about the state of playback.
1953 bool waitingForData = m_readyState <= kHaveCurrentData;
1954 if (m_officialPlaybackPositionNeedsUpdate && !m_paused && !waitingForData) {
1955 // Internal player position may advance slightly beyond duration because
1956 // many files use imprecise duration. Clamp official position to duration.
1957 // REVIEWER: Not sure what the spec expects really. If I don't do this here,
mlamouri (slow - plz ping) 2016/10/26 15:32:54 +foolip@, are you familiar with the spirit of the
foolip 2016/10/26 19:43:30 Per spec, it's OK for the duration to change any n
1958 // I at least need to update MediaControlsPainter::paintMediaSliderInternal
1959 // to not skip ranges when rangeEnd < currentTime.
1960 double newPosition = std::min(duration(), currentPlaybackPosition());
1961 setOfficialPlaybackPosition(newPosition);
1962 }
1963
1964 #if LOG_OFFICIAL_TIME_STATUS
1965 static const double minCachedDeltaForWarning = 0.01;
1966 double delta =
1967 std::abs(m_officialPlaybackPosition - currentPlaybackPosition());
1968 if (delta > minCachedDeltaForWarning) {
1969 BLINK_MEDIA_LOG << "currentTime(" << (void*)this
1970 << ") - WARNING, cached time is " << delta
1971 << "seconds off of media time when paused/waiting";
1972 }
1973 #endif
1974
1975 return m_officialPlaybackPosition;
1976 }
1977
1978 void HTMLMediaElement::setOfficialPlaybackPosition(double position) const {
1979 #if LOG_OFFICIAL_TIME_STATUS
1980 BLINK_MEDIA_LOG << "setOfficialPlaybackPosition(" << (void*)this
1981 << ") was:" << m_officialPlaybackPosition
1982 << " now:" << position;
1983 #endif
1984
1985 m_officialPlaybackPosition = position;
1986
1987 // Once set, official playback position should hold steady until the next
1988 // stable state. We approximate this by using a microtask to mark the
1989 // need for an update after the current (micro)task has completed. When
1990 // needed, the update is applied in the next call to
1991 // officialPlaybackPosition().
1992 m_officialPlaybackPositionNeedsUpdate = false;
1993 Microtask::enqueueMicrotask(
1994 WTF::bind(&HTMLMediaElement::requireOfficialPlaybackPositionUpdate,
1995 wrapWeakPersistent(this)));
1996 }
1997
1998 void HTMLMediaElement::requireOfficialPlaybackPositionUpdate() const {
1999 m_officialPlaybackPositionNeedsUpdate = true;
2000 }
2001
1918 double HTMLMediaElement::currentTime() const { 2002 double HTMLMediaElement::currentTime() const {
1919 if (m_defaultPlaybackStartPosition) 2003 if (m_defaultPlaybackStartPosition)
1920 return m_defaultPlaybackStartPosition; 2004 return m_defaultPlaybackStartPosition;
1921 2005
1922 if (m_readyState == kHaveNothing)
1923 return 0;
1924
1925 if (m_seeking) { 2006 if (m_seeking) {
1926 BLINK_MEDIA_LOG << "currentTime(" << (void*)this 2007 BLINK_MEDIA_LOG << "currentTime(" << (void*)this
1927 << ") - seeking, returning " << m_lastSeekTime; 2008 << ") - seeking, returning " << m_lastSeekTime;
1928 return m_lastSeekTime; 2009 return m_lastSeekTime;
1929 } 2010 }
1930 2011
1931 if (!std::isnan(m_cachedTime) && m_paused) { 2012 return officialPlaybackPosition();
1932 #if LOG_CACHED_TIME_WARNINGS
1933 static const double minCachedDeltaForWarning = 0.01;
1934 double delta = m_cachedTime - webMediaPlayer()->currentTime();
1935 if (delta > minCachedDeltaForWarning)
1936 BLINK_MEDIA_LOG << "currentTime(" << (void*)this
1937 << ") - WARNING, cached time is " << delta
1938 << "seconds off of media time when paused";
1939 #endif
1940 return m_cachedTime;
1941 }
1942
1943 refreshCachedTime();
1944
1945 return m_cachedTime;
1946 } 2013 }
1947 2014
1948 void HTMLMediaElement::setCurrentTime(double time) { 2015 void HTMLMediaElement::setCurrentTime(double time) {
1949 // If the media element's readyState is kHaveNothing, then set the default 2016 // If the media element's readyState is kHaveNothing, then set the default
1950 // playback start position to that time. 2017 // playback start position to that time.
1951 if (m_readyState == kHaveNothing) { 2018 if (m_readyState == kHaveNothing) {
1952 m_defaultPlaybackStartPosition = time; 2019 m_defaultPlaybackStartPosition = time;
1953 return; 2020 return;
1954 } 2021 }
1955 2022
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1997 2064
1998 double HTMLMediaElement::playbackRate() const { 2065 double HTMLMediaElement::playbackRate() const {
1999 return m_playbackRate; 2066 return m_playbackRate;
2000 } 2067 }
2001 2068
2002 void HTMLMediaElement::setPlaybackRate(double rate) { 2069 void HTMLMediaElement::setPlaybackRate(double rate) {
2003 BLINK_MEDIA_LOG << "setPlaybackRate(" << (void*)this << ", " << rate << ")"; 2070 BLINK_MEDIA_LOG << "setPlaybackRate(" << (void*)this << ", " << rate << ")";
2004 2071
2005 if (m_playbackRate != rate) { 2072 if (m_playbackRate != rate) {
2006 m_playbackRate = rate; 2073 m_playbackRate = rate;
2007 invalidateCachedTime();
2008 scheduleEvent(EventTypeNames::ratechange); 2074 scheduleEvent(EventTypeNames::ratechange);
2009 } 2075 }
2010 2076
2011 updatePlaybackRate(); 2077 updatePlaybackRate();
2012 } 2078 }
2013 2079
2014 HTMLMediaElement::DirectionOfPlayback HTMLMediaElement::getDirectionOfPlayback() 2080 HTMLMediaElement::DirectionOfPlayback HTMLMediaElement::getDirectionOfPlayback()
2015 const { 2081 const {
2016 return m_playbackRate >= 0 ? Forward : Backward; 2082 return m_playbackRate >= 0 ? Forward : Backward;
2017 } 2083 }
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
2204 invokeResourceSelectionAlgorithm(); 2270 invokeResourceSelectionAlgorithm();
2205 2271
2206 // Generally "ended" and "looping" are exclusive. Here, the loop attribute 2272 // Generally "ended" and "looping" are exclusive. Here, the loop attribute
2207 // is ignored to seek back to start in case loop was set after playback 2273 // is ignored to seek back to start in case loop was set after playback
2208 // ended. See http://crbug.com/364442 2274 // ended. See http://crbug.com/364442
2209 if (endedPlayback(LoopCondition::Ignored)) 2275 if (endedPlayback(LoopCondition::Ignored))
2210 seek(0); 2276 seek(0);
2211 2277
2212 if (m_paused) { 2278 if (m_paused) {
2213 m_paused = false; 2279 m_paused = false;
2214 invalidateCachedTime();
2215 scheduleEvent(EventTypeNames::play); 2280 scheduleEvent(EventTypeNames::play);
2216 2281
2217 if (m_readyState <= kHaveCurrentData) 2282 if (m_readyState <= kHaveCurrentData)
2218 scheduleEvent(EventTypeNames::waiting); 2283 scheduleEvent(EventTypeNames::waiting);
2219 else if (m_readyState >= kHaveFutureData) 2284 else if (m_readyState >= kHaveFutureData)
2220 scheduleNotifyPlaying(); 2285 scheduleNotifyPlaying();
2221 } else if (m_readyState >= kHaveFutureData) { 2286 } else if (m_readyState >= kHaveFutureData) {
2222 scheduleResolvePlayPromises(); 2287 scheduleResolvePlayPromises();
2223 } 2288 }
2224 2289
(...skipping 22 matching lines...) Expand all
2247 invokeResourceSelectionAlgorithm(); 2312 invokeResourceSelectionAlgorithm();
2248 2313
2249 m_autoplayHelper->pauseMethodCalled(); 2314 m_autoplayHelper->pauseMethodCalled();
2250 2315
2251 m_autoplaying = false; 2316 m_autoplaying = false;
2252 2317
2253 if (!m_paused) { 2318 if (!m_paused) {
2254 m_paused = true; 2319 m_paused = true;
2255 scheduleTimeupdateEvent(false); 2320 scheduleTimeupdateEvent(false);
2256 scheduleEvent(EventTypeNames::pause); 2321 scheduleEvent(EventTypeNames::pause);
2322
2323 // Force an update to official playback position. Automatic updates from
2324 // currentPlaybackPosition() will be blocked while m_paused = true. This
2325 // blocking is desired while paused, but its good to update it one final
2326 // time to accurately reflect movie time at the moment we paused.
2327 setOfficialPlaybackPosition(currentPlaybackPosition());
2328
2257 scheduleRejectPlayPromises(AbortError); 2329 scheduleRejectPlayPromises(AbortError);
2258 } 2330 }
2259 2331
2260 updatePlayState(); 2332 updatePlayState();
2261 } 2333 }
2262 2334
2263 void HTMLMediaElement::requestRemotePlayback() { 2335 void HTMLMediaElement::requestRemotePlayback() {
2264 if (webMediaPlayer()) 2336 if (webMediaPlayer())
2265 webMediaPlayer()->requestRemotePlayback(); 2337 webMediaPlayer()->requestRemotePlayback();
2266 } 2338 }
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
2431 if (!playbackRate()) 2503 if (!playbackRate())
2432 return; 2504 return;
2433 2505
2434 if (!m_paused && mediaControls()) 2506 if (!m_paused && mediaControls())
2435 mediaControls()->playbackProgressed(); 2507 mediaControls()->playbackProgressed();
2436 2508
2437 cueTimeline().updateActiveCues(currentTime()); 2509 cueTimeline().updateActiveCues(currentTime());
2438 } 2510 }
2439 2511
2440 void HTMLMediaElement::scheduleTimeupdateEvent(bool periodicEvent) { 2512 void HTMLMediaElement::scheduleTimeupdateEvent(bool periodicEvent) {
2513 // Per spec, consult current playback position to check for changing time.
2514 double movieTime = currentPlaybackPosition();
2441 double now = WTF::currentTime(); 2515 double now = WTF::currentTime();
2442 double movieTime = currentTime();
2443 2516
2444 bool haveNotRecentlyFiredTimeupdate = 2517 bool haveNotRecentlyFiredTimeupdate =
2445 (now - m_lastTimeUpdateEventWallTime) >= maxTimeupdateEventFrequency; 2518 (now - m_lastTimeUpdateEventWallTime) >= maxTimeupdateEventFrequency;
2446 bool movieTimeHasProgressed = movieTime != m_lastTimeUpdateEventMovieTime; 2519 bool movieTimeHasProgressed = movieTime != m_lastTimeUpdateEventMovieTime;
2447 2520
2448 // Non-periodic timeupdate events must always fire as mandated by the spec, 2521 // Non-periodic timeupdate events must always fire as mandated by the spec,
2449 // otherwise we shouldn't fire duplicate periodic timeupdate events when the 2522 // otherwise we shouldn't fire duplicate periodic timeupdate events when the
2450 // movie time hasn't changed. 2523 // movie time hasn't changed.
2451 if (!periodicEvent || 2524 if (!periodicEvent ||
2452 (haveNotRecentlyFiredTimeupdate && movieTimeHasProgressed)) { 2525 (haveNotRecentlyFiredTimeupdate && movieTimeHasProgressed)) {
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
2977 BLINK_MEDIA_LOG << "sourceWasRemoved(" << (void*)this 3050 BLINK_MEDIA_LOG << "sourceWasRemoved(" << (void*)this
2978 << ") - m_currentSourceNode set to 0"; 3051 << ") - m_currentSourceNode set to 0";
2979 } 3052 }
2980 } 3053 }
2981 3054
2982 void HTMLMediaElement::timeChanged() { 3055 void HTMLMediaElement::timeChanged() {
2983 BLINK_MEDIA_LOG << "timeChanged(" << (void*)this << ")"; 3056 BLINK_MEDIA_LOG << "timeChanged(" << (void*)this << ")";
2984 3057
2985 cueTimeline().updateActiveCues(currentTime()); 3058 cueTimeline().updateActiveCues(currentTime());
2986 3059
2987 invalidateCachedTime();
2988
2989 // 4.8.10.9 steps 12-14. Needed if no ReadyState change is associated with the 3060 // 4.8.10.9 steps 12-14. Needed if no ReadyState change is associated with the
2990 // seek. 3061 // seek.
2991 if (m_seeking && m_readyState >= kHaveCurrentData && 3062 if (m_seeking && m_readyState >= kHaveCurrentData &&
2992 !webMediaPlayer()->seeking()) 3063 !webMediaPlayer()->seeking())
2993 finishSeek(); 3064 finishSeek();
2994 3065
2995 // Always call scheduleTimeupdateEvent when the media engine reports a time 3066 // Always call scheduleTimeupdateEvent when the media engine reports a time
2996 // discontinuity, it will only queue a 'timeupdate' event if we haven't 3067 // discontinuity, it will only queue a 'timeupdate' event if we haven't
2997 // already posted one at the current movie time. 3068 // already posted one at the current movie time.
2998 scheduleTimeupdateEvent(false); 3069 scheduleTimeupdateEvent(false);
2999 3070
3000 double now = currentTime(); 3071 double now = currentPlaybackPosition();
3001 double dur = duration(); 3072 double dur = duration();
3002 3073
3003 // When the current playback position reaches the end of the media resource 3074 // When the current playback position reaches the end of the media resource
3004 // when the direction of playback is forwards, then the user agent must follow 3075 // when the direction of playback is forwards, then the user agent must follow
3005 // these steps: 3076 // these steps:
3006 if (!std::isnan(dur) && dur && now >= dur && 3077 if (!std::isnan(dur) && dur && now >= dur &&
3007 getDirectionOfPlayback() == Forward) { 3078 getDirectionOfPlayback() == Forward) {
3008 // If the media element has a loop attribute specified 3079 // If the media element has a loop attribute specified
3009 if (loop()) { 3080 if (loop()) {
3010 // then seek to the earliest possible position of the media resource and 3081 // then seek to the earliest possible position of the media resource and
3011 // abort these steps. 3082 // abort these steps.
3012 seek(0); 3083 seek(earliestPossiblePosition());
3013 } else { 3084 } else {
3014 // If the media element has still ended playback, and the direction of 3085 // If the media element has still ended playback, and the direction of
3015 // playback is still forwards, and paused is false, 3086 // playback is still forwards, and paused is false,
3016 if (!m_paused) { 3087 if (!m_paused) {
3017 // changes paused to true and fires a simple event named pause at the 3088 // changes paused to true and fires a simple event named pause at the
3018 // media element. 3089 // media element.
3019 m_paused = true; 3090 m_paused = true;
3020 scheduleEvent(EventTypeNames::pause); 3091 scheduleEvent(EventTypeNames::pause);
3021 scheduleRejectPlayPromises(AbortError); 3092 scheduleRejectPlayPromises(AbortError);
3022 } 3093 }
3023 // Queue a task to fire a simple event named ended at the media element. 3094 // Queue a task to fire a simple event named ended at the media element.
3024 scheduleEvent(EventTypeNames::ended); 3095 scheduleEvent(EventTypeNames::ended);
3025 } 3096 }
3026 } 3097 }
3027 updatePlayState(); 3098 updatePlayState();
3028 } 3099 }
3029 3100
3030 void HTMLMediaElement::durationChanged() { 3101 void HTMLMediaElement::durationChanged() {
3031 BLINK_MEDIA_LOG << "durationChanged(" << (void*)this << ")"; 3102 BLINK_MEDIA_LOG << "durationChanged(" << (void*)this << ")";
3032 // FIXME: Change WebMediaPlayer to convey the currentTime 3103 // If the duration is changed such that the *current playback position* ends
3033 // when the duration change occured. The current WebMediaPlayer 3104 // up being greater than the time of the end of the media resource, then the
3034 // implementations always clamp currentTime() to duration() 3105 // user agent must also seek to the time of the end of the media resource.
3035 // so the requestSeek condition here is always false. 3106 durationChanged(duration(), currentPlaybackPosition() > duration());
3036 durationChanged(duration(), currentTime() > duration());
3037 } 3107 }
3038 3108
3039 void HTMLMediaElement::durationChanged(double duration, bool requestSeek) { 3109 void HTMLMediaElement::durationChanged(double duration, bool requestSeek) {
3040 BLINK_MEDIA_LOG << "durationChanged(" << (void*)this << ", " << duration 3110 BLINK_MEDIA_LOG << "durationChanged(" << (void*)this << ", " << duration
3041 << ", " << boolString(requestSeek) << ")"; 3111 << ", " << boolString(requestSeek) << ")";
3042 3112
3043 // Abort if duration unchanged. 3113 // Abort if duration unchanged.
3044 if (m_duration == duration) 3114 if (m_duration == duration)
3045 return; 3115 return;
3046 3116
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
3189 // 4.8.10.8 Playing the media resource 3259 // 4.8.10.8 Playing the media resource
3190 3260
3191 // A media element is said to have ended playback when the element's 3261 // A media element is said to have ended playback when the element's
3192 // readyState attribute is HAVE_METADATA or greater, 3262 // readyState attribute is HAVE_METADATA or greater,
3193 if (m_readyState < kHaveMetadata) 3263 if (m_readyState < kHaveMetadata)
3194 return false; 3264 return false;
3195 3265
3196 // and the current playback position is the end of the media resource and the 3266 // and the current playback position is the end of the media resource and the
3197 // direction of playback is forwards, Either the media element does not have a 3267 // direction of playback is forwards, Either the media element does not have a
3198 // loop attribute specified, 3268 // loop attribute specified,
3199 double now = currentTime(); 3269 double now = currentPlaybackPosition();
3200 if (getDirectionOfPlayback() == Forward) 3270 if (getDirectionOfPlayback() == Forward)
3201 return dur > 0 && now >= dur && 3271 return dur > 0 && now >= dur &&
3202 (loopCondition == LoopCondition::Ignored || !loop()); 3272 (loopCondition == LoopCondition::Ignored || !loop());
3203 3273
3204 // or the current playback position is the earliest possible position and the 3274 // or the current playback position is the earliest possible position and the
3205 // direction of playback is backwards 3275 // direction of playback is backwards
3206 DCHECK_EQ(getDirectionOfPlayback(), Backward); 3276 DCHECK_EQ(getDirectionOfPlayback(), Backward);
3207 return now <= 0; 3277 return now <= earliestPossiblePosition();
3208 } 3278 }
3209 3279
3210 bool HTMLMediaElement::stoppedDueToErrors() const { 3280 bool HTMLMediaElement::stoppedDueToErrors() const {
3211 if (m_readyState >= kHaveMetadata && m_error) { 3281 if (m_readyState >= kHaveMetadata && m_error) {
3212 TimeRanges* seekableRanges = seekable(); 3282 TimeRanges* seekableRanges = seekable();
3213 if (!seekableRanges->contain(currentTime())) 3283 if (!seekableRanges->contain(currentTime()))
3214 return true; 3284 return true;
3215 } 3285 }
3216 3286
3217 return false; 3287 return false;
3218 } 3288 }
3219 3289
3220 void HTMLMediaElement::updatePlayState() { 3290 void HTMLMediaElement::updatePlayState() {
3221 bool isPlaying = webMediaPlayer() && !webMediaPlayer()->paused(); 3291 bool isPlaying = webMediaPlayer() && !webMediaPlayer()->paused();
3222 bool shouldBePlaying = potentiallyPlaying(); 3292 bool shouldBePlaying = potentiallyPlaying();
3223 3293
3224 BLINK_MEDIA_LOG << "updatePlayState(" << (void*)this 3294 BLINK_MEDIA_LOG << "updatePlayState(" << (void*)this
3225 << ") - shouldBePlaying = " << boolString(shouldBePlaying) 3295 << ") - shouldBePlaying = " << boolString(shouldBePlaying)
3226 << ", isPlaying = " << boolString(isPlaying); 3296 << ", isPlaying = " << boolString(isPlaying);
3227 3297
3228 if (shouldBePlaying) { 3298 if (shouldBePlaying) {
3229 setDisplayMode(Video); 3299 setDisplayMode(Video);
3230 invalidateCachedTime();
3231 3300
3232 if (!isPlaying) { 3301 if (!isPlaying) {
3233 // Set rate, muted before calling play in case they were set before the 3302 // Set rate, muted before calling play in case they were set before the
3234 // media engine was setup. The media engine should just stash the rate 3303 // media engine was setup. The media engine should just stash the rate
3235 // and muted values since it isn't already playing. 3304 // and muted values since it isn't already playing.
3236 webMediaPlayer()->setRate(playbackRate()); 3305 webMediaPlayer()->setRate(playbackRate());
3237 updateVolume(); 3306 updateVolume();
3238 webMediaPlayer()->play(); 3307 webMediaPlayer()->play();
3239 m_autoplayHelper->playbackStarted(); 3308 m_autoplayHelper->playbackStarted();
3240 } 3309 }
3241 3310
3242 if (mediaControls()) 3311 if (mediaControls())
3243 mediaControls()->playbackStarted(); 3312 mediaControls()->playbackStarted();
3244 startPlaybackProgressTimer(); 3313 startPlaybackProgressTimer();
3245 m_playing = true; 3314 m_playing = true;
3246 3315
3247 } else { // Should not be playing right now 3316 } else { // Should not be playing right now
3248 if (isPlaying) { 3317 if (isPlaying) {
3249 webMediaPlayer()->pause(); 3318 webMediaPlayer()->pause();
3250 m_autoplayHelper->playbackStopped(); 3319 m_autoplayHelper->playbackStopped();
3251 } 3320 }
3252 3321
3253 refreshCachedTime();
3254
3255 m_playbackProgressTimer.stop(); 3322 m_playbackProgressTimer.stop();
3256 m_playing = false; 3323 m_playing = false;
3257 double time = currentTime(); 3324 double time = currentTime();
3258 if (time > m_lastSeekTime) 3325 if (time > m_lastSeekTime)
3259 addPlayedRange(m_lastSeekTime, time); 3326 addPlayedRange(m_lastSeekTime, time);
3260 3327
3261 if (mediaControls()) 3328 if (mediaControls())
3262 mediaControls()->playbackStopped(); 3329 mediaControls()->playbackStopped();
3263 } 3330 }
3264 3331
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
3302 m_remoteRoutesAvailable = false; 3369 m_remoteRoutesAvailable = false;
3303 m_playingRemotely = false; 3370 m_playingRemotely = false;
3304 if (mediaControls()) 3371 if (mediaControls())
3305 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); 3372 mediaControls()->refreshCastButtonVisibilityWithoutUpdate();
3306 3373
3307 if (layoutObject()) 3374 if (layoutObject())
3308 layoutObject()->setShouldDoFullPaintInvalidation(); 3375 layoutObject()->setShouldDoFullPaintInvalidation();
3309 } 3376 }
3310 3377
3311 void HTMLMediaElement::contextDestroyed() { 3378 void HTMLMediaElement::contextDestroyed() {
3312 BLINK_MEDIA_LOG << "contextDestroyed(" << (void*)this << ")";
mlamouri (slow - plz ping) 2016/10/26 15:32:54 Why did you remove this LOG?
chcunningham 2016/10/26 19:29:41 Mistake. Fixed.
3313 3379
3314 // Close the async event queue so that no events are enqueued. 3380 // Close the async event queue so that no events are enqueued.
3315 cancelPendingEventsAndCallbacks(); 3381 cancelPendingEventsAndCallbacks();
3316 m_asyncEventQueue->close(); 3382 m_asyncEventQueue->close();
3317 3383
3318 // Clear everything in the Media Element 3384 // Clear everything in the Media Element
3319 clearMediaPlayer(); 3385 clearMediaPlayer();
3320 m_readyState = kHaveNothing; 3386 m_readyState = kHaveNothing;
3321 m_readyStateMaximum = kHaveNothing; 3387 m_readyStateMaximum = kHaveNothing;
3322 setNetworkState(kNetworkEmpty); 3388 setNetworkState(kNetworkEmpty);
3323 setShouldDelayLoadEvent(false); 3389 setShouldDelayLoadEvent(false);
3324 m_currentSourceNode = nullptr; 3390 m_currentSourceNode = nullptr;
3325 invalidateCachedTime(); 3391 m_officialPlaybackPosition = std::numeric_limits<double>::quiet_NaN();
3392 m_officialPlaybackPositionNeedsUpdate = true;
3326 cueTimeline().updateActiveCues(0); 3393 cueTimeline().updateActiveCues(0);
3327 m_playing = false; 3394 m_playing = false;
3328 m_paused = true; 3395 m_paused = true;
3329 m_seeking = false; 3396 m_seeking = false;
3330 3397
3331 if (layoutObject()) 3398 if (layoutObject())
3332 layoutObject()->updateFromElement(); 3399 layoutObject()->updateFromElement();
3333 3400
3334 stopPeriodicTimers(); 3401 stopPeriodicTimers();
3335 3402
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
3967 ("Media.Controls.Show.Audio", MediaControlsShowMax)); 4034 ("Media.Controls.Show.Audio", MediaControlsShowMax));
3968 return histogram; 4035 return histogram;
3969 } 4036 }
3970 4037
3971 void HTMLMediaElement::onVisibilityChangedForAutoplay(bool isVisible) { 4038 void HTMLMediaElement::onVisibilityChangedForAutoplay(bool isVisible) {
3972 if (!isVisible) 4039 if (!isVisible)
3973 return; 4040 return;
3974 4041
3975 if (shouldAutoplay()) { 4042 if (shouldAutoplay()) {
3976 m_paused = false; 4043 m_paused = false;
3977 invalidateCachedTime();
3978 scheduleEvent(EventTypeNames::play); 4044 scheduleEvent(EventTypeNames::play);
3979 scheduleNotifyPlaying(); 4045 scheduleNotifyPlaying();
3980 m_autoplaying = false; 4046 m_autoplaying = false;
3981 4047
3982 updatePlayState(); 4048 updatePlayState();
3983 } 4049 }
3984 4050
3985 // TODO(zqzhang): There's still flaky leak if onVisibilityChangedForAutoplay() 4051 // TODO(zqzhang): There's still flaky leak if onVisibilityChangedForAutoplay()
3986 // is never called. The leak comes from either ElementVisibilityObserver or 4052 // is never called. The leak comes from either ElementVisibilityObserver or
3987 // IntersectionObserver. Should keep an eye on it. See 4053 // IntersectionObserver. Should keep an eye on it. See
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
4092 4158
4093 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect() 4159 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect()
4094 const { 4160 const {
4095 IntRect result; 4161 IntRect result;
4096 if (LayoutObject* object = m_element->layoutObject()) 4162 if (LayoutObject* object = m_element->layoutObject())
4097 result = object->absoluteBoundingBoxRect(); 4163 result = object->absoluteBoundingBoxRect();
4098 return result; 4164 return result;
4099 } 4165 }
4100 4166
4101 } // namespace blink 4167 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698