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 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
317 , m_defaultPlaybackRate(1.0f) | 317 , m_defaultPlaybackRate(1.0f) |
318 , m_networkState(NETWORK_EMPTY) | 318 , m_networkState(NETWORK_EMPTY) |
319 , m_readyState(HAVE_NOTHING) | 319 , m_readyState(HAVE_NOTHING) |
320 , m_readyStateMaximum(HAVE_NOTHING) | 320 , m_readyStateMaximum(HAVE_NOTHING) |
321 , m_volume(1.0f) | 321 , m_volume(1.0f) |
322 , m_lastSeekTime(0) | 322 , m_lastSeekTime(0) |
323 , m_previousProgressTime(std::numeric_limits<double>::max()) | 323 , m_previousProgressTime(std::numeric_limits<double>::max()) |
324 , m_duration(std::numeric_limits<double>::quiet_NaN()) | 324 , m_duration(std::numeric_limits<double>::quiet_NaN()) |
325 , m_lastTimeUpdateEventWallTime(0) | 325 , m_lastTimeUpdateEventWallTime(0) |
326 , m_lastTimeUpdateEventMovieTime(std::numeric_limits<double>::max()) | 326 , m_lastTimeUpdateEventMovieTime(std::numeric_limits<double>::max()) |
327 , m_defaultPlaybackStartPosition(0) | |
327 , m_loadState(WaitingForSource) | 328 , m_loadState(WaitingForSource) |
328 , m_deferredLoadState(NotDeferred) | 329 , m_deferredLoadState(NotDeferred) |
329 , m_deferredLoadTimer(this, &HTMLMediaElement::deferredLoadTimerFired) | 330 , m_deferredLoadTimer(this, &HTMLMediaElement::deferredLoadTimerFired) |
330 , m_webLayer(0) | 331 , m_webLayer(0) |
331 , m_preload(MediaPlayer::Auto) | 332 , m_preload(MediaPlayer::Auto) |
332 , m_displayMode(Unknown) | 333 , m_displayMode(Unknown) |
333 , m_cachedTime(MediaPlayer::invalidTime()) | 334 , m_cachedTime(MediaPlayer::invalidTime()) |
334 , m_cachedTimeWallClockUpdateTime(0) | 335 , m_cachedTimeWallClockUpdateTime(0) |
335 , m_minimumWallClockTimeToCacheMediaTime(0) | 336 , m_minimumWallClockTimeToCacheMediaTime(0) |
336 , m_fragmentStartTime(MediaPlayer::invalidTime()) | 337 , m_fragmentStartTime(MediaPlayer::invalidTime()) |
(...skipping 1478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1815 prepareMediaFragmentURI(); | 1816 prepareMediaFragmentURI(); |
1816 | 1817 |
1817 selectInitialTracksIfNecessary(); | 1818 selectInitialTracksIfNecessary(); |
1818 | 1819 |
1819 m_duration = duration(); | 1820 m_duration = duration(); |
1820 scheduleEvent(EventTypeNames::durationchange); | 1821 scheduleEvent(EventTypeNames::durationchange); |
1821 | 1822 |
1822 if (isHTMLVideoElement()) | 1823 if (isHTMLVideoElement()) |
1823 scheduleEvent(EventTypeNames::resize); | 1824 scheduleEvent(EventTypeNames::resize); |
1824 scheduleEvent(EventTypeNames::loadedmetadata); | 1825 scheduleEvent(EventTypeNames::loadedmetadata); |
1826 | |
1827 if (m_defaultPlaybackStartPosition > 0) { | |
amogh.bihani
2014/09/03 13:14:32
I tested locally for fragment URI and, as you had
philipj_slow
2014/09/03 14:09:13
Whichever you prefer is OK with me, but I would li
| |
1828 seek(m_defaultPlaybackStartPosition); | |
1829 m_defaultPlaybackStartPosition = 0; | |
1830 } | |
1831 | |
1825 if (hasMediaControls()) | 1832 if (hasMediaControls()) |
1826 mediaControls()->reset(); | 1833 mediaControls()->reset(); |
1827 if (renderer()) | 1834 if (renderer()) |
1828 renderer()->updateFromElement(); | 1835 renderer()->updateFromElement(); |
1829 } | 1836 } |
1830 | 1837 |
1831 bool shouldUpdateDisplayState = false; | 1838 bool shouldUpdateDisplayState = false; |
1832 | 1839 |
1833 if (m_readyState >= HAVE_CURRENT_DATA && oldState < HAVE_CURRENT_DATA && !m_ haveFiredLoadedData) { | 1840 if (m_readyState >= HAVE_CURRENT_DATA && oldState < HAVE_CURRENT_DATA && !m_ haveFiredLoadedData) { |
1834 m_haveFiredLoadedData = true; | 1841 m_haveFiredLoadedData = true; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1915 { | 1922 { |
1916 WTF_LOG(Media, "HTMLMediaElement::prepareToPlay(%p)", this); | 1923 WTF_LOG(Media, "HTMLMediaElement::prepareToPlay(%p)", this); |
1917 if (m_havePreparedToPlay) | 1924 if (m_havePreparedToPlay) |
1918 return; | 1925 return; |
1919 m_havePreparedToPlay = true; | 1926 m_havePreparedToPlay = true; |
1920 | 1927 |
1921 if (loadIsDeferred()) | 1928 if (loadIsDeferred()) |
1922 startDeferredLoad(); | 1929 startDeferredLoad(); |
1923 } | 1930 } |
1924 | 1931 |
1925 void HTMLMediaElement::seek(double time, ExceptionState& exceptionState) | 1932 void HTMLMediaElement::seek(double time) |
1926 { | 1933 { |
1927 WTF_LOG(Media, "HTMLMediaElement::seek(%f)", time); | 1934 WTF_LOG(Media, "HTMLMediaElement::seek(%f)", time); |
1928 | 1935 |
1929 // 4.8.10.9 Seeking | 1936 // 4.8.10.9 Seeking |
1930 | 1937 |
1931 // 1 - If the media element's readyState is HAVE_NOTHING, then raise an Inva lidStateError exception. | |
1932 if (m_readyState == HAVE_NOTHING) { | |
1933 exceptionState.throwDOMException(InvalidStateError, "The element's ready State is HAVE_NOTHING."); | |
1934 return; | |
1935 } | |
1936 | |
1937 // If the media engine has been told to postpone loading data, let it go ahe ad now. | 1938 // If the media engine has been told to postpone loading data, let it go ahe ad now. |
1938 if (m_preload < MediaPlayer::Auto && m_readyState < HAVE_FUTURE_DATA) | 1939 if (m_preload < MediaPlayer::Auto && m_readyState < HAVE_FUTURE_DATA) |
1939 prepareToPlay(); | 1940 prepareToPlay(); |
1940 | 1941 |
1941 // Get the current time before setting m_seeking, m_lastSeekTime is returned once it is set. | 1942 // Get the current time before setting m_seeking, m_lastSeekTime is returned once it is set. |
1942 refreshCachedTime(); | 1943 refreshCachedTime(); |
1943 double now = currentTime(); | 1944 double now = currentTime(); |
1944 | 1945 |
1945 // 2 - If the element's seeking IDL attribute is true, then another instance of this algorithm is | 1946 // 2 - If the element's seeking IDL attribute is true, then another instance of this algorithm is |
1946 // already running. Abort that other instance of the algorithm without waiti ng for the step that | 1947 // already running. Abort that other instance of the algorithm without waiti ng for the step that |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2067 m_cachedTime = MediaPlayer::invalidTime(); | 2068 m_cachedTime = MediaPlayer::invalidTime(); |
2068 } | 2069 } |
2069 | 2070 |
2070 // playback state | 2071 // playback state |
2071 double HTMLMediaElement::currentTime() const | 2072 double HTMLMediaElement::currentTime() const |
2072 { | 2073 { |
2073 #if LOG_CACHED_TIME_WARNINGS | 2074 #if LOG_CACHED_TIME_WARNINGS |
2074 static const double minCachedDeltaForWarning = 0.01; | 2075 static const double minCachedDeltaForWarning = 0.01; |
2075 #endif | 2076 #endif |
2076 | 2077 |
2078 if (m_defaultPlaybackStartPosition) { | |
2079 ASSERT(m_readyState == HAVE_NOTHING); | |
2080 return m_defaultPlaybackStartPosition; | |
2081 } | |
2082 | |
2077 if (m_readyState == HAVE_NOTHING) | 2083 if (m_readyState == HAVE_NOTHING) |
2078 return 0; | 2084 return 0; |
2079 | 2085 |
2080 if (m_seeking) { | 2086 if (m_seeking) { |
2081 WTF_LOG(Media, "HTMLMediaElement::currentTime - seeking, returning %f", m_lastSeekTime); | 2087 WTF_LOG(Media, "HTMLMediaElement::currentTime - seeking, returning %f", m_lastSeekTime); |
2082 return m_lastSeekTime; | 2088 return m_lastSeekTime; |
2083 } | 2089 } |
2084 | 2090 |
2085 if (m_cachedTime != MediaPlayer::invalidTime() && m_paused) { | 2091 if (m_cachedTime != MediaPlayer::invalidTime() && m_paused) { |
2086 #if LOG_CACHED_TIME_WARNINGS | 2092 #if LOG_CACHED_TIME_WARNINGS |
2087 double delta = m_cachedTime - webMediaPlayer()->currentTime(); | 2093 double delta = m_cachedTime - webMediaPlayer()->currentTime(); |
2088 if (delta > minCachedDeltaForWarning) | 2094 if (delta > minCachedDeltaForWarning) |
2089 WTF_LOG(Media, "HTMLMediaElement::currentTime - WARNING, cached time is %f seconds off of media time when paused", delta); | 2095 WTF_LOG(Media, "HTMLMediaElement::currentTime - WARNING, cached time is %f seconds off of media time when paused", delta); |
2090 #endif | 2096 #endif |
2091 return m_cachedTime; | 2097 return m_cachedTime; |
2092 } | 2098 } |
2093 | 2099 |
2094 refreshCachedTime(); | 2100 refreshCachedTime(); |
2095 | 2101 |
2096 return m_cachedTime; | 2102 return m_cachedTime; |
2097 } | 2103 } |
2098 | 2104 |
2099 void HTMLMediaElement::setCurrentTime(double time, ExceptionState& exceptionStat e) | 2105 void HTMLMediaElement::setCurrentTime(double time, ExceptionState& exceptionStat e) |
2100 { | 2106 { |
2101 if (m_mediaController) { | 2107 if (m_mediaController) { |
2102 exceptionState.throwDOMException(InvalidStateError, "The element is slav ed to a MediaController."); | 2108 exceptionState.throwDOMException(InvalidStateError, "The element is slav ed to a MediaController."); |
2103 return; | 2109 return; |
2104 } | 2110 } |
2105 seek(time, exceptionState); | 2111 |
2112 // If the media element's readyState is HAVE_NOTHING, then set the default | |
2113 // playback start position to that time. | |
2114 if (m_readyState == HAVE_NOTHING) { | |
2115 m_defaultPlaybackStartPosition = time; | |
2116 return; | |
2117 } | |
2118 | |
2119 seek(time); | |
2106 } | 2120 } |
2107 | 2121 |
2108 double HTMLMediaElement::duration() const | 2122 double HTMLMediaElement::duration() const |
2109 { | 2123 { |
2110 // FIXME: remove m_player check once we figure out how m_player is going | 2124 // FIXME: remove m_player check once we figure out how m_player is going |
2111 // out of sync with readystate. m_player is cleared but readystate is not se t | 2125 // out of sync with readystate. m_player is cleared but readystate is not se t |
2112 // to HAVE_NOTHING | 2126 // to HAVE_NOTHING |
2113 if (!m_player || m_readyState < HAVE_METADATA) | 2127 if (!m_player || m_readyState < HAVE_METADATA) |
2114 return std::numeric_limits<double>::quiet_NaN(); | 2128 return std::numeric_limits<double>::quiet_NaN(); |
2115 | 2129 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2234 | 2248 |
2235 void HTMLMediaElement::playInternal() | 2249 void HTMLMediaElement::playInternal() |
2236 { | 2250 { |
2237 WTF_LOG(Media, "HTMLMediaElement::playInternal"); | 2251 WTF_LOG(Media, "HTMLMediaElement::playInternal"); |
2238 | 2252 |
2239 // 4.8.10.9. Playing the media resource | 2253 // 4.8.10.9. Playing the media resource |
2240 if (!m_player || m_networkState == NETWORK_EMPTY) | 2254 if (!m_player || m_networkState == NETWORK_EMPTY) |
2241 scheduleDelayedAction(LoadMediaResource); | 2255 scheduleDelayedAction(LoadMediaResource); |
2242 | 2256 |
2243 if (endedPlayback()) | 2257 if (endedPlayback()) |
2244 seek(0, IGNORE_EXCEPTION); | 2258 seek(0); |
2245 | 2259 |
2246 if (m_mediaController) | 2260 if (m_mediaController) |
2247 m_mediaController->bringElementUpToSpeed(this); | 2261 m_mediaController->bringElementUpToSpeed(this); |
2248 | 2262 |
2249 if (m_paused) { | 2263 if (m_paused) { |
2250 m_paused = false; | 2264 m_paused = false; |
2251 invalidateCachedTime(); | 2265 invalidateCachedTime(); |
2252 scheduleEvent(EventTypeNames::play); | 2266 scheduleEvent(EventTypeNames::play); |
2253 | 2267 |
2254 if (m_readyState <= HAVE_CURRENT_DATA) | 2268 if (m_readyState <= HAVE_CURRENT_DATA) |
(...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3096 double now = currentTime(); | 3110 double now = currentTime(); |
3097 double dur = duration(); | 3111 double dur = duration(); |
3098 | 3112 |
3099 // When the current playback position reaches the end of the media resource when the direction of | 3113 // When the current playback position reaches the end of the media resource when the direction of |
3100 // playback is forwards, then the user agent must follow these steps: | 3114 // playback is forwards, then the user agent must follow these steps: |
3101 if (!std::isnan(dur) && dur && now >= dur && directionOfPlayback() == Forwar d) { | 3115 if (!std::isnan(dur) && dur && now >= dur && directionOfPlayback() == Forwar d) { |
3102 // If the media element has a loop attribute specified and does not have a current media controller, | 3116 // If the media element has a loop attribute specified and does not have a current media controller, |
3103 if (loop() && !m_mediaController) { | 3117 if (loop() && !m_mediaController) { |
3104 m_sentEndEvent = false; | 3118 m_sentEndEvent = false; |
3105 // then seek to the earliest possible position of the media resourc e and abort these steps. | 3119 // then seek to the earliest possible position of the media resourc e and abort these steps. |
3106 seek(0, IGNORE_EXCEPTION); | 3120 seek(0); |
3107 } else { | 3121 } else { |
3108 // If the media element does not have a current media controller, an d the media element | 3122 // If the media element does not have a current media controller, an d the media element |
3109 // has still ended playback, and the direction of playback is still forwards, and paused | 3123 // has still ended playback, and the direction of playback is still forwards, and paused |
3110 // is false, | 3124 // is false, |
3111 if (!m_mediaController && !m_paused) { | 3125 if (!m_mediaController && !m_paused) { |
3112 // changes paused to true and fires a simple event named pause a t the media element. | 3126 // changes paused to true and fires a simple event named pause a t the media element. |
3113 m_paused = true; | 3127 m_paused = true; |
3114 scheduleEvent(EventTypeNames::pause); | 3128 scheduleEvent(EventTypeNames::pause); |
3115 } | 3129 } |
3116 // Queue a task to fire a simple event named ended at the media elem ent. | 3130 // Queue a task to fire a simple event named ended at the media elem ent. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3150 WTF_LOG(Media, "HTMLMediaElement::durationChanged : %f -> %f", m_duration, d uration); | 3164 WTF_LOG(Media, "HTMLMediaElement::durationChanged : %f -> %f", m_duration, d uration); |
3151 m_duration = duration; | 3165 m_duration = duration; |
3152 scheduleEvent(EventTypeNames::durationchange); | 3166 scheduleEvent(EventTypeNames::durationchange); |
3153 | 3167 |
3154 if (hasMediaControls()) | 3168 if (hasMediaControls()) |
3155 mediaControls()->reset(); | 3169 mediaControls()->reset(); |
3156 if (renderer()) | 3170 if (renderer()) |
3157 renderer()->updateFromElement(); | 3171 renderer()->updateFromElement(); |
3158 | 3172 |
3159 if (requestSeek) | 3173 if (requestSeek) |
3160 seek(duration, IGNORE_EXCEPTION); | 3174 seek(duration); |
3161 } | 3175 } |
3162 | 3176 |
3163 void HTMLMediaElement::mediaPlayerPlaybackStateChanged() | 3177 void HTMLMediaElement::mediaPlayerPlaybackStateChanged() |
3164 { | 3178 { |
3165 WTF_LOG(Media, "HTMLMediaElement::mediaPlayerPlaybackStateChanged"); | 3179 WTF_LOG(Media, "HTMLMediaElement::mediaPlayerPlaybackStateChanged"); |
3166 | 3180 |
3167 if (!m_player || m_pausedInternal) | 3181 if (!m_player || m_pausedInternal) |
3168 return; | 3182 return; |
3169 | 3183 |
3170 if (webMediaPlayer()->paused()) | 3184 if (webMediaPlayer()->paused()) |
(...skipping 10 matching lines...) Expand all Loading... | |
3181 // user interaction or when it is technically required to play the video. | 3195 // user interaction or when it is technically required to play the video. |
3182 UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture); | 3196 UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture); |
3183 | 3197 |
3184 enterFullscreen(); | 3198 enterFullscreen(); |
3185 } | 3199 } |
3186 | 3200 |
3187 void HTMLMediaElement::mediaPlayerRequestSeek(double time) | 3201 void HTMLMediaElement::mediaPlayerRequestSeek(double time) |
3188 { | 3202 { |
3189 // The player is the source of this seek request. | 3203 // The player is the source of this seek request. |
3190 if (m_mediaController) { | 3204 if (m_mediaController) { |
3191 m_mediaController->setCurrentTime(time, IGNORE_EXCEPTION); | 3205 m_mediaController->setCurrentTime(time); |
3192 return; | 3206 return; |
3193 } | 3207 } |
3194 setCurrentTime(time, IGNORE_EXCEPTION); | 3208 setCurrentTime(time, ASSERT_NO_EXCEPTION); |
3195 } | 3209 } |
3196 | 3210 |
3197 // MediaPlayerPresentation methods | 3211 // MediaPlayerPresentation methods |
3198 void HTMLMediaElement::mediaPlayerRepaint() | 3212 void HTMLMediaElement::mediaPlayerRepaint() |
3199 { | 3213 { |
3200 if (m_webLayer) | 3214 if (m_webLayer) |
3201 m_webLayer->invalidate(); | 3215 m_webLayer->invalidate(); |
3202 | 3216 |
3203 updateDisplayState(); | 3217 updateDisplayState(); |
3204 if (renderer()) | 3218 if (renderer()) |
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3882 | 3896 |
3883 if (m_fragmentStartTime != MediaPlayer::invalidTime() && m_readyState < HAVE _FUTURE_DATA) | 3897 if (m_fragmentStartTime != MediaPlayer::invalidTime() && m_readyState < HAVE _FUTURE_DATA) |
3884 prepareToPlay(); | 3898 prepareToPlay(); |
3885 } | 3899 } |
3886 | 3900 |
3887 void HTMLMediaElement::applyMediaFragmentURI() | 3901 void HTMLMediaElement::applyMediaFragmentURI() |
3888 { | 3902 { |
3889 if (m_fragmentStartTime != MediaPlayer::invalidTime()) { | 3903 if (m_fragmentStartTime != MediaPlayer::invalidTime()) { |
3890 m_sentEndEvent = false; | 3904 m_sentEndEvent = false; |
3891 UseCounter::count(document(), UseCounter::HTMLMediaElementSeekToFragment Start); | 3905 UseCounter::count(document(), UseCounter::HTMLMediaElementSeekToFragment Start); |
3892 seek(m_fragmentStartTime, IGNORE_EXCEPTION); | 3906 seek(m_fragmentStartTime); |
3893 } | 3907 } |
3894 } | 3908 } |
3895 | 3909 |
3896 WebMediaPlayer::CORSMode HTMLMediaElement::corsMode() const | 3910 WebMediaPlayer::CORSMode HTMLMediaElement::corsMode() const |
3897 { | 3911 { |
3898 const AtomicString& crossOriginMode = fastGetAttribute(crossoriginAttr); | 3912 const AtomicString& crossOriginMode = fastGetAttribute(crossoriginAttr); |
3899 if (crossOriginMode.isNull()) | 3913 if (crossOriginMode.isNull()) |
3900 return WebMediaPlayer::CORSModeUnspecified; | 3914 return WebMediaPlayer::CORSModeUnspecified; |
3901 if (equalIgnoringCase(crossOriginMode, "use-credentials")) | 3915 if (equalIgnoringCase(crossOriginMode, "use-credentials")) |
3902 return WebMediaPlayer::CORSModeUseCredentials; | 3916 return WebMediaPlayer::CORSModeUseCredentials; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3989 | 4003 |
3990 #if ENABLE(WEB_AUDIO) | 4004 #if ENABLE(WEB_AUDIO) |
3991 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) | 4005 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) |
3992 { | 4006 { |
3993 if (!visitor->isAlive(m_audioSourceNode) && audioSourceProvider()) | 4007 if (!visitor->isAlive(m_audioSourceNode) && audioSourceProvider()) |
3994 audioSourceProvider()->setClient(0); | 4008 audioSourceProvider()->setClient(0); |
3995 } | 4009 } |
3996 #endif | 4010 #endif |
3997 | 4011 |
3998 } | 4012 } |
OLD | NEW |