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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
44 #include "core/frame/UseCounter.h" | 44 #include "core/frame/UseCounter.h" |
45 #include "core/frame/csp/ContentSecurityPolicy.h" | 45 #include "core/frame/csp/ContentSecurityPolicy.h" |
46 #include "core/html/HTMLMediaSource.h" | 46 #include "core/html/HTMLMediaSource.h" |
47 #include "core/html/HTMLSourceElement.h" | 47 #include "core/html/HTMLSourceElement.h" |
48 #include "core/html/HTMLTrackElement.h" | 48 #include "core/html/HTMLTrackElement.h" |
49 #include "core/html/MediaController.h" | 49 #include "core/html/MediaController.h" |
50 #include "core/html/MediaError.h" | 50 #include "core/html/MediaError.h" |
51 #include "core/html/MediaFragmentURIParser.h" | 51 #include "core/html/MediaFragmentURIParser.h" |
52 #include "core/html/TimeRanges.h" | 52 #include "core/html/TimeRanges.h" |
53 #include "core/html/shadow/MediaControls.h" | 53 #include "core/html/shadow/MediaControls.h" |
54 #include "core/html/track/AudioTrack.h" | |
55 #include "core/html/track/AudioTrackList.h" | |
54 #include "core/html/track/InbandTextTrack.h" | 56 #include "core/html/track/InbandTextTrack.h" |
55 #include "core/html/track/TextTrackCueList.h" | 57 #include "core/html/track/TextTrackCueList.h" |
56 #include "core/html/track/TextTrackList.h" | 58 #include "core/html/track/TextTrackList.h" |
59 #include "core/html/track/VideoTrack.h" | |
60 #include "core/html/track/VideoTrackList.h" | |
57 #include "core/loader/FrameLoader.h" | 61 #include "core/loader/FrameLoader.h" |
58 #include "core/rendering/RenderVideo.h" | 62 #include "core/rendering/RenderVideo.h" |
59 #include "core/rendering/RenderView.h" | 63 #include "core/rendering/RenderView.h" |
60 #include "core/rendering/compositing/RenderLayerCompositor.h" | 64 #include "core/rendering/compositing/RenderLayerCompositor.h" |
61 #include "platform/ContentType.h" | 65 #include "platform/ContentType.h" |
62 #include "platform/Language.h" | 66 #include "platform/Language.h" |
63 #include "platform/Logging.h" | 67 #include "platform/Logging.h" |
64 #include "platform/MIMETypeFromURL.h" | 68 #include "platform/MIMETypeFromURL.h" |
65 #include "platform/MIMETypeRegistry.h" | 69 #include "platform/MIMETypeRegistry.h" |
66 #include "platform/NotImplemented.h" | 70 #include "platform/NotImplemented.h" |
(...skipping 11 matching lines...) Expand all Loading... | |
78 | 82 |
79 #if ENABLE(WEB_AUDIO) | 83 #if ENABLE(WEB_AUDIO) |
80 #include "platform/audio/AudioSourceProvider.h" | 84 #include "platform/audio/AudioSourceProvider.h" |
81 #include "modules/webaudio/MediaElementAudioSourceNode.h" | 85 #include "modules/webaudio/MediaElementAudioSourceNode.h" |
82 #endif | 86 #endif |
83 | 87 |
84 using namespace std; | 88 using namespace std; |
85 using blink::WebInbandTextTrack; | 89 using blink::WebInbandTextTrack; |
86 using blink::WebMediaPlayer; | 90 using blink::WebMediaPlayer; |
87 using blink::WebMimeRegistry; | 91 using blink::WebMimeRegistry; |
92 using blink::WebMediaPlayerClient; | |
88 | 93 |
89 namespace WebCore { | 94 namespace WebCore { |
90 | 95 |
91 #if !LOG_DISABLED | 96 #if !LOG_DISABLED |
92 static String urlForLoggingMedia(const KURL& url) | 97 static String urlForLoggingMedia(const KURL& url) |
93 { | 98 { |
94 static const unsigned maximumURLLengthForLogging = 128; | 99 static const unsigned maximumURLLengthForLogging = 128; |
95 | 100 |
96 if (url.string().length() < maximumURLLengthForLogging) | 101 if (url.string().length() < maximumURLLengthForLogging) |
97 return url.string(); | 102 return url.string(); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
156 ~TrackDisplayUpdateScope() | 161 ~TrackDisplayUpdateScope() |
157 { | 162 { |
158 ASSERT(m_mediaElement); | 163 ASSERT(m_mediaElement); |
159 m_mediaElement->endIgnoringTrackDisplayUpdateRequests(); | 164 m_mediaElement->endIgnoringTrackDisplayUpdateRequests(); |
160 } | 165 } |
161 | 166 |
162 private: | 167 private: |
163 HTMLMediaElement* m_mediaElement; | 168 HTMLMediaElement* m_mediaElement; |
164 }; | 169 }; |
165 | 170 |
171 static const AtomicString& AudioKindToString(WebMediaPlayerClient::AudioTrackKin d kind) | |
172 { | |
173 switch (kind) { | |
174 case WebMediaPlayerClient::AudioTrackKindNone: | |
175 return emptyAtom; | |
176 case WebMediaPlayerClient::AudioTrackKindAlternative: | |
177 return AudioTrack::alternativeKeyword(); | |
178 case WebMediaPlayerClient::AudioTrackKindDescriptions: | |
179 return AudioTrack::descriptionsKeyword(); | |
180 case WebMediaPlayerClient::AudioTrackKindMain: | |
181 return AudioTrack::mainKeyword(); | |
182 case WebMediaPlayerClient::AudioTrackKindMainDescriptions: | |
183 return AudioTrack::mainDescriptionsKeyword(); | |
184 case WebMediaPlayerClient::AudioTrackKindTranslation: | |
185 return AudioTrack::translationKeyword(); | |
186 case WebMediaPlayerClient::AudioTrackKindCommentary: | |
187 return AudioTrack::commentaryKeyword(); | |
188 } | |
189 | |
190 ASSERT_NOT_REACHED(); | |
191 return emptyAtom; | |
192 } | |
193 | |
194 static const AtomicString& VideoKindToString(WebMediaPlayerClient::VideoTrackKin d kind) | |
195 { | |
196 switch (kind) { | |
197 case WebMediaPlayerClient::VideoTrackKindNone: | |
198 return emptyAtom; | |
199 case WebMediaPlayerClient::VideoTrackKindAlternative: | |
200 return VideoTrack::alternativeKeyword(); | |
201 case WebMediaPlayerClient::VideoTrackKindCaptions: | |
202 return VideoTrack::captionsKeyword(); | |
203 case WebMediaPlayerClient::VideoTrackKindMain: | |
204 return VideoTrack::mainKeyword(); | |
205 case WebMediaPlayerClient::VideoTrackKindSign: | |
206 return VideoTrack::signKeyword(); | |
207 case WebMediaPlayerClient::VideoTrackKindSubtitles: | |
208 return VideoTrack::subtitlesKeyword(); | |
209 case WebMediaPlayerClient::VideoTrackKindCommentary: | |
210 return VideoTrack::commentaryKeyword(); | |
211 } | |
212 | |
213 ASSERT_NOT_REACHED(); | |
214 return emptyAtom; | |
215 } | |
216 | |
166 static bool canLoadURL(const KURL& url, const ContentType& contentType, const St ring& keySystem) | 217 static bool canLoadURL(const KURL& url, const ContentType& contentType, const St ring& keySystem) |
167 { | 218 { |
168 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); | 219 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); |
169 | 220 |
170 String contentMIMEType = contentType.type().lower(); | 221 String contentMIMEType = contentType.type().lower(); |
171 String contentTypeCodecs = contentType.parameter(codecs); | 222 String contentTypeCodecs = contentType.parameter(codecs); |
172 | 223 |
173 // If the MIME type is missing or is not meaningful, try to figure it out fr om the URL. | 224 // If the MIME type is missing or is not meaningful, try to figure it out fr om the URL. |
174 if (contentMIMEType.isEmpty() || contentMIMEType == "application/octet-strea m" || contentMIMEType == "text/plain") { | 225 if (contentMIMEType.isEmpty() || contentMIMEType == "application/octet-strea m" || contentMIMEType == "text/plain") { |
175 if (url.protocolIsData()) | 226 if (url.protocolIsData()) |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
227 { | 278 { |
228 return s_mediaStreamRegistry ? s_mediaStreamRegistry->contains(url) : false; | 279 return s_mediaStreamRegistry ? s_mediaStreamRegistry->contains(url) : false; |
229 } | 280 } |
230 | 281 |
231 HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum ent) | 282 HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum ent) |
232 : HTMLElement(tagName, document) | 283 : HTMLElement(tagName, document) |
233 , ActiveDOMObject(&document) | 284 , ActiveDOMObject(&document) |
234 , m_loadTimer(this, &HTMLMediaElement::loadTimerFired) | 285 , m_loadTimer(this, &HTMLMediaElement::loadTimerFired) |
235 , m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired) | 286 , m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired) |
236 , m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFire d) | 287 , m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFire d) |
288 , m_audioTracksTimer(this, &HTMLMediaElement::audioTracksTimerFired) | |
237 , m_playedTimeRanges() | 289 , m_playedTimeRanges() |
238 , m_asyncEventQueue(GenericEventQueue::create(this)) | 290 , m_asyncEventQueue(GenericEventQueue::create(this)) |
239 , m_playbackRate(1.0f) | 291 , m_playbackRate(1.0f) |
240 , m_defaultPlaybackRate(1.0f) | 292 , m_defaultPlaybackRate(1.0f) |
241 , m_networkState(NETWORK_EMPTY) | 293 , m_networkState(NETWORK_EMPTY) |
242 , m_readyState(HAVE_NOTHING) | 294 , m_readyState(HAVE_NOTHING) |
243 , m_readyStateMaximum(HAVE_NOTHING) | 295 , m_readyStateMaximum(HAVE_NOTHING) |
244 , m_volume(1.0f) | 296 , m_volume(1.0f) |
245 , m_lastSeekTime(0) | 297 , m_lastSeekTime(0) |
246 , m_previousProgressTime(numeric_limits<double>::max()) | 298 , m_previousProgressTime(numeric_limits<double>::max()) |
(...skipping 24 matching lines...) Expand all Loading... | |
271 , m_sentEndEvent(false) | 323 , m_sentEndEvent(false) |
272 , m_pausedInternal(false) | 324 , m_pausedInternal(false) |
273 , m_closedCaptionsVisible(false) | 325 , m_closedCaptionsVisible(false) |
274 , m_completelyLoaded(false) | 326 , m_completelyLoaded(false) |
275 , m_havePreparedToPlay(false) | 327 , m_havePreparedToPlay(false) |
276 , m_delayingLoadForPreloadNone(false) | 328 , m_delayingLoadForPreloadNone(false) |
277 , m_tracksAreReady(true) | 329 , m_tracksAreReady(true) |
278 , m_haveVisibleTextTrack(false) | 330 , m_haveVisibleTextTrack(false) |
279 , m_processingPreferenceChange(false) | 331 , m_processingPreferenceChange(false) |
280 , m_lastTextTrackUpdateTime(-1) | 332 , m_lastTextTrackUpdateTime(-1) |
333 , m_audioTracks(AudioTrackList::create(*this)) | |
334 , m_videoTracks(VideoTrackList::create(*this)) | |
281 , m_textTracks(nullptr) | 335 , m_textTracks(nullptr) |
282 , m_ignoreTrackDisplayUpdate(0) | 336 , m_ignoreTrackDisplayUpdate(0) |
283 #if ENABLE(WEB_AUDIO) | 337 #if ENABLE(WEB_AUDIO) |
284 , m_audioSourceNode(0) | 338 , m_audioSourceNode(0) |
285 #endif | 339 #endif |
286 { | 340 { |
287 ASSERT(RuntimeEnabledFeatures::mediaEnabled()); | 341 ASSERT(RuntimeEnabledFeatures::mediaEnabled()); |
288 | 342 |
289 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement"); | 343 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement"); |
290 ScriptWrappable::init(this); | 344 ScriptWrappable::init(this); |
(...skipping 12 matching lines...) Expand all Loading... | |
303 { | 357 { |
304 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement"); | 358 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement"); |
305 | 359 |
306 m_asyncEventQueue->close(); | 360 m_asyncEventQueue->close(); |
307 | 361 |
308 setShouldDelayLoadEvent(false); | 362 setShouldDelayLoadEvent(false); |
309 | 363 |
310 if (m_textTracks) | 364 if (m_textTracks) |
311 m_textTracks->clearOwner(); | 365 m_textTracks->clearOwner(); |
312 | 366 |
367 m_audioTracks->shutdown(); | |
368 m_videoTracks->shutdown(); | |
369 | |
313 if (m_mediaController) { | 370 if (m_mediaController) { |
314 m_mediaController->removeMediaElement(this); | 371 m_mediaController->removeMediaElement(this); |
315 m_mediaController = nullptr; | 372 m_mediaController = nullptr; |
316 } | 373 } |
317 | 374 |
318 closeMediaSource(); | 375 closeMediaSource(); |
319 | 376 |
320 removeElementFromDocumentMap(this, &document()); | 377 removeElementFromDocumentMap(this, &document()); |
321 | 378 |
322 // Destroying the player may cause a resource load to be canceled, | 379 // Destroying the player may cause a resource load to be canceled, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
362 // previous document. A proper fix would provide a mechanism to allow this | 419 // previous document. A proper fix would provide a mechanism to allow this |
363 // object to refresh the MediaPlayer's LocalFrame and FrameLoader references on | 420 // object to refresh the MediaPlayer's LocalFrame and FrameLoader references on |
364 // document changes so that playback can be resumed properly. | 421 // document changes so that playback can be resumed properly. |
365 userCancelledLoad(); | 422 userCancelledLoad(); |
366 | 423 |
367 // Decrement the load event delay count on oldDocument now that m_player has been destroyed | 424 // Decrement the load event delay count on oldDocument now that m_player has been destroyed |
368 // and there is no risk of dispatching a load event from within the destruct or. | 425 // and there is no risk of dispatching a load event from within the destruct or. |
369 oldDocument.decrementLoadEventDelayCount(); | 426 oldDocument.decrementLoadEventDelayCount(); |
370 | 427 |
371 ActiveDOMObject::didMoveToNewExecutionContext(&document()); | 428 ActiveDOMObject::didMoveToNewExecutionContext(&document()); |
429 | |
372 HTMLElement::didMoveToNewDocument(oldDocument); | 430 HTMLElement::didMoveToNewDocument(oldDocument); |
373 } | 431 } |
374 | 432 |
375 bool HTMLMediaElement::hasCustomFocusLogic() const | 433 bool HTMLMediaElement::hasCustomFocusLogic() const |
376 { | 434 { |
377 return true; | 435 return true; |
378 } | 436 } |
379 | 437 |
380 bool HTMLMediaElement::supportsFocus() const | 438 bool HTMLMediaElement::supportsFocus() const |
381 { | 439 { |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
595 | 653 |
596 void HTMLMediaElement::prepareForLoad() | 654 void HTMLMediaElement::prepareForLoad() |
597 { | 655 { |
598 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad"); | 656 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad"); |
599 | 657 |
600 // Perform the cleanup required for the resource load algorithm to run. | 658 // Perform the cleanup required for the resource load algorithm to run. |
601 stopPeriodicTimers(); | 659 stopPeriodicTimers(); |
602 m_loadTimer.stop(); | 660 m_loadTimer.stop(); |
603 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec essary and set m_pendingActionFlags to 0 here. | 661 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec essary and set m_pendingActionFlags to 0 here. |
604 m_pendingActionFlags &= ~LoadMediaResource; | 662 m_pendingActionFlags &= ~LoadMediaResource; |
663 m_audioTracksTimer.stop(); | |
605 m_sentEndEvent = false; | 664 m_sentEndEvent = false; |
606 m_sentStalledEvent = false; | 665 m_sentStalledEvent = false; |
607 m_haveFiredLoadedData = false; | 666 m_haveFiredLoadedData = false; |
608 m_completelyLoaded = false; | 667 m_completelyLoaded = false; |
609 m_havePreparedToPlay = false; | 668 m_havePreparedToPlay = false; |
610 m_displayMode = Unknown; | 669 m_displayMode = Unknown; |
611 | 670 |
612 // 1 - Abort any already-running instance of the resource selection algorith m for this element. | 671 // 1 - Abort any already-running instance of the resource selection algorith m for this element. |
613 m_loadState = WaitingForSource; | 672 m_loadState = WaitingForSource; |
614 m_currentSourceNode = nullptr; | 673 m_currentSourceNode = nullptr; |
(...skipping 966 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1581 finishSeek(); | 1640 finishSeek(); |
1582 } else { | 1641 } else { |
1583 if (wasPotentiallyPlaying && m_readyState < HAVE_FUTURE_DATA) { | 1642 if (wasPotentiallyPlaying && m_readyState < HAVE_FUTURE_DATA) { |
1584 // 4.8.10.8 | 1643 // 4.8.10.8 |
1585 scheduleTimeupdateEvent(false); | 1644 scheduleTimeupdateEvent(false); |
1586 scheduleEvent(EventTypeNames::waiting); | 1645 scheduleEvent(EventTypeNames::waiting); |
1587 } | 1646 } |
1588 } | 1647 } |
1589 | 1648 |
1590 if (m_readyState >= HAVE_METADATA && oldState < HAVE_METADATA) { | 1649 if (m_readyState >= HAVE_METADATA && oldState < HAVE_METADATA) { |
1650 createPlaceholderTracksIfNecessary(); | |
1651 | |
1591 prepareMediaFragmentURI(); | 1652 prepareMediaFragmentURI(); |
1653 | |
1654 selectInitialTracksIfNecessary(); | |
1655 | |
1592 scheduleEvent(EventTypeNames::durationchange); | 1656 scheduleEvent(EventTypeNames::durationchange); |
1593 if (isHTMLVideoElement(*this)) | 1657 if (isHTMLVideoElement(*this)) |
1594 scheduleEvent(EventTypeNames::resize); | 1658 scheduleEvent(EventTypeNames::resize); |
1595 scheduleEvent(EventTypeNames::loadedmetadata); | 1659 scheduleEvent(EventTypeNames::loadedmetadata); |
1596 if (hasMediaControls()) | 1660 if (hasMediaControls()) |
1597 mediaControls()->reset(); | 1661 mediaControls()->reset(); |
1598 if (renderer()) | 1662 if (renderer()) |
1599 renderer()->updateFromElement(); | 1663 renderer()->updateFromElement(); |
1600 } | 1664 } |
1601 | 1665 |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2179 m_lastTimeUpdateEventWallTime = now; | 2243 m_lastTimeUpdateEventWallTime = now; |
2180 m_lastTimeUpdateEventMovieTime = movieTime; | 2244 m_lastTimeUpdateEventMovieTime = movieTime; |
2181 } | 2245 } |
2182 } | 2246 } |
2183 | 2247 |
2184 bool HTMLMediaElement::canPlay() const | 2248 bool HTMLMediaElement::canPlay() const |
2185 { | 2249 { |
2186 return paused() || ended() || m_readyState < HAVE_METADATA; | 2250 return paused() || ended() || m_readyState < HAVE_METADATA; |
2187 } | 2251 } |
2188 | 2252 |
2253 | |
2189 void HTMLMediaElement::togglePlayState() | 2254 void HTMLMediaElement::togglePlayState() |
2190 { | 2255 { |
2191 ASSERT(controls()); | 2256 ASSERT(controls()); |
2192 // The activation behavior of a media element that is exposing a user interf ace to the user | 2257 // The activation behavior of a media element that is exposing a user interf ace to the user |
2193 if (m_mediaController) { | 2258 if (m_mediaController) { |
2194 if (m_mediaController->isRestrained()) | 2259 if (m_mediaController->isRestrained()) |
2195 m_mediaController->play(); | 2260 m_mediaController->play(); |
2196 else if (m_mediaController->paused()) | 2261 else if (m_mediaController->paused()) |
2197 m_mediaController->unpause(); | 2262 m_mediaController->unpause(); |
2198 else | 2263 else |
2199 m_mediaController->pause(); | 2264 m_mediaController->pause(); |
2200 } else { | 2265 } else { |
2201 if (paused()) | 2266 if (paused()) |
2202 play(); | 2267 play(); |
2203 else | 2268 else |
2204 pause(); | 2269 pause(); |
2205 } | 2270 } |
2271 | |
2272 AudioTrackList& HTMLMediaElement::audioTracks() | |
2273 { | |
2274 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled()); | |
2275 return *m_audioTracks; | |
2276 } | |
2277 | |
2278 void HTMLMediaElement::audioTrackChanged(const String& audioTrackID) | |
2279 { | |
2280 WTF_LOG(Media, "HTMLMediaElement::audioTrackChanged('%s')", audioTrackID.asc ii().data()); | |
2281 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled()); | |
2282 ASSERT(!audioTrackID.isEmpty()); | |
2283 | |
2284 audioTracks().scheduleChangeEvent(); | |
2285 | |
2286 // FIXME: Add call on m_mediaSource to notify it of track changes once the S ourceBuffer.audioTracks attribute is added. | |
2287 | |
2288 if (!m_audioTracksTimer.isActive()) | |
2289 m_audioTracksTimer.startOneShot(0, FROM_HERE); | |
2290 } | |
2291 | |
2292 void HTMLMediaElement::addAudioTrack(const String& id, blink::WebMediaPlayerClie nt::AudioTrackKind kind, const AtomicString& label, const AtomicString& language , bool enabled) | |
2293 { | |
2294 AtomicString kindString = AudioKindToString(kind); | |
2295 WTF_LOG(Media, "HTMLMediaElement::addAudioTrack('%s', '%s', '%s', '%s', %d)" , | |
2296 id.ascii().data(), kindString.ascii().data(), label.ascii().data(), lang uage.ascii().data(), enabled); | |
2297 ASSERT(!id.isEmpty()); | |
philipj_slow
2014/04/23 12:08:07
We've made a little discovery on this point. The s
| |
2298 | |
2299 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) | |
2300 return; | |
2301 | |
2302 RefPtr<AudioTrack> audioTrack = AudioTrack::create(this, id, kindString, lab el, language); | |
2303 audioTracks().add(audioTrack.get()); | |
2304 | |
2305 if (enabled) | |
2306 audioTrack->setEnabled(true); | |
2307 } | |
2308 | |
2309 void HTMLMediaElement::removeAudioTrack(const String& id) | |
2310 { | |
2311 WTF_LOG(Media, "HTMLMediaElement::removeAudioTrack('%s')", id.ascii().data() ); | |
2312 ASSERT(!id.isEmpty()); | |
2313 | |
2314 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) | |
2315 return; | |
2316 | |
2317 audioTracks().remove(id); | |
2318 } | |
2319 | |
2320 VideoTrackList& HTMLMediaElement::videoTracks() | |
2321 { | |
2322 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled()); | |
2323 return *m_videoTracks; | |
2324 } | |
2325 | |
2326 void HTMLMediaElement::selectedVideoTrackChanged(const String& selectedTrackID) | |
2327 { | |
2328 WTF_LOG(Media, "HTMLMediaElement::selectedVideoTrackChanged('%s')", selected TrackID.ascii().data()); | |
2329 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled()); | |
2330 | |
2331 String unselectedTrackID; | |
2332 | |
2333 int oldSelectedIndex = videoTracks().selectedIndex(); | |
2334 if (oldSelectedIndex != -1) | |
2335 unselectedTrackID = videoTracks().anonymousIndexedGetter(oldSelectedInde x)->id(); | |
2336 | |
2337 ASSERT(unselectedTrackID != selectedTrackID); | |
2338 ASSERT(!unselectedTrackID.isEmpty() || !selectedTrackID.isEmpty()); | |
2339 | |
2340 videoTracks().trackSelected(selectedTrackID); | |
2341 | |
2342 // FIXME: Add call on m_mediaSource to notify it of track changes once the S ourceBuffer.videoTracks attribute is added. | |
2343 | |
2344 if (webMediaPlayer()) | |
2345 webMediaPlayer()->selectedVideoTrackChanged(selectedTrackID); | |
2346 } | |
2347 | |
2348 void HTMLMediaElement::addVideoTrack(const String& id, blink::WebMediaPlayerClie nt::VideoTrackKind kind, const AtomicString& label, const AtomicString& language , bool selected) | |
2349 { | |
2350 AtomicString kindString = VideoKindToString(kind); | |
2351 WTF_LOG(Media, "HTMLMediaElement::addVideoTrack('%s', '%s', '%s', '%s', %d)" , | |
2352 id.ascii().data(), kindString.ascii().data(), label.ascii().data(), lang uage.ascii().data(), selected); | |
2353 ASSERT(!id.isEmpty()); | |
2354 | |
2355 RefPtr<VideoTrack> videoTrack = VideoTrack::create(this, id, kindString, lab el, language); | |
2356 videoTracks().add(videoTrack.get()); | |
2357 | |
2358 if (selected) | |
2359 videoTrack->setSelected(true); | |
2360 } | |
2361 | |
2362 void HTMLMediaElement::removeVideoTrack(const String& id) | |
2363 { | |
2364 WTF_LOG(Media, "HTMLMediaElement::removeVideoTrack('%s')", id.ascii().data() ); | |
2365 ASSERT(!id.isEmpty()); | |
2366 | |
2367 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) | |
2368 return; | |
2369 | |
2370 videoTracks().remove(id); | |
2206 } | 2371 } |
2207 | 2372 |
2208 void HTMLMediaElement::mediaPlayerDidAddTextTrack(WebInbandTextTrack* webTrack) | 2373 void HTMLMediaElement::mediaPlayerDidAddTextTrack(WebInbandTextTrack* webTrack) |
2209 { | 2374 { |
2210 if (!RuntimeEnabledFeatures::videoTrackEnabled()) | 2375 if (!RuntimeEnabledFeatures::videoTrackEnabled()) |
2211 return; | 2376 return; |
2212 | 2377 |
2213 // 4.8.10.12.2 Sourcing in-band text tracks | 2378 // 4.8.10.12.2 Sourcing in-band text tracks |
2214 // 1. Associate the relevant data with a new text track and its correspondin g new TextTrack object. | 2379 // 1. Associate the relevant data with a new text track and its correspondin g new TextTrack object. |
2215 RefPtr<InbandTextTrack> textTrack = InbandTextTrack::create(document(), webT rack); | 2380 RefPtr<InbandTextTrack> textTrack = InbandTextTrack::create(document(), webT rack); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2273 void HTMLMediaElement::removeTextTrack(TextTrack* track) | 2438 void HTMLMediaElement::removeTextTrack(TextTrack* track) |
2274 { | 2439 { |
2275 TrackDisplayUpdateScope scope(this); | 2440 TrackDisplayUpdateScope scope(this); |
2276 m_textTracks->remove(track); | 2441 m_textTracks->remove(track); |
2277 | 2442 |
2278 closeCaptionTracksChanged(); | 2443 closeCaptionTracksChanged(); |
2279 } | 2444 } |
2280 | 2445 |
2281 void HTMLMediaElement::forgetResourceSpecificTracks() | 2446 void HTMLMediaElement::forgetResourceSpecificTracks() |
2282 { | 2447 { |
2448 // Implements the "forget the media element's media-resource-specific tracks " algorithm. | |
2449 // The order is explicitly specified as text, then audio, and finally video. Also | |
2450 // 'removetrack' events should not be fired. | |
2283 if (m_textTracks) { | 2451 if (m_textTracks) { |
2284 TrackDisplayUpdateScope scope(this); | 2452 TrackDisplayUpdateScope scope(this); |
2285 m_textTracks->removeAllInbandTracks(); | 2453 m_textTracks->removeAllInbandTracks(); |
2286 closeCaptionTracksChanged(); | 2454 closeCaptionTracksChanged(); |
2287 } | 2455 } |
2456 | |
2457 m_audioTracks->removeAll(); | |
2458 m_videoTracks->removeAll(); | |
2288 } | 2459 } |
2289 | 2460 |
2290 PassRefPtr<TextTrack> HTMLMediaElement::addTextTrack(const AtomicString& kind, c onst AtomicString& label, const AtomicString& language, ExceptionState& exceptio nState) | 2461 PassRefPtr<TextTrack> HTMLMediaElement::addTextTrack(const AtomicString& kind, c onst AtomicString& label, const AtomicString& language, ExceptionState& exceptio nState) |
2291 { | 2462 { |
2292 ASSERT(RuntimeEnabledFeatures::videoTrackEnabled()); | 2463 ASSERT(RuntimeEnabledFeatures::videoTrackEnabled()); |
2293 | 2464 |
2294 // 4.8.10.12.4 Text track API | 2465 // 4.8.10.12.4 Text track API |
2295 // The addTextTrack(kind, label, language) method of media elements, when in voked, must run the following steps: | 2466 // The addTextTrack(kind, label, language) method of media elements, when in voked, must run the following steps: |
2296 | 2467 |
2297 // 1. If kind is not one of the following strings, then throw a SyntaxError exception and abort these steps | 2468 // 1. If kind is not one of the following strings, then throw a SyntaxError exception and abort these steps |
(...skipping 831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3129 forgetResourceSpecificTracks(); | 3300 forgetResourceSpecificTracks(); |
3130 | 3301 |
3131 closeMediaSource(); | 3302 closeMediaSource(); |
3132 | 3303 |
3133 m_delayingLoadForPreloadNone = false; | 3304 m_delayingLoadForPreloadNone = false; |
3134 | 3305 |
3135 clearMediaPlayerAndAudioSourceProviderClient(); | 3306 clearMediaPlayerAndAudioSourceProviderClient(); |
3136 | 3307 |
3137 stopPeriodicTimers(); | 3308 stopPeriodicTimers(); |
3138 m_loadTimer.stop(); | 3309 m_loadTimer.stop(); |
3310 m_audioTracksTimer.stop(); | |
3139 | 3311 |
3140 m_pendingActionFlags &= ~flags; | 3312 m_pendingActionFlags &= ~flags; |
3141 m_loadState = WaitingForSource; | 3313 m_loadState = WaitingForSource; |
3142 | 3314 |
3143 if (m_textTracks) | 3315 if (m_textTracks) |
3144 configureTextTrackDisplay(AssumeNoVisibleChange); | 3316 configureTextTrackDisplay(AssumeNoVisibleChange); |
3145 } | 3317 } |
3146 | 3318 |
3147 void HTMLMediaElement::stop() | 3319 void HTMLMediaElement::stop() |
3148 { | 3320 { |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3586 m_fragmentStartTime = MediaPlayer::invalidTime(); | 3758 m_fragmentStartTime = MediaPlayer::invalidTime(); |
3587 | 3759 |
3588 double end = fragmentParser.endTime(); | 3760 double end = fragmentParser.endTime(); |
3589 if (end != MediaFragmentURIParser::invalidTimeValue() && end > 0 && end > m_ fragmentStartTime) { | 3761 if (end != MediaFragmentURIParser::invalidTimeValue() && end > 0 && end > m_ fragmentStartTime) { |
3590 m_fragmentEndTime = end; | 3762 m_fragmentEndTime = end; |
3591 if (m_fragmentEndTime > dur) | 3763 if (m_fragmentEndTime > dur) |
3592 m_fragmentEndTime = dur; | 3764 m_fragmentEndTime = dur; |
3593 } else | 3765 } else |
3594 m_fragmentEndTime = MediaPlayer::invalidTime(); | 3766 m_fragmentEndTime = MediaPlayer::invalidTime(); |
3595 | 3767 |
3768 // FIXME: Add support for selecting tracks by ID with the Media Fragments tr ack dimension. | |
3769 | |
3596 if (m_fragmentStartTime != MediaPlayer::invalidTime() && m_readyState < HAVE _FUTURE_DATA) | 3770 if (m_fragmentStartTime != MediaPlayer::invalidTime() && m_readyState < HAVE _FUTURE_DATA) |
3597 prepareToPlay(); | 3771 prepareToPlay(); |
3598 } | 3772 } |
3599 | 3773 |
3600 void HTMLMediaElement::applyMediaFragmentURI() | 3774 void HTMLMediaElement::applyMediaFragmentURI() |
3601 { | 3775 { |
3602 if (m_fragmentStartTime != MediaPlayer::invalidTime()) { | 3776 if (m_fragmentStartTime != MediaPlayer::invalidTime()) { |
3603 m_sentEndEvent = false; | 3777 m_sentEndEvent = false; |
3604 UseCounter::count(document(), UseCounter::HTMLMediaElementSeekToFragment Start); | 3778 UseCounter::count(document(), UseCounter::HTMLMediaElementSeekToFragment Start); |
3605 seek(m_fragmentStartTime, IGNORE_EXCEPTION); | 3779 seek(m_fragmentStartTime, IGNORE_EXCEPTION); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3644 void HTMLMediaElement::mediaPlayerMediaSourceOpened(blink::WebMediaSource* webMe diaSource) | 3818 void HTMLMediaElement::mediaPlayerMediaSourceOpened(blink::WebMediaSource* webMe diaSource) |
3645 { | 3819 { |
3646 m_mediaSource->setWebMediaSourceAndOpen(adoptPtr(webMediaSource)); | 3820 m_mediaSource->setWebMediaSourceAndOpen(adoptPtr(webMediaSource)); |
3647 } | 3821 } |
3648 | 3822 |
3649 bool HTMLMediaElement::isInteractiveContent() const | 3823 bool HTMLMediaElement::isInteractiveContent() const |
3650 { | 3824 { |
3651 return fastHasAttribute(controlsAttr); | 3825 return fastHasAttribute(controlsAttr); |
3652 } | 3826 } |
3653 | 3827 |
3828 void HTMLMediaElement::createPlaceholderTracksIfNecessary() | |
3829 { | |
3830 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) | |
3831 return; | |
3832 | |
3833 // Create a placeholder audio track if |m_player| says it has audio but it d idn't explicitly announce the tracks. | |
3834 if (m_player->hasAudio() && !audioTracks().length()) | |
3835 addAudioTrack("audio", WebMediaPlayerClient::AudioTrackKindMain, "Audio Track", "", true); | |
3836 | |
3837 // Create a placeholder video track if |m_player| says it has video but it d idn't explicitly announce the tracks. | |
3838 if (m_player->hasVideo() && !videoTracks().length()) | |
3839 addVideoTrack("video", WebMediaPlayerClient::VideoTrackKindMain, "Video Track", "", true); | |
3654 } | 3840 } |
3841 | |
3842 void HTMLMediaElement::selectInitialTracksIfNecessary() | |
3843 { | |
3844 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) | |
3845 return; | |
3846 | |
3847 // Enable the first audio track if an audio track hasn't been enabled yet. | |
3848 if (audioTracks().length() > 0 && !audioTracks().hasEnabledTrack()) | |
3849 audioTracks().anonymousIndexedGetter(0)->setEnabled(true); | |
3850 | |
3851 // Select the first video track if a video track hasn't been selected yet. | |
3852 if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1) | |
3853 videoTracks().anonymousIndexedGetter(0)->setSelected(true); | |
3854 } | |
3855 | |
3856 void HTMLMediaElement::audioTracksTimerFired(Timer<HTMLMediaElement>*) | |
3857 { | |
3858 if (!webMediaPlayer()) | |
3859 return; | |
3860 | |
3861 Vector<String> enabledTrackIDs; | |
3862 for (unsigned i = 0; i < audioTracks().length(); ++i) { | |
3863 RefPtr<AudioTrack> track = audioTracks().anonymousIndexedGetter(i); | |
3864 if (track->enabled()) | |
3865 enabledTrackIDs.append(track->id()); | |
3866 } | |
3867 | |
3868 webMediaPlayer()->enabledAudioTracksChanged(enabledTrackIDs); | |
3869 } | |
3870 | |
3871 } | |
OLD | NEW |