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 23 matching lines...) Expand all Loading... |
34 #include "core/css/MediaList.h" | 34 #include "core/css/MediaList.h" |
35 #include "core/dom/Attribute.h" | 35 #include "core/dom/Attribute.h" |
36 #include "core/dom/ElementTraversal.h" | 36 #include "core/dom/ElementTraversal.h" |
37 #include "core/dom/ExceptionCode.h" | 37 #include "core/dom/ExceptionCode.h" |
38 #include "core/events/Event.h" | 38 #include "core/events/Event.h" |
39 #include "core/frame/LocalFrame.h" | 39 #include "core/frame/LocalFrame.h" |
40 #include "core/frame/Settings.h" | 40 #include "core/frame/Settings.h" |
41 #include "core/frame/UseCounter.h" | 41 #include "core/frame/UseCounter.h" |
42 #include "core/html/HTMLMediaSource.h" | 42 #include "core/html/HTMLMediaSource.h" |
43 #include "core/html/HTMLSourceElement.h" | 43 #include "core/html/HTMLSourceElement.h" |
44 #include "core/html/MediaController.h" | |
45 #include "core/html/MediaError.h" | 44 #include "core/html/MediaError.h" |
46 #include "core/html/MediaFragmentURIParser.h" | 45 #include "core/html/MediaFragmentURIParser.h" |
47 #include "core/html/TimeRanges.h" | 46 #include "core/html/TimeRanges.h" |
48 #include "core/rendering/RenderVideo.h" | 47 #include "core/rendering/RenderVideo.h" |
49 #include "core/rendering/RenderView.h" | 48 #include "core/rendering/RenderView.h" |
50 #include "core/rendering/compositing/RenderLayerCompositor.h" | 49 #include "core/rendering/compositing/RenderLayerCompositor.h" |
51 #include "platform/ContentType.h" | 50 #include "platform/ContentType.h" |
52 #include "platform/Language.h" | 51 #include "platform/Language.h" |
53 #include "platform/Logging.h" | 52 #include "platform/Logging.h" |
54 #include "platform/MIMETypeFromURL.h" | 53 #include "platform/MIMETypeFromURL.h" |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 // destructed ActiveDOMObject::executionContext() returns 0. | 254 // destructed ActiveDOMObject::executionContext() returns 0. |
256 if (ActiveDOMObject::executionContext()) | 255 if (ActiveDOMObject::executionContext()) |
257 setShouldDelayLoadEvent(false); | 256 setShouldDelayLoadEvent(false); |
258 #else | 257 #else |
259 // HTMLMediaElement and m_asyncEventQueue always become unreachable | 258 // HTMLMediaElement and m_asyncEventQueue always become unreachable |
260 // together. So HTMLMediaElemenet and m_asyncEventQueue are destructed in | 259 // together. So HTMLMediaElemenet and m_asyncEventQueue are destructed in |
261 // the same GC. We don't need to close it explicitly in Oilpan. | 260 // the same GC. We don't need to close it explicitly in Oilpan. |
262 m_asyncEventQueue->close(); | 261 m_asyncEventQueue->close(); |
263 | 262 |
264 setShouldDelayLoadEvent(false); | 263 setShouldDelayLoadEvent(false); |
265 | |
266 if (m_mediaController) { | |
267 m_mediaController->removeMediaElement(this); | |
268 m_mediaController = nullptr; | |
269 } | |
270 #endif | 264 #endif |
271 | 265 |
272 #if ENABLE(OILPAN) | 266 #if ENABLE(OILPAN) |
273 if (m_closeMediaSourceWhenFinalizing) | 267 if (m_closeMediaSourceWhenFinalizing) |
274 closeMediaSource(); | 268 closeMediaSource(); |
275 #else | 269 #else |
276 closeMediaSource(); | 270 closeMediaSource(); |
277 | 271 |
278 removeElementFromDocumentMap(this, &document()); | 272 removeElementFromDocumentMap(this, &document()); |
279 #endif | 273 #endif |
(...skipping 930 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1210 | 1204 |
1211 scheduleEvent(EventTypeNames::canplaythrough); | 1205 scheduleEvent(EventTypeNames::canplaythrough); |
1212 | 1206 |
1213 shouldUpdateDisplayState = true; | 1207 shouldUpdateDisplayState = true; |
1214 } | 1208 } |
1215 | 1209 |
1216 if (shouldUpdateDisplayState) | 1210 if (shouldUpdateDisplayState) |
1217 updateDisplayState(); | 1211 updateDisplayState(); |
1218 | 1212 |
1219 updatePlayState(); | 1213 updatePlayState(); |
1220 updateMediaController(); | |
1221 } | 1214 } |
1222 | 1215 |
1223 void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*) | 1216 void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*) |
1224 { | 1217 { |
1225 ASSERT(m_player); | 1218 ASSERT(m_player); |
1226 if (m_networkState != NETWORK_LOADING) | 1219 if (m_networkState != NETWORK_LOADING) |
1227 return; | 1220 return; |
1228 | 1221 |
1229 double time = WTF::currentTime(); | 1222 double time = WTF::currentTime(); |
1230 double timedelta = time - m_previousProgressTime; | 1223 double timedelta = time - m_previousProgressTime; |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1424 return m_cachedTime; | 1417 return m_cachedTime; |
1425 } | 1418 } |
1426 | 1419 |
1427 refreshCachedTime(); | 1420 refreshCachedTime(); |
1428 | 1421 |
1429 return m_cachedTime; | 1422 return m_cachedTime; |
1430 } | 1423 } |
1431 | 1424 |
1432 void HTMLMediaElement::setCurrentTime(double time, ExceptionState& exceptionStat
e) | 1425 void HTMLMediaElement::setCurrentTime(double time, ExceptionState& exceptionStat
e) |
1433 { | 1426 { |
1434 if (m_mediaController) { | |
1435 exceptionState.throwDOMException(InvalidStateError, "The element is slav
ed to a MediaController."); | |
1436 return; | |
1437 } | |
1438 seek(time, exceptionState); | 1427 seek(time, exceptionState); |
1439 } | 1428 } |
1440 | 1429 |
1441 double HTMLMediaElement::duration() const | 1430 double HTMLMediaElement::duration() const |
1442 { | 1431 { |
1443 // FIXME: remove m_player check once we figure out how m_player is going | 1432 // FIXME: remove m_player check once we figure out how m_player is going |
1444 // out of sync with readystate. m_player is cleared but readystate is not se
t | 1433 // out of sync with readystate. m_player is cleared but readystate is not se
t |
1445 // to HAVE_NOTHING | 1434 // to HAVE_NOTHING |
1446 if (!m_player || m_readyState < HAVE_METADATA) | 1435 if (!m_player || m_readyState < HAVE_METADATA) |
1447 return std::numeric_limits<double>::quiet_NaN(); | 1436 return std::numeric_limits<double>::quiet_NaN(); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1494 m_playbackRate = rate; | 1483 m_playbackRate = rate; |
1495 invalidateCachedTime(); | 1484 invalidateCachedTime(); |
1496 scheduleEvent(EventTypeNames::ratechange); | 1485 scheduleEvent(EventTypeNames::ratechange); |
1497 } | 1486 } |
1498 | 1487 |
1499 updatePlaybackRate(); | 1488 updatePlaybackRate(); |
1500 } | 1489 } |
1501 | 1490 |
1502 double HTMLMediaElement::effectivePlaybackRate() const | 1491 double HTMLMediaElement::effectivePlaybackRate() const |
1503 { | 1492 { |
1504 return m_mediaController ? m_mediaController->playbackRate() : m_playbackRat
e; | 1493 return m_playbackRate; |
1505 } | 1494 } |
1506 | 1495 |
1507 HTMLMediaElement::DirectionOfPlayback HTMLMediaElement::directionOfPlayback() co
nst | 1496 HTMLMediaElement::DirectionOfPlayback HTMLMediaElement::directionOfPlayback() co
nst |
1508 { | 1497 { |
1509 return m_playbackRate >= 0 ? Forward : Backward; | 1498 return m_playbackRate >= 0 ? Forward : Backward; |
1510 } | 1499 } |
1511 | 1500 |
1512 void HTMLMediaElement::updatePlaybackRate() | 1501 void HTMLMediaElement::updatePlaybackRate() |
1513 { | 1502 { |
1514 double effectiveRate = effectivePlaybackRate(); | 1503 double effectiveRate = effectivePlaybackRate(); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1569 { | 1558 { |
1570 WTF_LOG(Media, "HTMLMediaElement::playInternal"); | 1559 WTF_LOG(Media, "HTMLMediaElement::playInternal"); |
1571 | 1560 |
1572 // 4.8.10.9. Playing the media resource | 1561 // 4.8.10.9. Playing the media resource |
1573 if (!m_player || m_networkState == NETWORK_EMPTY) | 1562 if (!m_player || m_networkState == NETWORK_EMPTY) |
1574 scheduleDelayedAction(LoadMediaResource); | 1563 scheduleDelayedAction(LoadMediaResource); |
1575 | 1564 |
1576 if (endedPlayback()) | 1565 if (endedPlayback()) |
1577 seek(0, IGNORE_EXCEPTION); | 1566 seek(0, IGNORE_EXCEPTION); |
1578 | 1567 |
1579 if (m_mediaController) | |
1580 m_mediaController->bringElementUpToSpeed(this); | |
1581 | |
1582 if (m_paused) { | 1568 if (m_paused) { |
1583 m_paused = false; | 1569 m_paused = false; |
1584 invalidateCachedTime(); | 1570 invalidateCachedTime(); |
1585 scheduleEvent(EventTypeNames::play); | 1571 scheduleEvent(EventTypeNames::play); |
1586 | 1572 |
1587 if (m_readyState <= HAVE_CURRENT_DATA) | 1573 if (m_readyState <= HAVE_CURRENT_DATA) |
1588 scheduleEvent(EventTypeNames::waiting); | 1574 scheduleEvent(EventTypeNames::waiting); |
1589 else if (m_readyState >= HAVE_FUTURE_DATA) | 1575 else if (m_readyState >= HAVE_FUTURE_DATA) |
1590 scheduleEvent(EventTypeNames::playing); | 1576 scheduleEvent(EventTypeNames::playing); |
1591 } | 1577 } |
1592 m_autoplaying = false; | 1578 m_autoplaying = false; |
1593 | 1579 |
1594 updatePlayState(); | 1580 updatePlayState(); |
1595 updateMediaController(); | |
1596 } | 1581 } |
1597 | 1582 |
1598 void HTMLMediaElement::pause() | 1583 void HTMLMediaElement::pause() |
1599 { | 1584 { |
1600 WTF_LOG(Media, "HTMLMediaElement::pause()"); | 1585 WTF_LOG(Media, "HTMLMediaElement::pause()"); |
1601 | 1586 |
1602 if (!m_player || m_networkState == NETWORK_EMPTY) | 1587 if (!m_player || m_networkState == NETWORK_EMPTY) |
1603 scheduleDelayedAction(LoadMediaResource); | 1588 scheduleDelayedAction(LoadMediaResource); |
1604 | 1589 |
1605 m_autoplaying = false; | 1590 m_autoplaying = false; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1678 { | 1663 { |
1679 if (webMediaPlayer()) | 1664 if (webMediaPlayer()) |
1680 webMediaPlayer()->setVolume(effectiveMediaVolume()); | 1665 webMediaPlayer()->setVolume(effectiveMediaVolume()); |
1681 } | 1666 } |
1682 | 1667 |
1683 double HTMLMediaElement::effectiveMediaVolume() const | 1668 double HTMLMediaElement::effectiveMediaVolume() const |
1684 { | 1669 { |
1685 if (m_muted) | 1670 if (m_muted) |
1686 return 0; | 1671 return 0; |
1687 | 1672 |
1688 if (m_mediaController && m_mediaController->muted()) | 1673 return m_volume; |
1689 return 0; | |
1690 | |
1691 double volume = m_volume; | |
1692 | |
1693 if (m_mediaController) | |
1694 volume *= m_mediaController->volume(); | |
1695 | |
1696 return volume; | |
1697 } | 1674 } |
1698 | 1675 |
1699 // The spec says to fire periodic timeupdate events (those sent while playing) e
very | 1676 // The spec says to fire periodic timeupdate events (those sent while playing) e
very |
1700 // "15 to 250ms", we choose the slowest frequency | 1677 // "15 to 250ms", we choose the slowest frequency |
1701 static const double maxTimeupdateEventFrequency = 0.25; | 1678 static const double maxTimeupdateEventFrequency = 0.25; |
1702 | 1679 |
1703 void HTMLMediaElement::startPlaybackProgressTimer() | 1680 void HTMLMediaElement::startPlaybackProgressTimer() |
1704 { | 1681 { |
1705 if (m_playbackProgressTimer.isActive()) | 1682 if (m_playbackProgressTimer.isActive()) |
1706 return; | 1683 return; |
1707 | 1684 |
1708 m_previousProgressTime = WTF::currentTime(); | 1685 m_previousProgressTime = WTF::currentTime(); |
1709 m_playbackProgressTimer.startRepeating(maxTimeupdateEventFrequency, FROM_HER
E); | 1686 m_playbackProgressTimer.startRepeating(maxTimeupdateEventFrequency, FROM_HER
E); |
1710 } | 1687 } |
1711 | 1688 |
1712 void HTMLMediaElement::playbackProgressTimerFired(Timer<HTMLMediaElement>*) | 1689 void HTMLMediaElement::playbackProgressTimerFired(Timer<HTMLMediaElement>*) |
1713 { | 1690 { |
1714 ASSERT(m_player); | 1691 ASSERT(m_player); |
1715 | 1692 |
1716 if (m_fragmentEndTime != MediaPlayer::invalidTime() && currentTime() >= m_fr
agmentEndTime && directionOfPlayback() == Forward) { | 1693 if (m_fragmentEndTime != MediaPlayer::invalidTime() && currentTime() >= m_fr
agmentEndTime && directionOfPlayback() == Forward) { |
1717 m_fragmentEndTime = MediaPlayer::invalidTime(); | 1694 m_fragmentEndTime = MediaPlayer::invalidTime(); |
1718 if (!m_mediaController && !m_paused) { | 1695 if (!m_paused) { |
1719 UseCounter::count(document(), UseCounter::HTMLMediaElementPauseAtFra
gmentEnd); | 1696 UseCounter::count(document(), UseCounter::HTMLMediaElementPauseAtFra
gmentEnd); |
1720 // changes paused to true and fires a simple event named pause at th
e media element. | 1697 // changes paused to true and fires a simple event named pause at th
e media element. |
1721 pause(); | 1698 pause(); |
1722 } | 1699 } |
1723 } | 1700 } |
1724 | 1701 |
1725 if (!m_seeking) | 1702 if (!m_seeking) |
1726 scheduleTimeupdateEvent(true); | 1703 scheduleTimeupdateEvent(true); |
1727 } | 1704 } |
1728 | 1705 |
(...skipping 11 matching lines...) Expand all Loading... |
1740 double movieTime = currentTime(); | 1717 double movieTime = currentTime(); |
1741 if (movieTime != m_lastTimeUpdateEventMovieTime) { | 1718 if (movieTime != m_lastTimeUpdateEventMovieTime) { |
1742 scheduleEvent(EventTypeNames::timeupdate); | 1719 scheduleEvent(EventTypeNames::timeupdate); |
1743 m_lastTimeUpdateEventWallTime = now; | 1720 m_lastTimeUpdateEventWallTime = now; |
1744 m_lastTimeUpdateEventMovieTime = movieTime; | 1721 m_lastTimeUpdateEventMovieTime = movieTime; |
1745 } | 1722 } |
1746 } | 1723 } |
1747 | 1724 |
1748 bool HTMLMediaElement::togglePlayStateWillPlay() const | 1725 bool HTMLMediaElement::togglePlayStateWillPlay() const |
1749 { | 1726 { |
1750 if (m_mediaController) | |
1751 return m_mediaController->paused() || m_mediaController->isRestrained(); | |
1752 return paused(); | 1727 return paused(); |
1753 } | 1728 } |
1754 | 1729 |
1755 void HTMLMediaElement::togglePlayState() | 1730 void HTMLMediaElement::togglePlayState() |
1756 { | 1731 { |
1757 if (m_mediaController) { | 1732 if (paused()) |
1758 if (m_mediaController->isRestrained()) | 1733 play(); |
1759 m_mediaController->play(); | 1734 else |
1760 else if (m_mediaController->paused()) | 1735 pause(); |
1761 m_mediaController->unpause(); | |
1762 else | |
1763 m_mediaController->pause(); | |
1764 } else { | |
1765 if (paused()) | |
1766 play(); | |
1767 else | |
1768 pause(); | |
1769 } | |
1770 } | 1736 } |
1771 | 1737 |
1772 bool HTMLMediaElement::havePotentialSourceChild() | 1738 bool HTMLMediaElement::havePotentialSourceChild() |
1773 { | 1739 { |
1774 // Stash the current <source> node and next nodes so we can restore them aft
er checking | 1740 // Stash the current <source> node and next nodes so we can restore them aft
er checking |
1775 // to see there is another potential. | 1741 // to see there is another potential. |
1776 RefPtrWillBeRawPtr<HTMLSourceElement> currentSourceNode = m_currentSourceNod
e; | 1742 RefPtrWillBeRawPtr<HTMLSourceElement> currentSourceNode = m_currentSourceNod
e; |
1777 RefPtrWillBeRawPtr<Node> nextNode = m_nextChildNodeToConsider; | 1743 RefPtrWillBeRawPtr<Node> nextNode = m_nextChildNodeToConsider; |
1778 | 1744 |
1779 KURL nextURL = selectNextSourceChild(0, 0, DoNothing); | 1745 KURL nextURL = selectNextSourceChild(0, 0, DoNothing); |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1967 // movie time. | 1933 // movie time. |
1968 scheduleTimeupdateEvent(false); | 1934 scheduleTimeupdateEvent(false); |
1969 | 1935 |
1970 double now = currentTime(); | 1936 double now = currentTime(); |
1971 double dur = duration(); | 1937 double dur = duration(); |
1972 | 1938 |
1973 // When the current playback position reaches the end of the media resource
when the direction of | 1939 // When the current playback position reaches the end of the media resource
when the direction of |
1974 // playback is forwards, then the user agent must follow these steps: | 1940 // playback is forwards, then the user agent must follow these steps: |
1975 if (!std::isnan(dur) && dur && now >= dur && directionOfPlayback() == Forwar
d) { | 1941 if (!std::isnan(dur) && dur && now >= dur && directionOfPlayback() == Forwar
d) { |
1976 // If the media element has a loop attribute specified and does not have
a current media controller, | 1942 // If the media element has a loop attribute specified and does not have
a current media controller, |
1977 if (loop() && !m_mediaController) { | 1943 if (loop()) { |
1978 m_sentEndEvent = false; | 1944 m_sentEndEvent = false; |
1979 // then seek to the earliest possible position of the media resourc
e and abort these steps. | 1945 // then seek to the earliest possible position of the media resourc
e and abort these steps. |
1980 seek(0, IGNORE_EXCEPTION); | 1946 seek(0, IGNORE_EXCEPTION); |
1981 } else { | 1947 } else { |
1982 // If the media element does not have a current media controller, an
d the media element | 1948 // If the media element does not have a current media controller, an
d the media element |
1983 // has still ended playback, and the direction of playback is still
forwards, and paused | 1949 // has still ended playback, and the direction of playback is still
forwards, and paused |
1984 // is false, | 1950 // is false, |
1985 if (!m_mediaController && !m_paused) { | 1951 if (!m_paused) { |
1986 // changes paused to true and fires a simple event named pause a
t the media element. | 1952 // changes paused to true and fires a simple event named pause a
t the media element. |
1987 m_paused = true; | 1953 m_paused = true; |
1988 scheduleEvent(EventTypeNames::pause); | 1954 scheduleEvent(EventTypeNames::pause); |
1989 } | 1955 } |
1990 // Queue a task to fire a simple event named ended at the media elem
ent. | 1956 // Queue a task to fire a simple event named ended at the media elem
ent. |
1991 if (!m_sentEndEvent) { | 1957 if (!m_sentEndEvent) { |
1992 m_sentEndEvent = true; | 1958 m_sentEndEvent = true; |
1993 scheduleEvent(EventTypeNames::ended); | 1959 scheduleEvent(EventTypeNames::ended); |
1994 } | 1960 } |
1995 // If the media element has a current media controller, then report
the controller state | |
1996 // for the media element's current media controller. | |
1997 updateMediaController(); | |
1998 } | 1961 } |
1999 } | 1962 } |
2000 else | 1963 else |
2001 m_sentEndEvent = false; | 1964 m_sentEndEvent = false; |
2002 | 1965 |
2003 updatePlayState(); | 1966 updatePlayState(); |
2004 } | 1967 } |
2005 | 1968 |
2006 void HTMLMediaElement::mediaPlayerDurationChanged() | 1969 void HTMLMediaElement::mediaPlayerDurationChanged() |
2007 { | 1970 { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2045 playInternal(); | 2008 playInternal(); |
2046 } | 2009 } |
2047 | 2010 |
2048 void HTMLMediaElement::mediaPlayerRequestFullscreen() | 2011 void HTMLMediaElement::mediaPlayerRequestFullscreen() |
2049 { | 2012 { |
2050 // FIXME(sky): How do we go full screen now? | 2013 // FIXME(sky): How do we go full screen now? |
2051 } | 2014 } |
2052 | 2015 |
2053 void HTMLMediaElement::mediaPlayerRequestSeek(double time) | 2016 void HTMLMediaElement::mediaPlayerRequestSeek(double time) |
2054 { | 2017 { |
2055 // The player is the source of this seek request. | |
2056 if (m_mediaController) { | |
2057 m_mediaController->setCurrentTime(time, IGNORE_EXCEPTION); | |
2058 return; | |
2059 } | |
2060 setCurrentTime(time, IGNORE_EXCEPTION); | 2018 setCurrentTime(time, IGNORE_EXCEPTION); |
2061 } | 2019 } |
2062 | 2020 |
2063 // MediaPlayerPresentation methods | 2021 // MediaPlayerPresentation methods |
2064 void HTMLMediaElement::mediaPlayerRepaint() | 2022 void HTMLMediaElement::mediaPlayerRepaint() |
2065 { | 2023 { |
2066 if (m_webLayer) | 2024 if (m_webLayer) |
2067 m_webLayer->invalidate(); | 2025 m_webLayer->invalidate(); |
2068 | 2026 |
2069 updateDisplayState(); | 2027 updateDisplayState(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2117 } | 2075 } |
2118 return TimeRanges::create(); | 2076 return TimeRanges::create(); |
2119 } | 2077 } |
2120 | 2078 |
2121 bool HTMLMediaElement::potentiallyPlaying() const | 2079 bool HTMLMediaElement::potentiallyPlaying() const |
2122 { | 2080 { |
2123 // "pausedToBuffer" means the media engine's rate is 0, but only because it
had to stop playing | 2081 // "pausedToBuffer" means the media engine's rate is 0, but only because it
had to stop playing |
2124 // when it ran out of buffered data. A movie is this state is "potentially p
laying", modulo the | 2082 // when it ran out of buffered data. A movie is this state is "potentially p
laying", modulo the |
2125 // checks in couldPlayIfEnoughData(). | 2083 // checks in couldPlayIfEnoughData(). |
2126 bool pausedToBuffer = m_readyStateMaximum >= HAVE_FUTURE_DATA && m_readyStat
e < HAVE_FUTURE_DATA; | 2084 bool pausedToBuffer = m_readyStateMaximum >= HAVE_FUTURE_DATA && m_readyStat
e < HAVE_FUTURE_DATA; |
2127 return (pausedToBuffer || m_readyState >= HAVE_FUTURE_DATA) && couldPlayIfEn
oughData() && !isBlockedOnMediaController(); | 2085 return (pausedToBuffer || m_readyState >= HAVE_FUTURE_DATA) && couldPlayIfEn
oughData(); |
2128 } | 2086 } |
2129 | 2087 |
2130 bool HTMLMediaElement::couldPlayIfEnoughData() const | 2088 bool HTMLMediaElement::couldPlayIfEnoughData() const |
2131 { | 2089 { |
2132 return !paused() && !endedPlayback() && !stoppedDueToErrors(); | 2090 return !paused() && !endedPlayback() && !stoppedDueToErrors(); |
2133 } | 2091 } |
2134 | 2092 |
2135 bool HTMLMediaElement::endedPlayback() const | 2093 bool HTMLMediaElement::endedPlayback() const |
2136 { | 2094 { |
2137 double dur = duration(); | 2095 double dur = duration(); |
2138 if (!m_player || std::isnan(dur)) | 2096 if (!m_player || std::isnan(dur)) |
2139 return false; | 2097 return false; |
2140 | 2098 |
2141 // 4.8.10.8 Playing the media resource | 2099 // 4.8.10.8 Playing the media resource |
2142 | 2100 |
2143 // A media element is said to have ended playback when the element's | 2101 // A media element is said to have ended playback when the element's |
2144 // readyState attribute is HAVE_METADATA or greater, | 2102 // readyState attribute is HAVE_METADATA or greater, |
2145 if (m_readyState < HAVE_METADATA) | 2103 if (m_readyState < HAVE_METADATA) |
2146 return false; | 2104 return false; |
2147 | 2105 |
2148 // and the current playback position is the end of the media resource and th
e direction | 2106 // and the current playback position is the end of the media resource and th
e direction |
2149 // of playback is forwards, Either the media element does not have a loop at
tribute specified, | 2107 // of playback is forwards, Either the media element does not have a loop at
tribute specified, |
2150 // or the media element has a current media controller. | 2108 // or the media element has a current media controller. |
2151 double now = currentTime(); | 2109 double now = currentTime(); |
2152 if (directionOfPlayback() == Forward) | 2110 if (directionOfPlayback() == Forward) |
2153 return dur > 0 && now >= dur && (!loop() || m_mediaController); | 2111 return dur > 0 && now >= dur && !loop(); |
2154 | 2112 |
2155 // or the current playback position is the earliest possible position and th
e direction | 2113 // or the current playback position is the earliest possible position and th
e direction |
2156 // of playback is backwards | 2114 // of playback is backwards |
2157 ASSERT(directionOfPlayback() == Backward); | 2115 ASSERT(directionOfPlayback() == Backward); |
2158 return now <= 0; | 2116 return now <= 0; |
2159 } | 2117 } |
2160 | 2118 |
2161 bool HTMLMediaElement::stoppedDueToErrors() const | 2119 bool HTMLMediaElement::stoppedDueToErrors() const |
2162 { | 2120 { |
2163 if (m_readyState >= HAVE_METADATA && m_error) { | 2121 if (m_readyState >= HAVE_METADATA && m_error) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2211 m_playbackProgressTimer.stop(); | 2169 m_playbackProgressTimer.stop(); |
2212 m_playing = false; | 2170 m_playing = false; |
2213 double time = currentTime(); | 2171 double time = currentTime(); |
2214 if (time > m_lastSeekTime) | 2172 if (time > m_lastSeekTime) |
2215 addPlayedRange(m_lastSeekTime, time); | 2173 addPlayedRange(m_lastSeekTime, time); |
2216 | 2174 |
2217 if (couldPlayIfEnoughData()) | 2175 if (couldPlayIfEnoughData()) |
2218 prepareToPlay(); | 2176 prepareToPlay(); |
2219 } | 2177 } |
2220 | 2178 |
2221 updateMediaController(); | |
2222 | |
2223 if (renderer()) | 2179 if (renderer()) |
2224 renderer()->updateFromElement(); | 2180 renderer()->updateFromElement(); |
2225 } | 2181 } |
2226 | 2182 |
2227 void HTMLMediaElement::setPausedInternal(bool b) | 2183 void HTMLMediaElement::setPausedInternal(bool b) |
2228 { | 2184 { |
2229 m_pausedInternal = b; | 2185 m_pausedInternal = b; |
2230 updatePlayState(); | 2186 updatePlayState(); |
2231 } | 2187 } |
2232 | 2188 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2269 | 2225 |
2270 // 5 - Set the element's delaying-the-load-event flag to false. This stops d
elaying the load event. | 2226 // 5 - Set the element's delaying-the-load-event flag to false. This stops d
elaying the load event. |
2271 setShouldDelayLoadEvent(false); | 2227 setShouldDelayLoadEvent(false); |
2272 | 2228 |
2273 // 6 - Abort the overall resource selection algorithm. | 2229 // 6 - Abort the overall resource selection algorithm. |
2274 m_currentSourceNode = nullptr; | 2230 m_currentSourceNode = nullptr; |
2275 | 2231 |
2276 // Reset m_readyState since m_player is gone. | 2232 // Reset m_readyState since m_player is gone. |
2277 m_readyState = HAVE_NOTHING; | 2233 m_readyState = HAVE_NOTHING; |
2278 invalidateCachedTime(); | 2234 invalidateCachedTime(); |
2279 updateMediaController(); | |
2280 } | 2235 } |
2281 | 2236 |
2282 void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClientWithoutLockin
g() | 2237 void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClientWithoutLockin
g() |
2283 { | 2238 { |
2284 m_player.clear(); | 2239 m_player.clear(); |
2285 } | 2240 } |
2286 | 2241 |
2287 void HTMLMediaElement::clearMediaPlayer(int flags) | 2242 void HTMLMediaElement::clearMediaPlayer(int flags) |
2288 { | 2243 { |
2289 closeMediaSource(); | 2244 closeMediaSource(); |
(...skipping 28 matching lines...) Expand all Loading... |
2318 m_asyncEventQueue->close(); | 2273 m_asyncEventQueue->close(); |
2319 } | 2274 } |
2320 | 2275 |
2321 bool HTMLMediaElement::hasPendingActivity() const | 2276 bool HTMLMediaElement::hasPendingActivity() const |
2322 { | 2277 { |
2323 return (hasAudio() && isPlaying()) || m_asyncEventQueue->hasPendingEvents(); | 2278 return (hasAudio() && isPlaying()) || m_asyncEventQueue->hasPendingEvents(); |
2324 } | 2279 } |
2325 | 2280 |
2326 void HTMLMediaElement::contextDestroyed() | 2281 void HTMLMediaElement::contextDestroyed() |
2327 { | 2282 { |
2328 // With Oilpan the ExecutionContext is weakly referenced from the media | |
2329 // controller and so it will clear itself on destruction. | |
2330 #if !ENABLE(OILPAN) | |
2331 if (m_mediaController) | |
2332 m_mediaController->clearExecutionContext(); | |
2333 #endif | |
2334 ActiveDOMObject::contextDestroyed(); | 2283 ActiveDOMObject::contextDestroyed(); |
2335 } | 2284 } |
2336 | 2285 |
2337 bool HTMLMediaElement::isFullscreen() const | 2286 bool HTMLMediaElement::isFullscreen() const |
2338 { | 2287 { |
2339 // FIXME(sky): How does video go full screen now? | 2288 // FIXME(sky): How does video go full screen now? |
2340 return false; | 2289 return false; |
2341 } | 2290 } |
2342 | 2291 |
2343 void HTMLMediaElement::enterFullscreen() | 2292 void HTMLMediaElement::enterFullscreen() |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2381 { | 2330 { |
2382 closeMediaSource(); | 2331 closeMediaSource(); |
2383 m_player = MediaPlayer::create(this); | 2332 m_player = MediaPlayer::create(this); |
2384 } | 2333 } |
2385 | 2334 |
2386 const AtomicString& HTMLMediaElement::mediaGroup() const | 2335 const AtomicString& HTMLMediaElement::mediaGroup() const |
2387 { | 2336 { |
2388 return getAttribute(HTMLNames::mediagroupAttr); | 2337 return getAttribute(HTMLNames::mediagroupAttr); |
2389 } | 2338 } |
2390 | 2339 |
2391 void HTMLMediaElement::setMediaGroup(const AtomicString& group) | |
2392 { | |
2393 // When a media element is created with a mediagroup attribute, and when a m
edia element's mediagroup | |
2394 // attribute is set, changed, or removed, the user agent must run the follow
ing steps: | |
2395 // 1. Let m [this] be the media element in question. | |
2396 // 2. Let m have no current media controller, if it currently has one. | |
2397 setControllerInternal(nullptr); | |
2398 | |
2399 // 3. If m's mediagroup attribute is being removed, then abort these steps. | |
2400 if (group.isNull() || group.isEmpty()) | |
2401 return; | |
2402 | |
2403 // 4. If there is another media element whose Document is the same as m's Do
cument (even if one or both | |
2404 // of these elements are not actually in the Document), | |
2405 WeakMediaElementSet elements = documentToElementSetMap().get(&document()); | |
2406 for (WeakMediaElementSet::iterator i = elements.begin(); i != elements.end()
; ++i) { | |
2407 if (*i == this) | |
2408 continue; | |
2409 | |
2410 // and which also has a mediagroup attribute, and whose mediagroup attri
bute has the same value as | |
2411 // the new value of m's mediagroup attribute, | |
2412 if ((*i)->mediaGroup() == group) { | |
2413 // then let controller be that media element's current media contro
ller. | |
2414 setControllerInternal((*i)->controller()); | |
2415 return; | |
2416 } | |
2417 } | |
2418 | |
2419 // Otherwise, let controller be a newly created MediaController. | |
2420 setControllerInternal(MediaController::create(Node::executionContext())); | |
2421 } | |
2422 | |
2423 MediaController* HTMLMediaElement::controller() const | |
2424 { | |
2425 return m_mediaController.get(); | |
2426 } | |
2427 | |
2428 void HTMLMediaElement::setController(PassRefPtrWillBeRawPtr<MediaController> con
troller) | |
2429 { | |
2430 // 4.8.10.11.2 Media controllers: controller attribute. | |
2431 // On setting, it must first remove the element's mediagroup attribute, if a
ny, | |
2432 removeAttribute(HTMLNames::mediagroupAttr); | |
2433 // and then set the current media controller to the given value. | |
2434 setControllerInternal(controller); | |
2435 } | |
2436 | |
2437 void HTMLMediaElement::setControllerInternal(PassRefPtrWillBeRawPtr<MediaControl
ler> controller) | |
2438 { | |
2439 if (m_mediaController) | |
2440 m_mediaController->removeMediaElement(this); | |
2441 | |
2442 m_mediaController = controller; | |
2443 | |
2444 if (m_mediaController) | |
2445 m_mediaController->addMediaElement(this); | |
2446 } | |
2447 | |
2448 void HTMLMediaElement::updateMediaController() | |
2449 { | |
2450 if (m_mediaController) | |
2451 m_mediaController->reportControllerState(); | |
2452 } | |
2453 | |
2454 bool HTMLMediaElement::isBlocked() const | 2340 bool HTMLMediaElement::isBlocked() const |
2455 { | 2341 { |
2456 // A media element is a blocked media element if its readyState attribute is
in the | 2342 // A media element is a blocked media element if its readyState attribute is
in the |
2457 // HAVE_NOTHING state, the HAVE_METADATA state, or the HAVE_CURRENT_DATA sta
te, | 2343 // HAVE_NOTHING state, the HAVE_METADATA state, or the HAVE_CURRENT_DATA sta
te, |
2458 // or if the element has paused for user interaction or paused for in-band c
ontent. | 2344 // or if the element has paused for user interaction or paused for in-band c
ontent. |
2459 if (m_readyState <= HAVE_CURRENT_DATA) | 2345 if (m_readyState <= HAVE_CURRENT_DATA) |
2460 return true; | 2346 return true; |
2461 | 2347 |
2462 return false; | 2348 return false; |
2463 } | 2349 } |
2464 | 2350 |
2465 bool HTMLMediaElement::isBlockedOnMediaController() const | |
2466 { | |
2467 if (!m_mediaController) | |
2468 return false; | |
2469 | |
2470 // A media element is blocked on its media controller if the MediaController
is a blocked | |
2471 // media controller, | |
2472 if (m_mediaController->isBlocked()) | |
2473 return true; | |
2474 | |
2475 // or if its media controller position is either before the media resource's
earliest possible | |
2476 // position relative to the MediaController's timeline or after the end of t
he media resource | |
2477 // relative to the MediaController's timeline. | |
2478 double mediaControllerPosition = m_mediaController->currentTime(); | |
2479 if (mediaControllerPosition < 0 || mediaControllerPosition > duration()) | |
2480 return true; | |
2481 | |
2482 return false; | |
2483 } | |
2484 | |
2485 void HTMLMediaElement::prepareMediaFragmentURI() | 2351 void HTMLMediaElement::prepareMediaFragmentURI() |
2486 { | 2352 { |
2487 MediaFragmentURIParser fragmentParser(m_currentSrc); | 2353 MediaFragmentURIParser fragmentParser(m_currentSrc); |
2488 double dur = duration(); | 2354 double dur = duration(); |
2489 | 2355 |
2490 double start = fragmentParser.startTime(); | 2356 double start = fragmentParser.startTime(); |
2491 if (start != MediaFragmentURIParser::invalidTimeValue() && start > 0) { | 2357 if (start != MediaFragmentURIParser::invalidTimeValue() && start > 0) { |
2492 m_fragmentStartTime = start; | 2358 m_fragmentStartTime = start; |
2493 if (m_fragmentStartTime > dur) | 2359 if (m_fragmentStartTime > dur) |
2494 m_fragmentStartTime = dur; | 2360 m_fragmentStartTime = dur; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2559 } | 2425 } |
2560 | 2426 |
2561 void HTMLMediaElement::trace(Visitor* visitor) | 2427 void HTMLMediaElement::trace(Visitor* visitor) |
2562 { | 2428 { |
2563 visitor->trace(m_playedTimeRanges); | 2429 visitor->trace(m_playedTimeRanges); |
2564 visitor->trace(m_asyncEventQueue); | 2430 visitor->trace(m_asyncEventQueue); |
2565 visitor->trace(m_error); | 2431 visitor->trace(m_error); |
2566 visitor->trace(m_currentSourceNode); | 2432 visitor->trace(m_currentSourceNode); |
2567 visitor->trace(m_nextChildNodeToConsider); | 2433 visitor->trace(m_nextChildNodeToConsider); |
2568 visitor->trace(m_mediaSource); | 2434 visitor->trace(m_mediaSource); |
2569 visitor->trace(m_mediaController); | |
2570 WillBeHeapSupplementable<HTMLMediaElement>::trace(visitor); | 2435 WillBeHeapSupplementable<HTMLMediaElement>::trace(visitor); |
2571 HTMLElement::trace(visitor); | 2436 HTMLElement::trace(visitor); |
2572 } | 2437 } |
2573 | 2438 |
2574 } | 2439 } |
OLD | NEW |