Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(143)

Side by Side Diff: Source/core/html/HTMLMediaElement.cpp

Issue 170233009: Initial implementation of AudioTrack, AudioTrackList, VideoTrack, and VideoTrackList. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@blink-master
Patch Set: Addressed IDL comments. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698