| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights
reserved. | 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights
reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 #include "core/dom/Fullscreen.h" | 38 #include "core/dom/Fullscreen.h" |
| 39 #include "core/dom/shadow/ShadowRoot.h" | 39 #include "core/dom/shadow/ShadowRoot.h" |
| 40 #include "core/events/Event.h" | 40 #include "core/events/Event.h" |
| 41 #include "core/frame/LocalFrame.h" | 41 #include "core/frame/LocalFrame.h" |
| 42 #include "core/frame/Settings.h" | 42 #include "core/frame/Settings.h" |
| 43 #include "core/frame/UseCounter.h" | 43 #include "core/frame/UseCounter.h" |
| 44 #include "core/frame/csp/ContentSecurityPolicy.h" | 44 #include "core/frame/csp/ContentSecurityPolicy.h" |
| 45 #include "core/html/HTMLMediaSource.h" | 45 #include "core/html/HTMLMediaSource.h" |
| 46 #include "core/html/HTMLSourceElement.h" | 46 #include "core/html/HTMLSourceElement.h" |
| 47 #include "core/html/HTMLTrackElement.h" | 47 #include "core/html/HTMLTrackElement.h" |
| 48 #include "core/html/MediaController.h" | |
| 49 #include "core/html/MediaError.h" | 48 #include "core/html/MediaError.h" |
| 50 #include "core/html/MediaFragmentURIParser.h" | 49 #include "core/html/MediaFragmentURIParser.h" |
| 51 #include "core/html/TimeRanges.h" | 50 #include "core/html/TimeRanges.h" |
| 52 #include "core/html/shadow/MediaControls.h" | 51 #include "core/html/shadow/MediaControls.h" |
| 53 #include "core/html/track/AudioTrack.h" | 52 #include "core/html/track/AudioTrack.h" |
| 54 #include "core/html/track/AudioTrackList.h" | 53 #include "core/html/track/AudioTrackList.h" |
| 55 #include "core/html/track/AutomaticTrackSelection.h" | 54 #include "core/html/track/AutomaticTrackSelection.h" |
| 56 #include "core/html/track/CueTimeline.h" | 55 #include "core/html/track/CueTimeline.h" |
| 57 #include "core/html/track/InbandTextTrack.h" | 56 #include "core/html/track/InbandTextTrack.h" |
| 58 #include "core/html/track/TextTrackContainer.h" | 57 #include "core/html/track/TextTrackContainer.h" |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 // the same GC. We don't need to close it explicitly in Oilpan. | 371 // the same GC. We don't need to close it explicitly in Oilpan. |
| 373 m_asyncEventQueue->close(); | 372 m_asyncEventQueue->close(); |
| 374 | 373 |
| 375 setShouldDelayLoadEvent(false); | 374 setShouldDelayLoadEvent(false); |
| 376 | 375 |
| 377 if (m_textTracks) | 376 if (m_textTracks) |
| 378 m_textTracks->clearOwner(); | 377 m_textTracks->clearOwner(); |
| 379 m_audioTracks->shutdown(); | 378 m_audioTracks->shutdown(); |
| 380 m_videoTracks->shutdown(); | 379 m_videoTracks->shutdown(); |
| 381 | 380 |
| 382 if (m_mediaController) { | |
| 383 m_mediaController->removeMediaElement(this); | |
| 384 m_mediaController = nullptr; | |
| 385 } | |
| 386 closeMediaSource(); | 381 closeMediaSource(); |
| 387 | 382 |
| 388 removeElementFromDocumentMap(this, &document()); | 383 removeElementFromDocumentMap(this, &document()); |
| 389 | 384 |
| 390 // Destroying the player may cause a resource load to be canceled, | 385 // Destroying the player may cause a resource load to be canceled, |
| 391 // which could result in userCancelledLoad() being called back. | 386 // which could result in userCancelledLoad() being called back. |
| 392 // Setting m_isFinalizing ensures that such a call will not cause | 387 // Setting m_isFinalizing ensures that such a call will not cause |
| 393 // us to dispatch an abort event, which would result in a crash. | 388 // us to dispatch an abort event, which would result in a crash. |
| 394 // See http://crbug.com/233654 for more details. | 389 // See http://crbug.com/233654 for more details. |
| 395 m_isFinalizing = true; | 390 m_isFinalizing = true; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 if (name == srcAttr) { | 505 if (name == srcAttr) { |
| 511 // Trigger a reload, as long as the 'src' attribute is present. | 506 // Trigger a reload, as long as the 'src' attribute is present. |
| 512 if (!value.isNull()) { | 507 if (!value.isNull()) { |
| 513 clearMediaPlayer(LoadMediaResource); | 508 clearMediaPlayer(LoadMediaResource); |
| 514 scheduleDelayedAction(LoadMediaResource); | 509 scheduleDelayedAction(LoadMediaResource); |
| 515 } | 510 } |
| 516 } else if (name == controlsAttr) { | 511 } else if (name == controlsAttr) { |
| 517 configureMediaControls(); | 512 configureMediaControls(); |
| 518 } else if (name == preloadAttr) { | 513 } else if (name == preloadAttr) { |
| 519 setPlayerPreload(); | 514 setPlayerPreload(); |
| 520 } else if (name == mediagroupAttr && RuntimeEnabledFeatures::mediaController
Enabled()) { | |
| 521 setMediaGroup(value); | |
| 522 } else { | 515 } else { |
| 523 HTMLElement::parseAttribute(name, value); | 516 HTMLElement::parseAttribute(name, value); |
| 524 } | 517 } |
| 525 } | 518 } |
| 526 | 519 |
| 527 void HTMLMediaElement::finishParsingChildren() | 520 void HTMLMediaElement::finishParsingChildren() |
| 528 { | 521 { |
| 529 HTMLElement::finishParsingChildren(); | 522 HTMLElement::finishParsingChildren(); |
| 530 | 523 |
| 531 if (Traversal<HTMLTrackElement>::firstChild(*this)) | 524 if (Traversal<HTMLTrackElement>::firstChild(*this)) |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 780 // If this changed the official playback position, then queue a ta
sk to fire a simple event named timeupdate at the media element. | 773 // If this changed the official playback position, then queue a ta
sk to fire a simple event named timeupdate at the media element. |
| 781 // FIXME: Add support for firing this event. | 774 // FIXME: Add support for firing this event. |
| 782 | 775 |
| 783 // 4.8 - Set the initial playback position to 0. | 776 // 4.8 - Set the initial playback position to 0. |
| 784 // FIXME: Make this less subtle. The position only becomes 0 because the
ready state is HAVE_NOTHING. | 777 // FIXME: Make this less subtle. The position only becomes 0 because the
ready state is HAVE_NOTHING. |
| 785 invalidateCachedTime(); | 778 invalidateCachedTime(); |
| 786 | 779 |
| 787 // 4.9 - Set the timeline offset to Not-a-Number (NaN). | 780 // 4.9 - Set the timeline offset to Not-a-Number (NaN). |
| 788 // 4.10 - Update the duration attribute to Not-a-Number (NaN). | 781 // 4.10 - Update the duration attribute to Not-a-Number (NaN). |
| 789 | 782 |
| 790 | |
| 791 updateMediaController(); | |
| 792 cueTimeline().updateActiveCues(0); | 783 cueTimeline().updateActiveCues(0); |
| 793 } | 784 } |
| 794 | 785 |
| 795 // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRat
e attribute. | 786 // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRat
e attribute. |
| 796 setPlaybackRate(defaultPlaybackRate()); | 787 setPlaybackRate(defaultPlaybackRate()); |
| 797 | 788 |
| 798 // 6 - Set the error attribute to null and the autoplaying flag to true. | 789 // 6 - Set the error attribute to null and the autoplaying flag to true. |
| 799 m_error = nullptr; | 790 m_error = nullptr; |
| 800 m_autoplaying = true; | 791 m_autoplaying = true; |
| 801 | 792 |
| (...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1516 if (std::isnan(initialPlaybackPosition)) | 1507 if (std::isnan(initialPlaybackPosition)) |
| 1517 initialPlaybackPosition = 0; | 1508 initialPlaybackPosition = 0; |
| 1518 | 1509 |
| 1519 if (!jumped && initialPlaybackPosition > 0) { | 1510 if (!jumped && initialPlaybackPosition > 0) { |
| 1520 m_sentEndEvent = false; | 1511 m_sentEndEvent = false; |
| 1521 UseCounter::count(document(), UseCounter::HTMLMediaElementSeekToFrag
mentStart); | 1512 UseCounter::count(document(), UseCounter::HTMLMediaElementSeekToFrag
mentStart); |
| 1522 seek(initialPlaybackPosition); | 1513 seek(initialPlaybackPosition); |
| 1523 jumped = true; | 1514 jumped = true; |
| 1524 } | 1515 } |
| 1525 | 1516 |
| 1526 if (m_mediaController) { | |
| 1527 if (jumped && initialPlaybackPosition > m_mediaController->currentTi
me()) | |
| 1528 m_mediaController->setCurrentTime(initialPlaybackPosition); | |
| 1529 else | |
| 1530 seek(m_mediaController->currentTime()); | |
| 1531 } | |
| 1532 | |
| 1533 if (mediaControls()) | 1517 if (mediaControls()) |
| 1534 mediaControls()->reset(); | 1518 mediaControls()->reset(); |
| 1535 if (layoutObject()) | 1519 if (layoutObject()) |
| 1536 layoutObject()->updateFromElement(); | 1520 layoutObject()->updateFromElement(); |
| 1537 } | 1521 } |
| 1538 | 1522 |
| 1539 bool shouldUpdateDisplayState = false; | 1523 bool shouldUpdateDisplayState = false; |
| 1540 | 1524 |
| 1541 if (m_readyState >= HAVE_CURRENT_DATA && oldState < HAVE_CURRENT_DATA && !m_
haveFiredLoadedData) { | 1525 if (m_readyState >= HAVE_CURRENT_DATA && oldState < HAVE_CURRENT_DATA && !m_
haveFiredLoadedData) { |
| 1542 m_haveFiredLoadedData = true; | 1526 m_haveFiredLoadedData = true; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1579 shouldUpdateDisplayState = true; | 1563 shouldUpdateDisplayState = true; |
| 1580 } | 1564 } |
| 1581 | 1565 |
| 1582 if (shouldUpdateDisplayState) { | 1566 if (shouldUpdateDisplayState) { |
| 1583 updateDisplayState(); | 1567 updateDisplayState(); |
| 1584 if (mediaControls()) | 1568 if (mediaControls()) |
| 1585 mediaControls()->refreshClosedCaptionsButtonVisibility(); | 1569 mediaControls()->refreshClosedCaptionsButtonVisibility(); |
| 1586 } | 1570 } |
| 1587 | 1571 |
| 1588 updatePlayState(); | 1572 updatePlayState(); |
| 1589 updateMediaController(); | |
| 1590 cueTimeline().updateActiveCues(currentTime()); | 1573 cueTimeline().updateActiveCues(currentTime()); |
| 1591 } | 1574 } |
| 1592 | 1575 |
| 1593 void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*) | 1576 void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*) |
| 1594 { | 1577 { |
| 1595 if (m_networkState != NETWORK_LOADING) | 1578 if (m_networkState != NETWORK_LOADING) |
| 1596 return; | 1579 return; |
| 1597 | 1580 |
| 1598 double time = WTF::currentTime(); | 1581 double time = WTF::currentTime(); |
| 1599 double timedelta = time - m_previousProgressTime; | 1582 double timedelta = time - m_previousProgressTime; |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1776 WTF_LOG(Media, "HTMLMediaElement::currentTime(%p) - WARNING, cached
time is %f seconds off of media time when paused", this, delta); | 1759 WTF_LOG(Media, "HTMLMediaElement::currentTime(%p) - WARNING, cached
time is %f seconds off of media time when paused", this, delta); |
| 1777 #endif | 1760 #endif |
| 1778 return m_cachedTime; | 1761 return m_cachedTime; |
| 1779 } | 1762 } |
| 1780 | 1763 |
| 1781 refreshCachedTime(); | 1764 refreshCachedTime(); |
| 1782 | 1765 |
| 1783 return m_cachedTime; | 1766 return m_cachedTime; |
| 1784 } | 1767 } |
| 1785 | 1768 |
| 1786 void HTMLMediaElement::setCurrentTime(double time, ExceptionState& exceptionStat
e) | 1769 void HTMLMediaElement::setCurrentTime(double time) |
| 1787 { | 1770 { |
| 1788 if (m_mediaController) { | |
| 1789 exceptionState.throwDOMException(InvalidStateError, "The element is slav
ed to a MediaController."); | |
| 1790 return; | |
| 1791 } | |
| 1792 | |
| 1793 // If the media element's readyState is HAVE_NOTHING, then set the default | 1771 // If the media element's readyState is HAVE_NOTHING, then set the default |
| 1794 // playback start position to that time. | 1772 // playback start position to that time. |
| 1795 if (m_readyState == HAVE_NOTHING) { | 1773 if (m_readyState == HAVE_NOTHING) { |
| 1796 m_defaultPlaybackStartPosition = time; | 1774 m_defaultPlaybackStartPosition = time; |
| 1797 return; | 1775 return; |
| 1798 } | 1776 } |
| 1799 | 1777 |
| 1800 seek(time); | 1778 seek(time); |
| 1801 } | 1779 } |
| 1802 | 1780 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1854 | 1832 |
| 1855 if (m_playbackRate != rate) { | 1833 if (m_playbackRate != rate) { |
| 1856 m_playbackRate = rate; | 1834 m_playbackRate = rate; |
| 1857 invalidateCachedTime(); | 1835 invalidateCachedTime(); |
| 1858 scheduleEvent(EventTypeNames::ratechange); | 1836 scheduleEvent(EventTypeNames::ratechange); |
| 1859 } | 1837 } |
| 1860 | 1838 |
| 1861 updatePlaybackRate(); | 1839 updatePlaybackRate(); |
| 1862 } | 1840 } |
| 1863 | 1841 |
| 1864 double HTMLMediaElement::effectivePlaybackRate() const | |
| 1865 { | |
| 1866 return m_mediaController ? m_mediaController->playbackRate() : m_playbackRat
e; | |
| 1867 } | |
| 1868 | |
| 1869 HTMLMediaElement::DirectionOfPlayback HTMLMediaElement::directionOfPlayback() co
nst | 1842 HTMLMediaElement::DirectionOfPlayback HTMLMediaElement::directionOfPlayback() co
nst |
| 1870 { | 1843 { |
| 1871 return m_playbackRate >= 0 ? Forward : Backward; | 1844 return m_playbackRate >= 0 ? Forward : Backward; |
| 1872 } | 1845 } |
| 1873 | 1846 |
| 1874 void HTMLMediaElement::updatePlaybackRate() | 1847 void HTMLMediaElement::updatePlaybackRate() |
| 1875 { | 1848 { |
| 1876 double effectiveRate = effectivePlaybackRate(); | |
| 1877 // FIXME: remove m_webMediaPlayer check once we figure out how | 1849 // FIXME: remove m_webMediaPlayer check once we figure out how |
| 1878 // m_webMediaPlayer is going out of sync with readystate. | 1850 // m_webMediaPlayer is going out of sync with readystate. |
| 1879 // m_webMediaPlayer is cleared but readystate is not set to HAVE_NOTHING. | 1851 // m_webMediaPlayer is cleared but readystate is not set to HAVE_NOTHING. |
| 1880 if (m_webMediaPlayer && potentiallyPlaying()) | 1852 if (m_webMediaPlayer && potentiallyPlaying()) |
| 1881 webMediaPlayer()->setRate(effectiveRate); | 1853 webMediaPlayer()->setRate(playbackRate()); |
| 1882 } | 1854 } |
| 1883 | 1855 |
| 1884 bool HTMLMediaElement::ended() const | 1856 bool HTMLMediaElement::ended() const |
| 1885 { | 1857 { |
| 1886 // 4.8.10.8 Playing the media resource | 1858 // 4.8.10.8 Playing the media resource |
| 1887 // The ended attribute must return true if the media element has ended | 1859 // The ended attribute must return true if the media element has ended |
| 1888 // playback and the direction of playback is forwards, and false otherwise. | 1860 // playback and the direction of playback is forwards, and false otherwise. |
| 1889 return endedPlayback() && directionOfPlayback() == Forward; | 1861 return endedPlayback() && directionOfPlayback() == Forward; |
| 1890 } | 1862 } |
| 1891 | 1863 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1998 // 4.8.10.9. Playing the media resource | 1970 // 4.8.10.9. Playing the media resource |
| 1999 if (m_networkState == NETWORK_EMPTY) | 1971 if (m_networkState == NETWORK_EMPTY) |
| 2000 scheduleDelayedAction(LoadMediaResource); | 1972 scheduleDelayedAction(LoadMediaResource); |
| 2001 | 1973 |
| 2002 // Generally "ended" and "looping" are exclusive. Here, the loop attribute | 1974 // Generally "ended" and "looping" are exclusive. Here, the loop attribute |
| 2003 // is ignored to seek back to start in case loop was set after playback | 1975 // is ignored to seek back to start in case loop was set after playback |
| 2004 // ended. See http://crbug.com/364442 | 1976 // ended. See http://crbug.com/364442 |
| 2005 if (endedPlayback(LoopCondition::Ignored)) | 1977 if (endedPlayback(LoopCondition::Ignored)) |
| 2006 seek(0); | 1978 seek(0); |
| 2007 | 1979 |
| 2008 if (m_mediaController) | |
| 2009 m_mediaController->bringElementUpToSpeed(this); | |
| 2010 | |
| 2011 if (m_paused) { | 1980 if (m_paused) { |
| 2012 m_paused = false; | 1981 m_paused = false; |
| 2013 invalidateCachedTime(); | 1982 invalidateCachedTime(); |
| 2014 scheduleEvent(EventTypeNames::play); | 1983 scheduleEvent(EventTypeNames::play); |
| 2015 | 1984 |
| 2016 if (m_readyState <= HAVE_CURRENT_DATA) | 1985 if (m_readyState <= HAVE_CURRENT_DATA) |
| 2017 scheduleEvent(EventTypeNames::waiting); | 1986 scheduleEvent(EventTypeNames::waiting); |
| 2018 else if (m_readyState >= HAVE_FUTURE_DATA) | 1987 else if (m_readyState >= HAVE_FUTURE_DATA) |
| 2019 scheduleEvent(EventTypeNames::playing); | 1988 scheduleEvent(EventTypeNames::playing); |
| 2020 } | 1989 } |
| 2021 m_autoplaying = false; | 1990 m_autoplaying = false; |
| 2022 | 1991 |
| 2023 updatePlayState(); | 1992 updatePlayState(); |
| 2024 updateMediaController(); | |
| 2025 } | 1993 } |
| 2026 | 1994 |
| 2027 void HTMLMediaElement::autoplayMediaEncountered() | 1995 void HTMLMediaElement::autoplayMediaEncountered() |
| 2028 { | 1996 { |
| 2029 if (!m_autoplayMediaCounted) { | 1997 if (!m_autoplayMediaCounted) { |
| 2030 m_autoplayMediaCounted = true; | 1998 m_autoplayMediaCounted = true; |
| 2031 recordAutoplayMetric(AutoplayMediaFound); | 1999 recordAutoplayMetric(AutoplayMediaFound); |
| 2032 | 2000 |
| 2033 if (!m_userGestureRequiredForPlay) | 2001 if (!m_userGestureRequiredForPlay) |
| 2034 m_initialPlayWithoutUserGesture = true; | 2002 m_initialPlayWithoutUserGesture = true; |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2163 | 2131 |
| 2164 if (mediaControls()) | 2132 if (mediaControls()) |
| 2165 mediaControls()->updateVolume(); | 2133 mediaControls()->updateVolume(); |
| 2166 } | 2134 } |
| 2167 | 2135 |
| 2168 double HTMLMediaElement::effectiveMediaVolume() const | 2136 double HTMLMediaElement::effectiveMediaVolume() const |
| 2169 { | 2137 { |
| 2170 if (m_muted) | 2138 if (m_muted) |
| 2171 return 0; | 2139 return 0; |
| 2172 | 2140 |
| 2173 if (m_mediaController && m_mediaController->muted()) | 2141 return m_volume; |
| 2174 return 0; | |
| 2175 | |
| 2176 double volume = m_volume; | |
| 2177 | |
| 2178 if (m_mediaController) | |
| 2179 volume *= m_mediaController->volume(); | |
| 2180 | |
| 2181 return volume; | |
| 2182 } | 2142 } |
| 2183 | 2143 |
| 2184 // The spec says to fire periodic timeupdate events (those sent while playing) e
very | 2144 // The spec says to fire periodic timeupdate events (those sent while playing) e
very |
| 2185 // "15 to 250ms", we choose the slowest frequency | 2145 // "15 to 250ms", we choose the slowest frequency |
| 2186 static const double maxTimeupdateEventFrequency = 0.25; | 2146 static const double maxTimeupdateEventFrequency = 0.25; |
| 2187 | 2147 |
| 2188 void HTMLMediaElement::startPlaybackProgressTimer() | 2148 void HTMLMediaElement::startPlaybackProgressTimer() |
| 2189 { | 2149 { |
| 2190 if (m_playbackProgressTimer.isActive()) | 2150 if (m_playbackProgressTimer.isActive()) |
| 2191 return; | 2151 return; |
| 2192 | 2152 |
| 2193 m_previousProgressTime = WTF::currentTime(); | 2153 m_previousProgressTime = WTF::currentTime(); |
| 2194 m_playbackProgressTimer.startRepeating(maxTimeupdateEventFrequency, BLINK_FR
OM_HERE); | 2154 m_playbackProgressTimer.startRepeating(maxTimeupdateEventFrequency, BLINK_FR
OM_HERE); |
| 2195 } | 2155 } |
| 2196 | 2156 |
| 2197 void HTMLMediaElement::playbackProgressTimerFired(Timer<HTMLMediaElement>*) | 2157 void HTMLMediaElement::playbackProgressTimerFired(Timer<HTMLMediaElement>*) |
| 2198 { | 2158 { |
| 2199 if (!std::isnan(m_fragmentEndTime) && currentTime() >= m_fragmentEndTime &&
directionOfPlayback() == Forward) { | 2159 if (!std::isnan(m_fragmentEndTime) && currentTime() >= m_fragmentEndTime &&
directionOfPlayback() == Forward) { |
| 2200 m_fragmentEndTime = std::numeric_limits<double>::quiet_NaN(); | 2160 m_fragmentEndTime = std::numeric_limits<double>::quiet_NaN(); |
| 2201 if (!m_mediaController && !m_paused) { | 2161 if (!m_paused) { |
| 2202 UseCounter::count(document(), UseCounter::HTMLMediaElementPauseAtFra
gmentEnd); | 2162 UseCounter::count(document(), UseCounter::HTMLMediaElementPauseAtFra
gmentEnd); |
| 2203 // changes paused to true and fires a simple event named pause at th
e media element. | 2163 // changes paused to true and fires a simple event named pause at th
e media element. |
| 2204 pause(); | 2164 pause(); |
| 2205 } | 2165 } |
| 2206 } | 2166 } |
| 2207 | 2167 |
| 2208 if (!m_seeking) | 2168 if (!m_seeking) |
| 2209 scheduleTimeupdateEvent(true); | 2169 scheduleTimeupdateEvent(true); |
| 2210 | 2170 |
| 2211 if (!effectivePlaybackRate()) | 2171 if (!playbackRate()) |
| 2212 return; | 2172 return; |
| 2213 | 2173 |
| 2214 if (!m_paused && mediaControls()) | 2174 if (!m_paused && mediaControls()) |
| 2215 mediaControls()->playbackProgressed(); | 2175 mediaControls()->playbackProgressed(); |
| 2216 | 2176 |
| 2217 cueTimeline().updateActiveCues(currentTime()); | 2177 cueTimeline().updateActiveCues(currentTime()); |
| 2218 } | 2178 } |
| 2219 | 2179 |
| 2220 void HTMLMediaElement::scheduleTimeupdateEvent(bool periodicEvent) | 2180 void HTMLMediaElement::scheduleTimeupdateEvent(bool periodicEvent) |
| 2221 { | 2181 { |
| 2222 double now = WTF::currentTime(); | 2182 double now = WTF::currentTime(); |
| 2223 double movieTime = currentTime(); | 2183 double movieTime = currentTime(); |
| 2224 | 2184 |
| 2225 bool haveNotRecentlyFiredTimeupdate = (now - m_lastTimeUpdateEventWallTime)
>= maxTimeupdateEventFrequency; | 2185 bool haveNotRecentlyFiredTimeupdate = (now - m_lastTimeUpdateEventWallTime)
>= maxTimeupdateEventFrequency; |
| 2226 bool movieTimeHasProgressed = movieTime != m_lastTimeUpdateEventMovieTime; | 2186 bool movieTimeHasProgressed = movieTime != m_lastTimeUpdateEventMovieTime; |
| 2227 | 2187 |
| 2228 // Non-periodic timeupdate events must always fire as mandated by the spec, | 2188 // Non-periodic timeupdate events must always fire as mandated by the spec, |
| 2229 // otherwise we shouldn't fire duplicate periodic timeupdate events when the | 2189 // otherwise we shouldn't fire duplicate periodic timeupdate events when the |
| 2230 // movie time hasn't changed. | 2190 // movie time hasn't changed. |
| 2231 if (!periodicEvent || (haveNotRecentlyFiredTimeupdate && movieTimeHasProgres
sed)) { | 2191 if (!periodicEvent || (haveNotRecentlyFiredTimeupdate && movieTimeHasProgres
sed)) { |
| 2232 scheduleEvent(EventTypeNames::timeupdate); | 2192 scheduleEvent(EventTypeNames::timeupdate); |
| 2233 m_lastTimeUpdateEventWallTime = now; | 2193 m_lastTimeUpdateEventWallTime = now; |
| 2234 m_lastTimeUpdateEventMovieTime = movieTime; | 2194 m_lastTimeUpdateEventMovieTime = movieTime; |
| 2235 } | 2195 } |
| 2236 } | 2196 } |
| 2237 | 2197 |
| 2238 bool HTMLMediaElement::togglePlayStateWillPlay() const | |
| 2239 { | |
| 2240 if (m_mediaController) | |
| 2241 return m_mediaController->paused() || m_mediaController->isRestrained(); | |
| 2242 return paused(); | |
| 2243 } | |
| 2244 | |
| 2245 void HTMLMediaElement::togglePlayState() | 2198 void HTMLMediaElement::togglePlayState() |
| 2246 { | 2199 { |
| 2247 if (m_mediaController) { | 2200 if (paused()) |
| 2248 if (m_mediaController->isRestrained()) | 2201 play(); |
| 2249 m_mediaController->play(); | 2202 else |
| 2250 else if (m_mediaController->paused()) | 2203 pause(); |
| 2251 m_mediaController->unpause(); | |
| 2252 else | |
| 2253 m_mediaController->pause(); | |
| 2254 } else { | |
| 2255 if (paused()) | |
| 2256 play(); | |
| 2257 else | |
| 2258 pause(); | |
| 2259 } | |
| 2260 } | 2204 } |
| 2261 | 2205 |
| 2262 AudioTrackList& HTMLMediaElement::audioTracks() | 2206 AudioTrackList& HTMLMediaElement::audioTracks() |
| 2263 { | 2207 { |
| 2264 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled()); | 2208 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled()); |
| 2265 return *m_audioTracks; | 2209 return *m_audioTracks; |
| 2266 } | 2210 } |
| 2267 | 2211 |
| 2268 void HTMLMediaElement::audioTrackChanged() | 2212 void HTMLMediaElement::audioTrackChanged() |
| 2269 { | 2213 { |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2756 // it will only queue a 'timeupdate' event if we haven't already posted one
at the current | 2700 // it will only queue a 'timeupdate' event if we haven't already posted one
at the current |
| 2757 // movie time. | 2701 // movie time. |
| 2758 scheduleTimeupdateEvent(false); | 2702 scheduleTimeupdateEvent(false); |
| 2759 | 2703 |
| 2760 double now = currentTime(); | 2704 double now = currentTime(); |
| 2761 double dur = duration(); | 2705 double dur = duration(); |
| 2762 | 2706 |
| 2763 // When the current playback position reaches the end of the media resource
when the direction of | 2707 // When the current playback position reaches the end of the media resource
when the direction of |
| 2764 // playback is forwards, then the user agent must follow these steps: | 2708 // playback is forwards, then the user agent must follow these steps: |
| 2765 if (!std::isnan(dur) && dur && now >= dur && directionOfPlayback() == Forwar
d) { | 2709 if (!std::isnan(dur) && dur && now >= dur && directionOfPlayback() == Forwar
d) { |
| 2766 // If the media element has a loop attribute specified and does not have
a current media controller, | 2710 // If the media element has a loop attribute specified |
| 2767 if (loop() && !m_mediaController) { | 2711 if (loop()) { |
| 2768 m_sentEndEvent = false; | 2712 m_sentEndEvent = false; |
| 2769 // then seek to the earliest possible position of the media resourc
e and abort these steps. | 2713 // then seek to the earliest possible position of the media resourc
e and abort these steps. |
| 2770 seek(0); | 2714 seek(0); |
| 2771 } else { | 2715 } else { |
| 2772 // If the media element does not have a current media controller, an
d the media element | 2716 // If the media element has still ended playback, and the direction
of playback is still |
| 2773 // has still ended playback, and the direction of playback is still
forwards, and paused | 2717 // forwards, and paused is false, |
| 2774 // is false, | 2718 if (!m_paused) { |
| 2775 if (!m_mediaController && !m_paused) { | |
| 2776 // changes paused to true and fires a simple event named pause a
t the media element. | 2719 // changes paused to true and fires a simple event named pause a
t the media element. |
| 2777 m_paused = true; | 2720 m_paused = true; |
| 2778 scheduleEvent(EventTypeNames::pause); | 2721 scheduleEvent(EventTypeNames::pause); |
| 2779 } | 2722 } |
| 2780 // Queue a task to fire a simple event named ended at the media elem
ent. | 2723 // Queue a task to fire a simple event named ended at the media elem
ent. |
| 2781 if (!m_sentEndEvent) { | 2724 if (!m_sentEndEvent) { |
| 2782 m_sentEndEvent = true; | 2725 m_sentEndEvent = true; |
| 2783 scheduleEvent(EventTypeNames::ended); | 2726 scheduleEvent(EventTypeNames::ended); |
| 2784 } | 2727 } |
| 2785 recordMetricsIfPausing(); | 2728 recordMetricsIfPausing(); |
| 2786 // If the media element has a current media controller, then report
the controller state | |
| 2787 // for the media element's current media controller. | |
| 2788 updateMediaController(); | |
| 2789 } | 2729 } |
| 2790 } else { | 2730 } else { |
| 2791 m_sentEndEvent = false; | 2731 m_sentEndEvent = false; |
| 2792 } | 2732 } |
| 2793 | 2733 |
| 2794 updatePlayState(); | 2734 updatePlayState(); |
| 2795 } | 2735 } |
| 2796 | 2736 |
| 2797 void HTMLMediaElement::durationChanged() | 2737 void HTMLMediaElement::durationChanged() |
| 2798 { | 2738 { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2834 | 2774 |
| 2835 if (webMediaPlayer()->paused()) | 2775 if (webMediaPlayer()->paused()) |
| 2836 pause(); | 2776 pause(); |
| 2837 else | 2777 else |
| 2838 playInternal(); | 2778 playInternal(); |
| 2839 } | 2779 } |
| 2840 | 2780 |
| 2841 void HTMLMediaElement::requestSeek(double time) | 2781 void HTMLMediaElement::requestSeek(double time) |
| 2842 { | 2782 { |
| 2843 // The player is the source of this seek request. | 2783 // The player is the source of this seek request. |
| 2844 if (m_mediaController) { | 2784 setCurrentTime(time); |
| 2845 m_mediaController->setCurrentTime(time); | |
| 2846 return; | |
| 2847 } | |
| 2848 setCurrentTime(time, ASSERT_NO_EXCEPTION); | |
| 2849 } | 2785 } |
| 2850 | 2786 |
| 2851 void HTMLMediaElement::remoteRouteAvailabilityChanged(bool routesAvailable) | 2787 void HTMLMediaElement::remoteRouteAvailabilityChanged(bool routesAvailable) |
| 2852 { | 2788 { |
| 2853 m_remoteRoutesAvailable = routesAvailable; | 2789 m_remoteRoutesAvailable = routesAvailable; |
| 2854 if (mediaControls()) | 2790 if (mediaControls()) |
| 2855 mediaControls()->refreshCastButtonVisibility(); | 2791 mediaControls()->refreshCastButtonVisibility(); |
| 2856 } | 2792 } |
| 2857 | 2793 |
| 2858 void HTMLMediaElement::connectedToRemoteDevice() | 2794 void HTMLMediaElement::connectedToRemoteDevice() |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2927 | 2863 |
| 2928 return TimeRanges::create(webMediaPlayer()->seekable()); | 2864 return TimeRanges::create(webMediaPlayer()->seekable()); |
| 2929 } | 2865 } |
| 2930 | 2866 |
| 2931 bool HTMLMediaElement::potentiallyPlaying() const | 2867 bool HTMLMediaElement::potentiallyPlaying() const |
| 2932 { | 2868 { |
| 2933 // "pausedToBuffer" means the media engine's rate is 0, but only because it
had to stop playing | 2869 // "pausedToBuffer" means the media engine's rate is 0, but only because it
had to stop playing |
| 2934 // when it ran out of buffered data. A movie in this state is "potentially p
laying", modulo the | 2870 // when it ran out of buffered data. A movie in this state is "potentially p
laying", modulo the |
| 2935 // checks in couldPlayIfEnoughData(). | 2871 // checks in couldPlayIfEnoughData(). |
| 2936 bool pausedToBuffer = m_readyStateMaximum >= HAVE_FUTURE_DATA && m_readyStat
e < HAVE_FUTURE_DATA; | 2872 bool pausedToBuffer = m_readyStateMaximum >= HAVE_FUTURE_DATA && m_readyStat
e < HAVE_FUTURE_DATA; |
| 2937 return (pausedToBuffer || m_readyState >= HAVE_FUTURE_DATA) && couldPlayIfEn
oughData() && !isBlockedOnMediaController(); | 2873 return (pausedToBuffer || m_readyState >= HAVE_FUTURE_DATA) && couldPlayIfEn
oughData(); |
| 2938 } | 2874 } |
| 2939 | 2875 |
| 2940 bool HTMLMediaElement::couldPlayIfEnoughData() const | 2876 bool HTMLMediaElement::couldPlayIfEnoughData() const |
| 2941 { | 2877 { |
| 2942 return !paused() && !endedPlayback() && !stoppedDueToErrors(); | 2878 return !paused() && !endedPlayback() && !stoppedDueToErrors(); |
| 2943 } | 2879 } |
| 2944 | 2880 |
| 2945 bool HTMLMediaElement::endedPlayback(LoopCondition loopCondition) const | 2881 bool HTMLMediaElement::endedPlayback(LoopCondition loopCondition) const |
| 2946 { | 2882 { |
| 2947 double dur = duration(); | 2883 double dur = duration(); |
| 2948 if (std::isnan(dur)) | 2884 if (std::isnan(dur)) |
| 2949 return false; | 2885 return false; |
| 2950 | 2886 |
| 2951 // 4.8.10.8 Playing the media resource | 2887 // 4.8.10.8 Playing the media resource |
| 2952 | 2888 |
| 2953 // A media element is said to have ended playback when the element's | 2889 // A media element is said to have ended playback when the element's |
| 2954 // readyState attribute is HAVE_METADATA or greater, | 2890 // readyState attribute is HAVE_METADATA or greater, |
| 2955 if (m_readyState < HAVE_METADATA) | 2891 if (m_readyState < HAVE_METADATA) |
| 2956 return false; | 2892 return false; |
| 2957 | 2893 |
| 2958 // and the current playback position is the end of the media resource and th
e direction | 2894 // and the current playback position is the end of the media resource and th
e direction |
| 2959 // of playback is forwards, Either the media element does not have a loop at
tribute specified, | 2895 // of playback is forwards, Either the media element does not have a loop at
tribute specified, |
| 2960 // or the media element has a current media controller. | |
| 2961 double now = currentTime(); | 2896 double now = currentTime(); |
| 2962 if (directionOfPlayback() == Forward) | 2897 if (directionOfPlayback() == Forward) |
| 2963 return dur > 0 && now >= dur && (loopCondition == LoopCondition::Ignored
|| !loop() || m_mediaController); | 2898 return dur > 0 && now >= dur && (loopCondition == LoopCondition::Ignored
|| !loop()); |
| 2964 | 2899 |
| 2965 // or the current playback position is the earliest possible position and th
e direction | 2900 // or the current playback position is the earliest possible position and th
e direction |
| 2966 // of playback is backwards | 2901 // of playback is backwards |
| 2967 ASSERT(directionOfPlayback() == Backward); | 2902 ASSERT(directionOfPlayback() == Backward); |
| 2968 return now <= 0; | 2903 return now <= 0; |
| 2969 } | 2904 } |
| 2970 | 2905 |
| 2971 bool HTMLMediaElement::stoppedDueToErrors() const | 2906 bool HTMLMediaElement::stoppedDueToErrors() const |
| 2972 { | 2907 { |
| 2973 if (m_readyState >= HAVE_METADATA && m_error) { | 2908 if (m_readyState >= HAVE_METADATA && m_error) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2987 WTF_LOG(Media, "HTMLMediaElement::updatePlayState(%p) - shouldBePlaying = %s
, isPlaying = %s", | 2922 WTF_LOG(Media, "HTMLMediaElement::updatePlayState(%p) - shouldBePlaying = %s
, isPlaying = %s", |
| 2988 this, boolString(shouldBePlaying), boolString(isPlaying)); | 2923 this, boolString(shouldBePlaying), boolString(isPlaying)); |
| 2989 | 2924 |
| 2990 if (shouldBePlaying) { | 2925 if (shouldBePlaying) { |
| 2991 setDisplayMode(Video); | 2926 setDisplayMode(Video); |
| 2992 invalidateCachedTime(); | 2927 invalidateCachedTime(); |
| 2993 | 2928 |
| 2994 if (!isPlaying) { | 2929 if (!isPlaying) { |
| 2995 // Set rate, muted before calling play in case they were set before
the media engine was setup. | 2930 // Set rate, muted before calling play in case they were set before
the media engine was setup. |
| 2996 // The media engine should just stash the rate and muted values sinc
e it isn't already playing. | 2931 // The media engine should just stash the rate and muted values sinc
e it isn't already playing. |
| 2997 webMediaPlayer()->setRate(effectivePlaybackRate()); | 2932 webMediaPlayer()->setRate(playbackRate()); |
| 2998 updateVolume(); | 2933 updateVolume(); |
| 2999 webMediaPlayer()->play(); | 2934 webMediaPlayer()->play(); |
| 3000 } | 2935 } |
| 3001 | 2936 |
| 3002 if (mediaControls()) | 2937 if (mediaControls()) |
| 3003 mediaControls()->playbackStarted(); | 2938 mediaControls()->playbackStarted(); |
| 3004 startPlaybackProgressTimer(); | 2939 startPlaybackProgressTimer(); |
| 3005 m_playing = true; | 2940 m_playing = true; |
| 3006 recordAutoplayMetric(AnyPlaybackStarted); | 2941 recordAutoplayMetric(AnyPlaybackStarted); |
| 3007 | 2942 |
| 3008 } else { // Should not be playing right now | 2943 } else { // Should not be playing right now |
| 3009 if (isPlaying) | 2944 if (isPlaying) |
| 3010 webMediaPlayer()->pause(); | 2945 webMediaPlayer()->pause(); |
| 3011 refreshCachedTime(); | 2946 refreshCachedTime(); |
| 3012 | 2947 |
| 3013 m_playbackProgressTimer.stop(); | 2948 m_playbackProgressTimer.stop(); |
| 3014 m_playing = false; | 2949 m_playing = false; |
| 3015 double time = currentTime(); | 2950 double time = currentTime(); |
| 3016 if (time > m_lastSeekTime) | 2951 if (time > m_lastSeekTime) |
| 3017 addPlayedRange(m_lastSeekTime, time); | 2952 addPlayedRange(m_lastSeekTime, time); |
| 3018 | 2953 |
| 3019 if (couldPlayIfEnoughData()) | 2954 if (couldPlayIfEnoughData()) |
| 3020 prepareToPlay(); | 2955 prepareToPlay(); |
| 3021 | 2956 |
| 3022 if (mediaControls()) | 2957 if (mediaControls()) |
| 3023 mediaControls()->playbackStopped(); | 2958 mediaControls()->playbackStopped(); |
| 3024 } | 2959 } |
| 3025 | 2960 |
| 3026 updateMediaController(); | |
| 3027 | |
| 3028 if (layoutObject()) | 2961 if (layoutObject()) |
| 3029 layoutObject()->updateFromElement(); | 2962 layoutObject()->updateFromElement(); |
| 3030 } | 2963 } |
| 3031 | 2964 |
| 3032 void HTMLMediaElement::stopPeriodicTimers() | 2965 void HTMLMediaElement::stopPeriodicTimers() |
| 3033 { | 2966 { |
| 3034 m_progressEventTimer.stop(); | 2967 m_progressEventTimer.stop(); |
| 3035 m_playbackProgressTimer.stop(); | 2968 m_playbackProgressTimer.stop(); |
| 3036 } | 2969 } |
| 3037 | 2970 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3069 m_networkState = NETWORK_IDLE; | 3002 m_networkState = NETWORK_IDLE; |
| 3070 } | 3003 } |
| 3071 | 3004 |
| 3072 // 5 - Set the element's delaying-the-load-event flag to false. This stops d
elaying the load event. | 3005 // 5 - Set the element's delaying-the-load-event flag to false. This stops d
elaying the load event. |
| 3073 setShouldDelayLoadEvent(false); | 3006 setShouldDelayLoadEvent(false); |
| 3074 | 3007 |
| 3075 // 6 - Abort the overall resource selection algorithm. | 3008 // 6 - Abort the overall resource selection algorithm. |
| 3076 m_currentSourceNode = nullptr; | 3009 m_currentSourceNode = nullptr; |
| 3077 | 3010 |
| 3078 invalidateCachedTime(); | 3011 invalidateCachedTime(); |
| 3079 updateMediaController(); | |
| 3080 cueTimeline().updateActiveCues(0); | 3012 cueTimeline().updateActiveCues(0); |
| 3081 } | 3013 } |
| 3082 | 3014 |
| 3083 void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClientWithoutLockin
g() | 3015 void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClientWithoutLockin
g() |
| 3084 { | 3016 { |
| 3085 #if ENABLE(WEB_AUDIO) | 3017 #if ENABLE(WEB_AUDIO) |
| 3086 audioSourceProvider().setClient(nullptr); | 3018 audioSourceProvider().setClient(nullptr); |
| 3087 #endif | 3019 #endif |
| 3088 if (m_webMediaPlayer) { | 3020 if (m_webMediaPlayer) { |
| 3089 #if ENABLE(WEB_AUDIO) | 3021 #if ENABLE(WEB_AUDIO) |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3173 if (m_mediaSource) | 3105 if (m_mediaSource) |
| 3174 return true; | 3106 return true; |
| 3175 | 3107 |
| 3176 // Wait for any pending events to be fired. | 3108 // Wait for any pending events to be fired. |
| 3177 if (m_asyncEventQueue->hasPendingEvents()) | 3109 if (m_asyncEventQueue->hasPendingEvents()) |
| 3178 return true; | 3110 return true; |
| 3179 | 3111 |
| 3180 return false; | 3112 return false; |
| 3181 } | 3113 } |
| 3182 | 3114 |
| 3183 void HTMLMediaElement::contextDestroyed() | |
| 3184 { | |
| 3185 // With Oilpan the ExecutionContext is weakly referenced from the media | |
| 3186 // controller and so it will clear itself on destruction. | |
| 3187 #if !ENABLE(OILPAN) | |
| 3188 if (m_mediaController) | |
| 3189 m_mediaController->clearExecutionContext(); | |
| 3190 #endif | |
| 3191 ActiveDOMObject::contextDestroyed(); | |
| 3192 } | |
| 3193 | |
| 3194 bool HTMLMediaElement::isFullscreen() const | 3115 bool HTMLMediaElement::isFullscreen() const |
| 3195 { | 3116 { |
| 3196 return Fullscreen::isActiveFullScreenElement(*this); | 3117 return Fullscreen::isActiveFullScreenElement(*this); |
| 3197 } | 3118 } |
| 3198 | 3119 |
| 3199 void HTMLMediaElement::enterFullscreen() | 3120 void HTMLMediaElement::enterFullscreen() |
| 3200 { | 3121 { |
| 3201 WTF_LOG(Media, "HTMLMediaElement::enterFullscreen(%p)", this); | 3122 WTF_LOG(Media, "HTMLMediaElement::enterFullscreen(%p)", this); |
| 3202 | 3123 |
| 3203 Fullscreen::from(document()).requestFullscreen(*this, Fullscreen::PrefixedRe
quest); | 3124 Fullscreen::from(document()).requestFullscreen(*this, Fullscreen::PrefixedRe
quest); |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3526 void HTMLMediaElement::setAudioSourceNode(AudioSourceProviderClient* sourceNode) | 3447 void HTMLMediaElement::setAudioSourceNode(AudioSourceProviderClient* sourceNode) |
| 3527 { | 3448 { |
| 3528 ASSERT(isMainThread()); | 3449 ASSERT(isMainThread()); |
| 3529 m_audioSourceNode = sourceNode; | 3450 m_audioSourceNode = sourceNode; |
| 3530 | 3451 |
| 3531 AudioSourceProviderClientLockScope scope(*this); | 3452 AudioSourceProviderClientLockScope scope(*this); |
| 3532 audioSourceProvider().setClient(m_audioSourceNode); | 3453 audioSourceProvider().setClient(m_audioSourceNode); |
| 3533 } | 3454 } |
| 3534 #endif | 3455 #endif |
| 3535 | 3456 |
| 3536 const AtomicString& HTMLMediaElement::mediaGroup() const | |
| 3537 { | |
| 3538 return fastGetAttribute(mediagroupAttr); | |
| 3539 } | |
| 3540 | |
| 3541 void HTMLMediaElement::setMediaGroup(const AtomicString& group) | |
| 3542 { | |
| 3543 // When a media element is created with a mediagroup attribute, and when a m
edia element's mediagroup | |
| 3544 // attribute is set, changed, or removed, the user agent must run the follow
ing steps: | |
| 3545 // 1. Let _R [this] be the media element in question. | |
| 3546 // 2. Let m have no current media controller, if it currently has one. | |
| 3547 setControllerInternal(nullptr); | |
| 3548 | |
| 3549 // 3. If m's mediagroup attribute is being removed, then abort these steps. | |
| 3550 if (group.isNull() || group.isEmpty()) | |
| 3551 return; | |
| 3552 | |
| 3553 // 4. If there is another media element whose Document is the same as m's Do
cument (even if one or both | |
| 3554 // of these elements are not actually in the Document), | |
| 3555 WeakMediaElementSet elements = documentToElementSetMap().get(&document()); | |
| 3556 for (const auto& element : elements) { | |
| 3557 if (element == this) | |
| 3558 continue; | |
| 3559 | |
| 3560 // and which also has a mediagroup attribute, and whose mediagroup attri
bute has the same value as | |
| 3561 // the new value of m's mediagroup attribute, | |
| 3562 if (element->mediaGroup() == group) { | |
| 3563 // then let controller be that media element's current media contro
ller. | |
| 3564 setControllerInternal(element->controller()); | |
| 3565 return; | |
| 3566 } | |
| 3567 } | |
| 3568 | |
| 3569 // Otherwise, let controller be a newly created MediaController. | |
| 3570 setControllerInternal(MediaController::create(Node::executionContext())); | |
| 3571 } | |
| 3572 | |
| 3573 MediaController* HTMLMediaElement::controller() const | |
| 3574 { | |
| 3575 return m_mediaController.get(); | |
| 3576 } | |
| 3577 | |
| 3578 void HTMLMediaElement::setController(MediaController* controller) | |
| 3579 { | |
| 3580 // 4.8.10.11.2 Media controllers: controller attribute. | |
| 3581 // On setting, it must first remove the element's mediagroup attribute, if a
ny, | |
| 3582 removeAttribute(mediagroupAttr); | |
| 3583 // and then set the current media controller to the given value. | |
| 3584 setControllerInternal(controller); | |
| 3585 } | |
| 3586 | |
| 3587 void HTMLMediaElement::setControllerInternal(MediaController* controller) | |
| 3588 { | |
| 3589 if (m_mediaController) | |
| 3590 m_mediaController->removeMediaElement(this); | |
| 3591 | |
| 3592 m_mediaController = controller; | |
| 3593 | |
| 3594 if (m_mediaController) | |
| 3595 m_mediaController->addMediaElement(this); | |
| 3596 } | |
| 3597 | |
| 3598 void HTMLMediaElement::updateMediaController() | |
| 3599 { | |
| 3600 if (m_mediaController) | |
| 3601 m_mediaController->reportControllerState(); | |
| 3602 } | |
| 3603 | |
| 3604 bool HTMLMediaElement::isBlocked() const | |
| 3605 { | |
| 3606 // A media element is a blocked media element if its readyState attribute is
in the | |
| 3607 // HAVE_NOTHING state, the HAVE_METADATA state, or the HAVE_CURRENT_DATA sta
te, | |
| 3608 // or if the element has paused for user interaction or paused for in-band c
ontent. | |
| 3609 if (m_readyState <= HAVE_CURRENT_DATA) | |
| 3610 return true; | |
| 3611 | |
| 3612 return false; | |
| 3613 } | |
| 3614 | |
| 3615 bool HTMLMediaElement::isBlockedOnMediaController() const | |
| 3616 { | |
| 3617 if (!m_mediaController) | |
| 3618 return false; | |
| 3619 | |
| 3620 // A media element is blocked on its media controller if the MediaController
is a blocked | |
| 3621 // media controller, | |
| 3622 if (m_mediaController->isBlocked()) | |
| 3623 return true; | |
| 3624 | |
| 3625 // or if its media controller position is either before the media resource's
earliest possible | |
| 3626 // position relative to the MediaController's timeline or after the end of t
he media resource | |
| 3627 // relative to the MediaController's timeline. | |
| 3628 double mediaControllerPosition = m_mediaController->currentTime(); | |
| 3629 if (mediaControllerPosition < 0 || mediaControllerPosition > duration()) | |
| 3630 return true; | |
| 3631 | |
| 3632 return false; | |
| 3633 } | |
| 3634 | |
| 3635 void HTMLMediaElement::setAllowHiddenVolumeControls(bool allow) | 3457 void HTMLMediaElement::setAllowHiddenVolumeControls(bool allow) |
| 3636 { | 3458 { |
| 3637 ensureMediaControls(); | 3459 ensureMediaControls(); |
| 3638 mediaControls()->setAllowHiddenVolumeControls(allow); | 3460 mediaControls()->setAllowHiddenVolumeControls(allow); |
| 3639 } | 3461 } |
| 3640 | 3462 |
| 3641 WebMediaPlayer::CORSMode HTMLMediaElement::corsMode() const | 3463 WebMediaPlayer::CORSMode HTMLMediaElement::corsMode() const |
| 3642 { | 3464 { |
| 3643 const AtomicString& crossOriginMode = fastGetAttribute(crossoriginAttr); | 3465 const AtomicString& crossOriginMode = fastGetAttribute(crossoriginAttr); |
| 3644 if (crossOriginMode.isNull()) | 3466 if (crossOriginMode.isNull()) |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3694 visitor->trace(m_asyncEventQueue); | 3516 visitor->trace(m_asyncEventQueue); |
| 3695 visitor->trace(m_error); | 3517 visitor->trace(m_error); |
| 3696 visitor->trace(m_currentSourceNode); | 3518 visitor->trace(m_currentSourceNode); |
| 3697 visitor->trace(m_nextChildNodeToConsider); | 3519 visitor->trace(m_nextChildNodeToConsider); |
| 3698 visitor->trace(m_mediaSource); | 3520 visitor->trace(m_mediaSource); |
| 3699 visitor->trace(m_audioTracks); | 3521 visitor->trace(m_audioTracks); |
| 3700 visitor->trace(m_videoTracks); | 3522 visitor->trace(m_videoTracks); |
| 3701 visitor->trace(m_cueTimeline); | 3523 visitor->trace(m_cueTimeline); |
| 3702 visitor->trace(m_textTracks); | 3524 visitor->trace(m_textTracks); |
| 3703 visitor->trace(m_textTracksWhenResourceSelectionBegan); | 3525 visitor->trace(m_textTracksWhenResourceSelectionBegan); |
| 3704 visitor->trace(m_mediaController); | |
| 3705 #if ENABLE(WEB_AUDIO) | 3526 #if ENABLE(WEB_AUDIO) |
| 3706 visitor->trace(m_audioSourceProvider); | 3527 visitor->trace(m_audioSourceProvider); |
| 3707 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c
learWeakMembers>(this); | 3528 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c
learWeakMembers>(this); |
| 3708 #endif | 3529 #endif |
| 3709 HeapSupplementable<HTMLMediaElement>::trace(visitor); | 3530 HeapSupplementable<HTMLMediaElement>::trace(visitor); |
| 3710 #endif | 3531 #endif |
| 3711 HTMLElement::trace(visitor); | 3532 HTMLElement::trace(visitor); |
| 3712 ActiveDOMObject::trace(visitor); | 3533 ActiveDOMObject::trace(visitor); |
| 3713 } | 3534 } |
| 3714 | 3535 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3817 visitor->trace(m_client); | 3638 visitor->trace(m_client); |
| 3818 } | 3639 } |
| 3819 | 3640 |
| 3820 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) | 3641 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) |
| 3821 { | 3642 { |
| 3822 visitor->trace(m_client); | 3643 visitor->trace(m_client); |
| 3823 } | 3644 } |
| 3824 #endif | 3645 #endif |
| 3825 | 3646 |
| 3826 } | 3647 } |
| OLD | NEW |