Chromium Code Reviews| 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, FROM_HER E); | 2154 m_playbackProgressTimer.startRepeating(maxTimeupdateEventFrequency, FROM_HER E); |
| 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 |
|
philipj_slow
2015/10/07 10:05:17
I'm changing the comments in the way I imagine the
fs
2015/10/07 10:17:14
I guess you could just leave an indication that th
philipj_slow
2015/10/07 13:21:13
I had a look at the spec and noticed other differe
| |
| 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 |
|
philipj_slow
2015/10/07 10:05:17
Should rewrap this if not reverted to previous wor
| |
| 2773 // has still ended playback, and the direction of playback is still forwards, and paused | 2717 // has still ended playback, and the direction of playback is still forwards, and paused |
| 2774 // is false, | 2718 // is false, |
| 2775 if (!m_mediaController && !m_paused) { | 2719 if (!m_paused) { |
| 2776 // changes paused to true and fires a simple event named pause a t the media element. | 2720 // changes paused to true and fires a simple event named pause a t the media element. |
| 2777 m_paused = true; | 2721 m_paused = true; |
| 2778 scheduleEvent(EventTypeNames::pause); | 2722 scheduleEvent(EventTypeNames::pause); |
| 2779 } | 2723 } |
| 2780 // Queue a task to fire a simple event named ended at the media elem ent. | 2724 // Queue a task to fire a simple event named ended at the media elem ent. |
| 2781 if (!m_sentEndEvent) { | 2725 if (!m_sentEndEvent) { |
| 2782 m_sentEndEvent = true; | 2726 m_sentEndEvent = true; |
| 2783 scheduleEvent(EventTypeNames::ended); | 2727 scheduleEvent(EventTypeNames::ended); |
| 2784 } | 2728 } |
| 2785 recordMetricsIfPausing(); | 2729 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 } | 2730 } |
| 2790 } else { | 2731 } else { |
| 2791 m_sentEndEvent = false; | 2732 m_sentEndEvent = false; |
| 2792 } | 2733 } |
| 2793 | 2734 |
| 2794 updatePlayState(); | 2735 updatePlayState(); |
| 2795 } | 2736 } |
| 2796 | 2737 |
| 2797 void HTMLMediaElement::durationChanged() | 2738 void HTMLMediaElement::durationChanged() |
| 2798 { | 2739 { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2834 | 2775 |
| 2835 if (webMediaPlayer()->paused()) | 2776 if (webMediaPlayer()->paused()) |
| 2836 pause(); | 2777 pause(); |
| 2837 else | 2778 else |
| 2838 playInternal(); | 2779 playInternal(); |
| 2839 } | 2780 } |
| 2840 | 2781 |
| 2841 void HTMLMediaElement::requestSeek(double time) | 2782 void HTMLMediaElement::requestSeek(double time) |
| 2842 { | 2783 { |
| 2843 // The player is the source of this seek request. | 2784 // The player is the source of this seek request. |
| 2844 if (m_mediaController) { | 2785 setCurrentTime(time); |
| 2845 m_mediaController->setCurrentTime(time); | |
| 2846 return; | |
| 2847 } | |
| 2848 setCurrentTime(time, ASSERT_NO_EXCEPTION); | |
| 2849 } | 2786 } |
| 2850 | 2787 |
| 2851 void HTMLMediaElement::remoteRouteAvailabilityChanged(bool routesAvailable) | 2788 void HTMLMediaElement::remoteRouteAvailabilityChanged(bool routesAvailable) |
| 2852 { | 2789 { |
| 2853 m_remoteRoutesAvailable = routesAvailable; | 2790 m_remoteRoutesAvailable = routesAvailable; |
| 2854 if (mediaControls()) | 2791 if (mediaControls()) |
| 2855 mediaControls()->refreshCastButtonVisibility(); | 2792 mediaControls()->refreshCastButtonVisibility(); |
| 2856 } | 2793 } |
| 2857 | 2794 |
| 2858 void HTMLMediaElement::connectedToRemoteDevice() | 2795 void HTMLMediaElement::connectedToRemoteDevice() |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2927 | 2864 |
| 2928 return TimeRanges::create(webMediaPlayer()->seekable()); | 2865 return TimeRanges::create(webMediaPlayer()->seekable()); |
| 2929 } | 2866 } |
| 2930 | 2867 |
| 2931 bool HTMLMediaElement::potentiallyPlaying() const | 2868 bool HTMLMediaElement::potentiallyPlaying() const |
| 2932 { | 2869 { |
| 2933 // "pausedToBuffer" means the media engine's rate is 0, but only because it had to stop playing | 2870 // "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 | 2871 // when it ran out of buffered data. A movie in this state is "potentially p laying", modulo the |
| 2935 // checks in couldPlayIfEnoughData(). | 2872 // checks in couldPlayIfEnoughData(). |
| 2936 bool pausedToBuffer = m_readyStateMaximum >= HAVE_FUTURE_DATA && m_readyStat e < HAVE_FUTURE_DATA; | 2873 bool pausedToBuffer = m_readyStateMaximum >= HAVE_FUTURE_DATA && m_readyStat e < HAVE_FUTURE_DATA; |
| 2937 return (pausedToBuffer || m_readyState >= HAVE_FUTURE_DATA) && couldPlayIfEn oughData() && !isBlockedOnMediaController(); | 2874 return (pausedToBuffer || m_readyState >= HAVE_FUTURE_DATA) && couldPlayIfEn oughData(); |
| 2938 } | 2875 } |
| 2939 | 2876 |
| 2940 bool HTMLMediaElement::couldPlayIfEnoughData() const | 2877 bool HTMLMediaElement::couldPlayIfEnoughData() const |
| 2941 { | 2878 { |
| 2942 return !paused() && !endedPlayback() && !stoppedDueToErrors(); | 2879 return !paused() && !endedPlayback() && !stoppedDueToErrors(); |
| 2943 } | 2880 } |
| 2944 | 2881 |
| 2945 bool HTMLMediaElement::endedPlayback(LoopCondition loopCondition) const | 2882 bool HTMLMediaElement::endedPlayback(LoopCondition loopCondition) const |
| 2946 { | 2883 { |
| 2947 double dur = duration(); | 2884 double dur = duration(); |
| 2948 if (std::isnan(dur)) | 2885 if (std::isnan(dur)) |
| 2949 return false; | 2886 return false; |
| 2950 | 2887 |
| 2951 // 4.8.10.8 Playing the media resource | 2888 // 4.8.10.8 Playing the media resource |
| 2952 | 2889 |
| 2953 // A media element is said to have ended playback when the element's | 2890 // A media element is said to have ended playback when the element's |
| 2954 // readyState attribute is HAVE_METADATA or greater, | 2891 // readyState attribute is HAVE_METADATA or greater, |
| 2955 if (m_readyState < HAVE_METADATA) | 2892 if (m_readyState < HAVE_METADATA) |
| 2956 return false; | 2893 return false; |
| 2957 | 2894 |
| 2958 // and the current playback position is the end of the media resource and th e direction | 2895 // 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, | 2896 // 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(); | 2897 double now = currentTime(); |
| 2962 if (directionOfPlayback() == Forward) | 2898 if (directionOfPlayback() == Forward) |
| 2963 return dur > 0 && now >= dur && (loopCondition == LoopCondition::Ignored || !loop() || m_mediaController); | 2899 return dur > 0 && now >= dur && (loopCondition == LoopCondition::Ignored || !loop()); |
| 2964 | 2900 |
| 2965 // or the current playback position is the earliest possible position and th e direction | 2901 // or the current playback position is the earliest possible position and th e direction |
| 2966 // of playback is backwards | 2902 // of playback is backwards |
| 2967 ASSERT(directionOfPlayback() == Backward); | 2903 ASSERT(directionOfPlayback() == Backward); |
| 2968 return now <= 0; | 2904 return now <= 0; |
| 2969 } | 2905 } |
| 2970 | 2906 |
| 2971 bool HTMLMediaElement::stoppedDueToErrors() const | 2907 bool HTMLMediaElement::stoppedDueToErrors() const |
| 2972 { | 2908 { |
| 2973 if (m_readyState >= HAVE_METADATA && m_error) { | 2909 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", | 2923 WTF_LOG(Media, "HTMLMediaElement::updatePlayState(%p) - shouldBePlaying = %s , isPlaying = %s", |
| 2988 this, boolString(shouldBePlaying), boolString(isPlaying)); | 2924 this, boolString(shouldBePlaying), boolString(isPlaying)); |
| 2989 | 2925 |
| 2990 if (shouldBePlaying) { | 2926 if (shouldBePlaying) { |
| 2991 setDisplayMode(Video); | 2927 setDisplayMode(Video); |
| 2992 invalidateCachedTime(); | 2928 invalidateCachedTime(); |
| 2993 | 2929 |
| 2994 if (!isPlaying) { | 2930 if (!isPlaying) { |
| 2995 // Set rate, muted before calling play in case they were set before the media engine was setup. | 2931 // 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. | 2932 // The media engine should just stash the rate and muted values sinc e it isn't already playing. |
| 2997 webMediaPlayer()->setRate(effectivePlaybackRate()); | 2933 webMediaPlayer()->setRate(playbackRate()); |
| 2998 updateVolume(); | 2934 updateVolume(); |
| 2999 webMediaPlayer()->play(); | 2935 webMediaPlayer()->play(); |
| 3000 } | 2936 } |
| 3001 | 2937 |
| 3002 if (mediaControls()) | 2938 if (mediaControls()) |
| 3003 mediaControls()->playbackStarted(); | 2939 mediaControls()->playbackStarted(); |
| 3004 startPlaybackProgressTimer(); | 2940 startPlaybackProgressTimer(); |
| 3005 m_playing = true; | 2941 m_playing = true; |
| 3006 recordAutoplayMetric(AnyPlaybackStarted); | 2942 recordAutoplayMetric(AnyPlaybackStarted); |
| 3007 | 2943 |
| 3008 } else { // Should not be playing right now | 2944 } else { // Should not be playing right now |
| 3009 if (isPlaying) | 2945 if (isPlaying) |
| 3010 webMediaPlayer()->pause(); | 2946 webMediaPlayer()->pause(); |
| 3011 refreshCachedTime(); | 2947 refreshCachedTime(); |
| 3012 | 2948 |
| 3013 m_playbackProgressTimer.stop(); | 2949 m_playbackProgressTimer.stop(); |
| 3014 m_playing = false; | 2950 m_playing = false; |
| 3015 double time = currentTime(); | 2951 double time = currentTime(); |
| 3016 if (time > m_lastSeekTime) | 2952 if (time > m_lastSeekTime) |
| 3017 addPlayedRange(m_lastSeekTime, time); | 2953 addPlayedRange(m_lastSeekTime, time); |
| 3018 | 2954 |
| 3019 if (couldPlayIfEnoughData()) | 2955 if (couldPlayIfEnoughData()) |
| 3020 prepareToPlay(); | 2956 prepareToPlay(); |
| 3021 | 2957 |
| 3022 if (mediaControls()) | 2958 if (mediaControls()) |
| 3023 mediaControls()->playbackStopped(); | 2959 mediaControls()->playbackStopped(); |
| 3024 } | 2960 } |
| 3025 | 2961 |
| 3026 updateMediaController(); | |
| 3027 | |
| 3028 if (layoutObject()) | 2962 if (layoutObject()) |
| 3029 layoutObject()->updateFromElement(); | 2963 layoutObject()->updateFromElement(); |
| 3030 } | 2964 } |
| 3031 | 2965 |
| 3032 void HTMLMediaElement::stopPeriodicTimers() | 2966 void HTMLMediaElement::stopPeriodicTimers() |
| 3033 { | 2967 { |
| 3034 m_progressEventTimer.stop(); | 2968 m_progressEventTimer.stop(); |
| 3035 m_playbackProgressTimer.stop(); | 2969 m_playbackProgressTimer.stop(); |
| 3036 } | 2970 } |
| 3037 | 2971 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 3066 | 3000 |
| 3067 // 5 - Set the element's delaying-the-load-event flag to false. This stops d elaying the load event. | 3001 // 5 - Set the element's delaying-the-load-event flag to false. This stops d elaying the load event. |
| 3068 setShouldDelayLoadEvent(false); | 3002 setShouldDelayLoadEvent(false); |
| 3069 | 3003 |
| 3070 // 6 - Abort the overall resource selection algorithm. | 3004 // 6 - Abort the overall resource selection algorithm. |
| 3071 m_currentSourceNode = nullptr; | 3005 m_currentSourceNode = nullptr; |
| 3072 | 3006 |
| 3073 // Reset m_readyState since m_webMediaPlayer is gone. | 3007 // Reset m_readyState since m_webMediaPlayer is gone. |
| 3074 m_readyState = HAVE_NOTHING; | 3008 m_readyState = HAVE_NOTHING; |
| 3075 invalidateCachedTime(); | 3009 invalidateCachedTime(); |
| 3076 updateMediaController(); | |
| 3077 cueTimeline().updateActiveCues(0); | 3010 cueTimeline().updateActiveCues(0); |
| 3078 } | 3011 } |
| 3079 | 3012 |
| 3080 void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClientWithoutLockin g() | 3013 void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClientWithoutLockin g() |
| 3081 { | 3014 { |
| 3082 #if ENABLE(WEB_AUDIO) | 3015 #if ENABLE(WEB_AUDIO) |
| 3083 audioSourceProvider().setClient(nullptr); | 3016 audioSourceProvider().setClient(nullptr); |
| 3084 #endif | 3017 #endif |
| 3085 if (m_webMediaPlayer) { | 3018 if (m_webMediaPlayer) { |
| 3086 #if ENABLE(WEB_AUDIO) | 3019 #if ENABLE(WEB_AUDIO) |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3170 if (m_mediaSource) | 3103 if (m_mediaSource) |
| 3171 return true; | 3104 return true; |
| 3172 | 3105 |
| 3173 // Wait for any pending events to be fired. | 3106 // Wait for any pending events to be fired. |
| 3174 if (m_asyncEventQueue->hasPendingEvents()) | 3107 if (m_asyncEventQueue->hasPendingEvents()) |
| 3175 return true; | 3108 return true; |
| 3176 | 3109 |
| 3177 return false; | 3110 return false; |
| 3178 } | 3111 } |
| 3179 | 3112 |
| 3180 void HTMLMediaElement::contextDestroyed() | |
| 3181 { | |
| 3182 // With Oilpan the ExecutionContext is weakly referenced from the media | |
| 3183 // controller and so it will clear itself on destruction. | |
| 3184 #if !ENABLE(OILPAN) | |
| 3185 if (m_mediaController) | |
| 3186 m_mediaController->clearExecutionContext(); | |
| 3187 #endif | |
| 3188 ActiveDOMObject::contextDestroyed(); | |
| 3189 } | |
| 3190 | |
| 3191 bool HTMLMediaElement::isFullscreen() const | 3113 bool HTMLMediaElement::isFullscreen() const |
| 3192 { | 3114 { |
| 3193 return Fullscreen::isActiveFullScreenElement(*this); | 3115 return Fullscreen::isActiveFullScreenElement(*this); |
| 3194 } | 3116 } |
| 3195 | 3117 |
| 3196 void HTMLMediaElement::enterFullscreen() | 3118 void HTMLMediaElement::enterFullscreen() |
| 3197 { | 3119 { |
| 3198 WTF_LOG(Media, "HTMLMediaElement::enterFullscreen(%p)", this); | 3120 WTF_LOG(Media, "HTMLMediaElement::enterFullscreen(%p)", this); |
| 3199 | 3121 |
| 3200 Fullscreen::from(document()).requestFullscreen(*this, Fullscreen::PrefixedRe quest); | 3122 Fullscreen::from(document()).requestFullscreen(*this, Fullscreen::PrefixedRe quest); |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3523 void HTMLMediaElement::setAudioSourceNode(AudioSourceProviderClient* sourceNode) | 3445 void HTMLMediaElement::setAudioSourceNode(AudioSourceProviderClient* sourceNode) |
| 3524 { | 3446 { |
| 3525 ASSERT(isMainThread()); | 3447 ASSERT(isMainThread()); |
| 3526 m_audioSourceNode = sourceNode; | 3448 m_audioSourceNode = sourceNode; |
| 3527 | 3449 |
| 3528 AudioSourceProviderClientLockScope scope(*this); | 3450 AudioSourceProviderClientLockScope scope(*this); |
| 3529 audioSourceProvider().setClient(m_audioSourceNode); | 3451 audioSourceProvider().setClient(m_audioSourceNode); |
| 3530 } | 3452 } |
| 3531 #endif | 3453 #endif |
| 3532 | 3454 |
| 3533 const AtomicString& HTMLMediaElement::mediaGroup() const | |
| 3534 { | |
| 3535 return fastGetAttribute(mediagroupAttr); | |
| 3536 } | |
| 3537 | |
| 3538 void HTMLMediaElement::setMediaGroup(const AtomicString& group) | |
| 3539 { | |
| 3540 // When a media element is created with a mediagroup attribute, and when a m edia element's mediagroup | |
| 3541 // attribute is set, changed, or removed, the user agent must run the follow ing steps: | |
| 3542 // 1. Let _R [this] be the media element in question. | |
| 3543 // 2. Let m have no current media controller, if it currently has one. | |
| 3544 setControllerInternal(nullptr); | |
| 3545 | |
| 3546 // 3. If m's mediagroup attribute is being removed, then abort these steps. | |
| 3547 if (group.isNull() || group.isEmpty()) | |
| 3548 return; | |
| 3549 | |
| 3550 // 4. If there is another media element whose Document is the same as m's Do cument (even if one or both | |
| 3551 // of these elements are not actually in the Document), | |
| 3552 WeakMediaElementSet elements = documentToElementSetMap().get(&document()); | |
| 3553 for (const auto& element : elements) { | |
| 3554 if (element == this) | |
| 3555 continue; | |
| 3556 | |
| 3557 // and which also has a mediagroup attribute, and whose mediagroup attri bute has the same value as | |
| 3558 // the new value of m's mediagroup attribute, | |
| 3559 if (element->mediaGroup() == group) { | |
| 3560 // then let controller be that media element's current media contro ller. | |
| 3561 setControllerInternal(element->controller()); | |
| 3562 return; | |
| 3563 } | |
| 3564 } | |
| 3565 | |
| 3566 // Otherwise, let controller be a newly created MediaController. | |
| 3567 setControllerInternal(MediaController::create(Node::executionContext())); | |
| 3568 } | |
| 3569 | |
| 3570 MediaController* HTMLMediaElement::controller() const | |
| 3571 { | |
| 3572 return m_mediaController.get(); | |
| 3573 } | |
| 3574 | |
| 3575 void HTMLMediaElement::setController(MediaController* controller) | |
| 3576 { | |
| 3577 // 4.8.10.11.2 Media controllers: controller attribute. | |
| 3578 // On setting, it must first remove the element's mediagroup attribute, if a ny, | |
| 3579 removeAttribute(mediagroupAttr); | |
| 3580 // and then set the current media controller to the given value. | |
| 3581 setControllerInternal(controller); | |
| 3582 } | |
| 3583 | |
| 3584 void HTMLMediaElement::setControllerInternal(MediaController* controller) | |
| 3585 { | |
| 3586 if (m_mediaController) | |
| 3587 m_mediaController->removeMediaElement(this); | |
| 3588 | |
| 3589 m_mediaController = controller; | |
| 3590 | |
| 3591 if (m_mediaController) | |
| 3592 m_mediaController->addMediaElement(this); | |
| 3593 } | |
| 3594 | |
| 3595 void HTMLMediaElement::updateMediaController() | |
| 3596 { | |
| 3597 if (m_mediaController) | |
| 3598 m_mediaController->reportControllerState(); | |
| 3599 } | |
| 3600 | |
| 3601 bool HTMLMediaElement::isBlocked() const | |
| 3602 { | |
| 3603 // A media element is a blocked media element if its readyState attribute is in the | |
| 3604 // HAVE_NOTHING state, the HAVE_METADATA state, or the HAVE_CURRENT_DATA sta te, | |
| 3605 // or if the element has paused for user interaction or paused for in-band c ontent. | |
| 3606 if (m_readyState <= HAVE_CURRENT_DATA) | |
| 3607 return true; | |
| 3608 | |
| 3609 return false; | |
| 3610 } | |
| 3611 | |
| 3612 bool HTMLMediaElement::isBlockedOnMediaController() const | |
| 3613 { | |
| 3614 if (!m_mediaController) | |
| 3615 return false; | |
| 3616 | |
| 3617 // A media element is blocked on its media controller if the MediaController is a blocked | |
| 3618 // media controller, | |
| 3619 if (m_mediaController->isBlocked()) | |
| 3620 return true; | |
| 3621 | |
| 3622 // or if its media controller position is either before the media resource's earliest possible | |
| 3623 // position relative to the MediaController's timeline or after the end of t he media resource | |
| 3624 // relative to the MediaController's timeline. | |
| 3625 double mediaControllerPosition = m_mediaController->currentTime(); | |
| 3626 if (mediaControllerPosition < 0 || mediaControllerPosition > duration()) | |
| 3627 return true; | |
| 3628 | |
| 3629 return false; | |
| 3630 } | |
| 3631 | |
| 3632 void HTMLMediaElement::setAllowHiddenVolumeControls(bool allow) | 3455 void HTMLMediaElement::setAllowHiddenVolumeControls(bool allow) |
| 3633 { | 3456 { |
| 3634 ensureMediaControls(); | 3457 ensureMediaControls(); |
| 3635 mediaControls()->setAllowHiddenVolumeControls(allow); | 3458 mediaControls()->setAllowHiddenVolumeControls(allow); |
| 3636 } | 3459 } |
| 3637 | 3460 |
| 3638 WebMediaPlayer::CORSMode HTMLMediaElement::corsMode() const | 3461 WebMediaPlayer::CORSMode HTMLMediaElement::corsMode() const |
| 3639 { | 3462 { |
| 3640 const AtomicString& crossOriginMode = fastGetAttribute(crossoriginAttr); | 3463 const AtomicString& crossOriginMode = fastGetAttribute(crossoriginAttr); |
| 3641 if (crossOriginMode.isNull()) | 3464 if (crossOriginMode.isNull()) |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3691 visitor->trace(m_asyncEventQueue); | 3514 visitor->trace(m_asyncEventQueue); |
| 3692 visitor->trace(m_error); | 3515 visitor->trace(m_error); |
| 3693 visitor->trace(m_currentSourceNode); | 3516 visitor->trace(m_currentSourceNode); |
| 3694 visitor->trace(m_nextChildNodeToConsider); | 3517 visitor->trace(m_nextChildNodeToConsider); |
| 3695 visitor->trace(m_mediaSource); | 3518 visitor->trace(m_mediaSource); |
| 3696 visitor->trace(m_audioTracks); | 3519 visitor->trace(m_audioTracks); |
| 3697 visitor->trace(m_videoTracks); | 3520 visitor->trace(m_videoTracks); |
| 3698 visitor->trace(m_cueTimeline); | 3521 visitor->trace(m_cueTimeline); |
| 3699 visitor->trace(m_textTracks); | 3522 visitor->trace(m_textTracks); |
| 3700 visitor->trace(m_textTracksWhenResourceSelectionBegan); | 3523 visitor->trace(m_textTracksWhenResourceSelectionBegan); |
| 3701 visitor->trace(m_mediaController); | |
| 3702 #if ENABLE(WEB_AUDIO) | 3524 #if ENABLE(WEB_AUDIO) |
| 3703 visitor->trace(m_audioSourceProvider); | 3525 visitor->trace(m_audioSourceProvider); |
| 3704 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c learWeakMembers>(this); | 3526 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c learWeakMembers>(this); |
| 3705 #endif | 3527 #endif |
| 3706 HeapSupplementable<HTMLMediaElement>::trace(visitor); | 3528 HeapSupplementable<HTMLMediaElement>::trace(visitor); |
| 3707 #endif | 3529 #endif |
| 3708 HTMLElement::trace(visitor); | 3530 HTMLElement::trace(visitor); |
| 3709 ActiveDOMObject::trace(visitor); | 3531 ActiveDOMObject::trace(visitor); |
| 3710 } | 3532 } |
| 3711 | 3533 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3814 visitor->trace(m_client); | 3636 visitor->trace(m_client); |
| 3815 } | 3637 } |
| 3816 | 3638 |
| 3817 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) | 3639 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) |
| 3818 { | 3640 { |
| 3819 visitor->trace(m_client); | 3641 visitor->trace(m_client); |
| 3820 } | 3642 } |
| 3821 #endif | 3643 #endif |
| 3822 | 3644 |
| 3823 } | 3645 } |
| OLD | NEW |