| 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 |