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

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

Issue 284513003: Implement AudioTrack, AudioTrackList, VideoTrack, and VideoTrackList (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: oilpan tracing Created 6 years, 6 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 | Annotate | Revision Log
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 "platform/audio/AudioSourceProviderClient.h" 85 #include "platform/audio/AudioSourceProviderClient.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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 ~TrackDisplayUpdateScope() 162 ~TrackDisplayUpdateScope()
158 { 163 {
159 ASSERT(m_mediaElement); 164 ASSERT(m_mediaElement);
160 m_mediaElement->endIgnoringTrackDisplayUpdateRequests(); 165 m_mediaElement->endIgnoringTrackDisplayUpdateRequests();
161 } 166 }
162 167
163 private: 168 private:
164 HTMLMediaElement* m_mediaElement; 169 HTMLMediaElement* m_mediaElement;
165 }; 170 };
166 171
172 static const AtomicString& AudioKindToString(WebMediaPlayerClient::AudioTrackKin d kind)
173 {
174 switch (kind) {
175 case WebMediaPlayerClient::AudioTrackKindNone:
176 return emptyAtom;
177 case WebMediaPlayerClient::AudioTrackKindAlternative:
178 return AudioTrack::alternativeKeyword();
179 case WebMediaPlayerClient::AudioTrackKindDescriptions:
180 return AudioTrack::descriptionsKeyword();
181 case WebMediaPlayerClient::AudioTrackKindMain:
182 return AudioTrack::mainKeyword();
183 case WebMediaPlayerClient::AudioTrackKindMainDescriptions:
184 return AudioTrack::mainDescriptionsKeyword();
185 case WebMediaPlayerClient::AudioTrackKindTranslation:
186 return AudioTrack::translationKeyword();
187 case WebMediaPlayerClient::AudioTrackKindCommentary:
188 return AudioTrack::commentaryKeyword();
189 }
190
191 ASSERT_NOT_REACHED();
192 return emptyAtom;
193 }
194
195 static const AtomicString& VideoKindToString(WebMediaPlayerClient::VideoTrackKin d kind)
196 {
197 switch (kind) {
198 case WebMediaPlayerClient::VideoTrackKindNone:
199 return emptyAtom;
200 case WebMediaPlayerClient::VideoTrackKindAlternative:
201 return VideoTrack::alternativeKeyword();
202 case WebMediaPlayerClient::VideoTrackKindCaptions:
203 return VideoTrack::captionsKeyword();
204 case WebMediaPlayerClient::VideoTrackKindMain:
205 return VideoTrack::mainKeyword();
206 case WebMediaPlayerClient::VideoTrackKindSign:
207 return VideoTrack::signKeyword();
208 case WebMediaPlayerClient::VideoTrackKindSubtitles:
209 return VideoTrack::subtitlesKeyword();
210 case WebMediaPlayerClient::VideoTrackKindCommentary:
211 return VideoTrack::commentaryKeyword();
212 }
213
214 ASSERT_NOT_REACHED();
215 return emptyAtom;
216 }
217
167 static bool canLoadURL(const KURL& url, const ContentType& contentType, const St ring& keySystem) 218 static bool canLoadURL(const KURL& url, const ContentType& contentType, const St ring& keySystem)
168 { 219 {
169 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); 220 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs"));
170 221
171 String contentMIMEType = contentType.type().lower(); 222 String contentMIMEType = contentType.type().lower();
172 String contentTypeCodecs = contentType.parameter(codecs); 223 String contentTypeCodecs = contentType.parameter(codecs);
173 224
174 // If the MIME type is missing or is not meaningful, try to figure it out fr om the URL. 225 // If the MIME type is missing or is not meaningful, try to figure it out fr om the URL.
175 if (contentMIMEType.isEmpty() || contentMIMEType == "application/octet-strea m" || contentMIMEType == "text/plain") { 226 if (contentMIMEType.isEmpty() || contentMIMEType == "application/octet-strea m" || contentMIMEType == "text/plain") {
176 if (url.protocolIsData()) 227 if (url.protocolIsData())
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 { 279 {
229 return s_mediaStreamRegistry ? s_mediaStreamRegistry->contains(url) : false; 280 return s_mediaStreamRegistry ? s_mediaStreamRegistry->contains(url) : false;
230 } 281 }
231 282
232 HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum ent) 283 HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum ent)
233 : HTMLElement(tagName, document) 284 : HTMLElement(tagName, document)
234 , ActiveDOMObject(&document) 285 , ActiveDOMObject(&document)
235 , m_loadTimer(this, &HTMLMediaElement::loadTimerFired) 286 , m_loadTimer(this, &HTMLMediaElement::loadTimerFired)
236 , m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired) 287 , m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired)
237 , m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFire d) 288 , m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFire d)
289 , m_audioTracksTimer(this, &HTMLMediaElement::audioTracksTimerFired)
238 , m_playedTimeRanges() 290 , m_playedTimeRanges()
239 , m_asyncEventQueue(GenericEventQueue::create(this)) 291 , m_asyncEventQueue(GenericEventQueue::create(this))
240 , m_playbackRate(1.0f) 292 , m_playbackRate(1.0f)
241 , m_defaultPlaybackRate(1.0f) 293 , m_defaultPlaybackRate(1.0f)
242 , m_networkState(NETWORK_EMPTY) 294 , m_networkState(NETWORK_EMPTY)
243 , m_readyState(HAVE_NOTHING) 295 , m_readyState(HAVE_NOTHING)
244 , m_readyStateMaximum(HAVE_NOTHING) 296 , m_readyStateMaximum(HAVE_NOTHING)
245 , m_volume(1.0f) 297 , m_volume(1.0f)
246 , m_lastSeekTime(0) 298 , m_lastSeekTime(0)
247 , m_previousProgressTime(numeric_limits<double>::max()) 299 , m_previousProgressTime(numeric_limits<double>::max())
(...skipping 26 matching lines...) Expand all
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 #if ENABLE(OILPAN) 332 #if ENABLE(OILPAN)
281 , m_isFinalizing(false) 333 , m_isFinalizing(false)
282 #endif 334 #endif
283 , m_lastTextTrackUpdateTime(-1) 335 , m_lastTextTrackUpdateTime(-1)
336 , m_audioTracks(AudioTrackList::create(*this))
337 , m_videoTracks(VideoTrackList::create(*this))
284 , m_textTracks(nullptr) 338 , m_textTracks(nullptr)
285 , m_ignoreTrackDisplayUpdate(0) 339 , m_ignoreTrackDisplayUpdate(0)
286 #if ENABLE(WEB_AUDIO) 340 #if ENABLE(WEB_AUDIO)
287 , m_audioSourceNode(0) 341 , m_audioSourceNode(0)
288 #endif 342 #endif
289 { 343 {
290 ASSERT(RuntimeEnabledFeatures::mediaEnabled()); 344 ASSERT(RuntimeEnabledFeatures::mediaEnabled());
291 345
292 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement"); 346 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement");
293 ScriptWrappable::init(this); 347 ScriptWrappable::init(this);
294 348
295 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes ture()) 349 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes ture())
296 m_userGestureRequiredForPlay = true; 350 m_userGestureRequiredForPlay = true;
297 351
298 setHasCustomStyleCallbacks(); 352 setHasCustomStyleCallbacks();
299 addElementToDocumentMap(this, &document); 353 addElementToDocumentMap(this, &document);
300 } 354 }
301 355
302 HTMLMediaElement::~HTMLMediaElement() 356 HTMLMediaElement::~HTMLMediaElement()
haraken 2014/06/12 01:22:07 Don't you need to stop m_audioTracksTimer when the
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 #if ENABLE(OILPAN) 362 #if ENABLE(OILPAN)
309 // If the HTMLMediaElement dies with the document we are not 363 // If the HTMLMediaElement dies with the document we are not
310 // allowed to touch the document to adjust delay load event counts 364 // allowed to touch the document to adjust delay load event counts
311 // because the document could have been already 365 // because the document could have been already
312 // destructed. However, if the HTMLMediaElement dies with the 366 // destructed. However, if the HTMLMediaElement dies with the
313 // document there is no need to change the delayed load counts 367 // document there is no need to change the delayed load counts
314 // because no load event will fire anyway. If the document is 368 // because no load event will fire anyway. If the document is
315 // still alive we do have to decrement the load delay counts. We 369 // still alive we do have to decrement the load delay counts. We
316 // determine if the document is alive via the ActiveDOMObject 370 // determine if the document is alive via the ActiveDOMObject
317 // which is a context lifecycle observer. If the Document has been 371 // which is a context lifecycle observer. If the Document has been
318 // destructed ActiveDOMObject::executionContext() returns 0. 372 // destructed ActiveDOMObject::executionContext() returns 0.
319 if (ActiveDOMObject::executionContext()) 373 if (ActiveDOMObject::executionContext())
320 setShouldDelayLoadEvent(false); 374 setShouldDelayLoadEvent(false);
321 #else 375 #else
322 setShouldDelayLoadEvent(false); 376 setShouldDelayLoadEvent(false);
323 #endif 377 #endif
324 378
325 #if !ENABLE(OILPAN) 379 #if !ENABLE(OILPAN)
326 if (m_textTracks) 380 if (m_textTracks)
327 m_textTracks->clearOwner(); 381 m_textTracks->clearOwner();
382 m_audioTracks->shutdown();
383 m_videoTracks->shutdown();
haraken 2014/06/12 01:22:06 Don't you need to stop m_audioTracksTimer when the
philipj_slow 2014/06/12 13:22:47 This is in the destructor, and TimerBase's destruc
328 384
329 if (m_mediaController) { 385 if (m_mediaController) {
330 m_mediaController->removeMediaElement(this); 386 m_mediaController->removeMediaElement(this);
331 m_mediaController = nullptr; 387 m_mediaController = nullptr;
332 } 388 }
333 #endif 389 #endif
334 390
335 closeMediaSource(); 391 closeMediaSource();
336 392
337 #if !ENABLE(OILPAN) 393 #if !ENABLE(OILPAN)
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 687
632 void HTMLMediaElement::prepareForLoad() 688 void HTMLMediaElement::prepareForLoad()
633 { 689 {
634 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad"); 690 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad");
635 691
636 // Perform the cleanup required for the resource load algorithm to run. 692 // Perform the cleanup required for the resource load algorithm to run.
637 stopPeriodicTimers(); 693 stopPeriodicTimers();
638 m_loadTimer.stop(); 694 m_loadTimer.stop();
639 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec essary and set m_pendingActionFlags to 0 here. 695 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec essary and set m_pendingActionFlags to 0 here.
640 m_pendingActionFlags &= ~LoadMediaResource; 696 m_pendingActionFlags &= ~LoadMediaResource;
697 m_audioTracksTimer.stop();
641 m_sentEndEvent = false; 698 m_sentEndEvent = false;
642 m_sentStalledEvent = false; 699 m_sentStalledEvent = false;
643 m_haveFiredLoadedData = false; 700 m_haveFiredLoadedData = false;
644 m_completelyLoaded = false; 701 m_completelyLoaded = false;
645 m_havePreparedToPlay = false; 702 m_havePreparedToPlay = false;
646 m_displayMode = Unknown; 703 m_displayMode = Unknown;
647 704
648 // 1 - Abort any already-running instance of the resource selection algorith m for this element. 705 // 1 - Abort any already-running instance of the resource selection algorith m for this element.
649 m_loadState = WaitingForSource; 706 m_loadState = WaitingForSource;
650 m_currentSourceNode = nullptr; 707 m_currentSourceNode = nullptr;
(...skipping 986 matching lines...) Expand 10 before | Expand all | Expand 10 after
1637 finishSeek(); 1694 finishSeek();
1638 } else { 1695 } else {
1639 if (wasPotentiallyPlaying && m_readyState < HAVE_FUTURE_DATA) { 1696 if (wasPotentiallyPlaying && m_readyState < HAVE_FUTURE_DATA) {
1640 // 4.8.10.8 1697 // 4.8.10.8
1641 scheduleTimeupdateEvent(false); 1698 scheduleTimeupdateEvent(false);
1642 scheduleEvent(EventTypeNames::waiting); 1699 scheduleEvent(EventTypeNames::waiting);
1643 } 1700 }
1644 } 1701 }
1645 1702
1646 if (m_readyState >= HAVE_METADATA && oldState < HAVE_METADATA) { 1703 if (m_readyState >= HAVE_METADATA && oldState < HAVE_METADATA) {
1704 createPlaceholderTracksIfNecessary();
1705
1647 prepareMediaFragmentURI(); 1706 prepareMediaFragmentURI();
1707
1708 selectInitialTracksIfNecessary();
1709
1648 scheduleEvent(EventTypeNames::durationchange); 1710 scheduleEvent(EventTypeNames::durationchange);
1649 if (isHTMLVideoElement(*this)) 1711 if (isHTMLVideoElement(*this))
1650 scheduleEvent(EventTypeNames::resize); 1712 scheduleEvent(EventTypeNames::resize);
1651 scheduleEvent(EventTypeNames::loadedmetadata); 1713 scheduleEvent(EventTypeNames::loadedmetadata);
1652 if (hasMediaControls()) 1714 if (hasMediaControls())
1653 mediaControls()->reset(); 1715 mediaControls()->reset();
1654 if (renderer()) 1716 if (renderer())
1655 renderer()->updateFromElement(); 1717 renderer()->updateFromElement();
1656 } 1718 }
1657 1719
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
2249 else 2311 else
2250 m_mediaController->pause(); 2312 m_mediaController->pause();
2251 } else { 2313 } else {
2252 if (paused()) 2314 if (paused())
2253 play(); 2315 play();
2254 else 2316 else
2255 pause(); 2317 pause();
2256 } 2318 }
2257 } 2319 }
2258 2320
2321 AudioTrackList& HTMLMediaElement::audioTracks()
2322 {
2323 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
2324 return *m_audioTracks;
2325 }
2326
2327 void HTMLMediaElement::audioTrackChanged()
2328 {
2329 WTF_LOG(Media, "HTMLMediaElement::audioTrackChanged()");
2330 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
2331
2332 audioTracks().scheduleChangeEvent();
2333
2334 // FIXME: Add call on m_mediaSource to notify it of track changes once the S ourceBuffer.audioTracks attribute is added.
2335
2336 if (!m_audioTracksTimer.isActive())
2337 m_audioTracksTimer.startOneShot(0, FROM_HERE);
2338 }
2339
2340 void HTMLMediaElement::audioTracksTimerFired(Timer<HTMLMediaElement>*)
2341 {
2342 if (!webMediaPlayer())
acolwell GONE FROM CHROMIUM 2014/06/11 19:01:03 Do we need this? Shouldn't we always have a webMed
philipj_slow 2014/06/12 12:08:24 Done.
2343 return;
2344
2345 Vector<WebMediaPlayer::TrackId> enabledTrackIds;
2346 for (unsigned i = 0; i < audioTracks().length(); ++i) {
2347 AudioTrack* track = audioTracks().anonymousIndexedGetter(i);
2348 if (track->enabled())
2349 enabledTrackIds.append(track->trackId());
2350 }
2351
2352 webMediaPlayer()->enabledAudioTracksChanged(enabledTrackIds);
2353 }
2354
2355 WebMediaPlayer::TrackId HTMLMediaElement::addAudioTrack(const String& id, blink: :WebMediaPlayerClient::AudioTrackKind kind, const AtomicString& label, const Ato micString& language, bool enabled)
2356 {
2357 AtomicString kindString = AudioKindToString(kind);
2358 WTF_LOG(Media, "HTMLMediaElement::addAudioTrack('%s', '%s', '%s', '%s', %d)" ,
2359 id.ascii().data(), kindString.ascii().data(), label.ascii().data(), lang uage.ascii().data(), enabled);
2360
2361 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
2362 return 0;
2363
2364 RefPtrWillBeRawPtr<AudioTrack> audioTrack = AudioTrack::create(id, kindStrin g, label, language);
2365 audioTracks().add(audioTrack);
2366
2367 if (enabled)
2368 audioTrack->setEnabled(true);
2369
2370 return audioTrack->trackId();
2371 }
2372
2373 void HTMLMediaElement::removeAudioTrack(WebMediaPlayer::TrackId trackId)
2374 {
2375 WTF_LOG(Media, "HTMLMediaElement::removeAudioTrack()");
2376
2377 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
2378 return;
2379
2380 audioTracks().remove(trackId);
haraken 2014/06/12 01:22:06 Shall we add ASSERT(audioTracks().contains(trackId
philipj_slow 2014/06/12 13:22:47 I've added an ASSERT_NOT_REACHED in TrackListBase:
2381 }
2382
2383 VideoTrackList& HTMLMediaElement::videoTracks()
2384 {
2385 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
2386 return *m_videoTracks;
2387 }
2388
2389 void HTMLMediaElement::selectedVideoTrackChanged(WebMediaPlayer::TrackId* select edTrackId)
2390 {
2391 WTF_LOG(Media, "HTMLMediaElement::selectedVideoTrackChanged()");
2392 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
2393
2394 videoTracks().trackSelected(selectedTrackId);
2395
2396 // FIXME: Add call on m_mediaSource to notify it of track changes once the S ourceBuffer.videoTracks attribute is added.
2397
2398 if (webMediaPlayer())
acolwell GONE FROM CHROMIUM 2014/06/11 19:01:03 Hmm.. It seems like you shouldn't have to make thi
philipj_slow 2014/06/12 12:08:23 Done.
2399 webMediaPlayer()->selectedVideoTrackChanged(selectedTrackId);
2400 }
2401
2402 WebMediaPlayer::TrackId HTMLMediaElement::addVideoTrack(const String& id, blink: :WebMediaPlayerClient::VideoTrackKind kind, const AtomicString& label, const Ato micString& language, bool selected)
2403 {
2404 AtomicString kindString = VideoKindToString(kind);
2405 WTF_LOG(Media, "HTMLMediaElement::addVideoTrack('%s', '%s', '%s', '%s', %d)" ,
2406 id.ascii().data(), kindString.ascii().data(), label.ascii().data(), lang uage.ascii().data(), selected);
2407
2408 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
2409 return 0;
2410
2411 RefPtrWillBeRawPtr<VideoTrack> videoTrack = VideoTrack::create(id, kindStrin g, label, language);
2412 videoTracks().add(videoTrack);
2413
2414 if (selected)
2415 videoTrack->setSelected(true);
2416
2417 return videoTrack->trackId();
2418 }
2419
2420 void HTMLMediaElement::removeVideoTrack(WebMediaPlayer::TrackId trackId)
2421 {
2422 WTF_LOG(Media, "HTMLMediaElement::removeVideoTrack()");
2423
2424 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
2425 return;
2426
2427 videoTracks().remove(trackId);
haraken 2014/06/12 01:22:07 Shall we add ASSERT(!videoTracks().contains(trackI
philipj_slow 2014/06/12 13:22:47 Ditto.
2428 }
2429
2259 void HTMLMediaElement::mediaPlayerDidAddTextTrack(WebInbandTextTrack* webTrack) 2430 void HTMLMediaElement::mediaPlayerDidAddTextTrack(WebInbandTextTrack* webTrack)
2260 { 2431 {
2261 // 4.8.10.12.2 Sourcing in-band text tracks 2432 // 4.8.10.12.2 Sourcing in-band text tracks
2262 // 1. Associate the relevant data with a new text track and its correspondin g new TextTrack object. 2433 // 1. Associate the relevant data with a new text track and its correspondin g new TextTrack object.
2263 RefPtrWillBeRawPtr<InbandTextTrack> textTrack = InbandTextTrack::create(docu ment(), webTrack); 2434 RefPtrWillBeRawPtr<InbandTextTrack> textTrack = InbandTextTrack::create(docu ment(), webTrack);
2264 2435
2265 // 2. Set the new text track's kind, label, and language based on the semant ics of the relevant data, 2436 // 2. Set the new text track's kind, label, and language based on the semant ics of the relevant data,
2266 // as defined by the relevant specification. If there is no label in that da ta, then the label must 2437 // as defined by the relevant specification. If there is no label in that da ta, then the label must
2267 // be set to the empty string. 2438 // be set to the empty string.
2268 // 3. Associate the text track list of cues with the rules for updating the text track rendering appropriate 2439 // 3. Associate the text track list of cues with the rules for updating the text track rendering appropriate
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2318 void HTMLMediaElement::removeTextTrack(TextTrack* track) 2489 void HTMLMediaElement::removeTextTrack(TextTrack* track)
2319 { 2490 {
2320 TrackDisplayUpdateScope scope(this); 2491 TrackDisplayUpdateScope scope(this);
2321 m_textTracks->remove(track); 2492 m_textTracks->remove(track);
2322 2493
2323 closeCaptionTracksChanged(); 2494 closeCaptionTracksChanged();
2324 } 2495 }
2325 2496
2326 void HTMLMediaElement::forgetResourceSpecificTracks() 2497 void HTMLMediaElement::forgetResourceSpecificTracks()
2327 { 2498 {
2499 // Implements the "forget the media element's media-resource-specific tracks " algorithm.
2500 // The order is explicitly specified as text, then audio, and finally video. Also
2501 // 'removetrack' events should not be fired.
2328 if (m_textTracks) { 2502 if (m_textTracks) {
2329 TrackDisplayUpdateScope scope(this); 2503 TrackDisplayUpdateScope scope(this);
2330 m_textTracks->removeAllInbandTracks(); 2504 m_textTracks->removeAllInbandTracks();
2331 closeCaptionTracksChanged(); 2505 closeCaptionTracksChanged();
2332 } 2506 }
2507
2508 m_audioTracks->removeAll();
2509 m_videoTracks->removeAll();
2333 } 2510 }
2334 2511
2335 PassRefPtrWillBeRawPtr<TextTrack> HTMLMediaElement::addTextTrack(const AtomicStr ing& kind, const AtomicString& label, const AtomicString& language, ExceptionSta te& exceptionState) 2512 PassRefPtrWillBeRawPtr<TextTrack> HTMLMediaElement::addTextTrack(const AtomicStr ing& kind, const AtomicString& label, const AtomicString& language, ExceptionSta te& exceptionState)
2336 { 2513 {
2337 // 4.8.10.12.4 Text track API 2514 // 4.8.10.12.4 Text track API
2338 // The addTextTrack(kind, label, language) method of media elements, when in voked, must run the following steps: 2515 // The addTextTrack(kind, label, language) method of media elements, when in voked, must run the following steps:
2339 2516
2340 // 1. If kind is not one of the following strings, then throw a SyntaxError exception and abort these steps 2517 // 1. If kind is not one of the following strings, then throw a SyntaxError exception and abort these steps
2341 if (!TextTrack::isValidKindKeyword(kind)) { 2518 if (!TextTrack::isValidKindKeyword(kind)) {
2342 exceptionState.throwDOMException(SyntaxError, "The 'kind' provided ('" + kind + "') is invalid."); 2519 exceptionState.throwDOMException(SyntaxError, "The 'kind' provided ('" + kind + "') is invalid.");
(...skipping 799 matching lines...) Expand 10 before | Expand all | Expand 10 after
3142 forgetResourceSpecificTracks(); 3319 forgetResourceSpecificTracks();
3143 3320
3144 closeMediaSource(); 3321 closeMediaSource();
3145 3322
3146 m_delayingLoadForPreloadNone = false; 3323 m_delayingLoadForPreloadNone = false;
3147 3324
3148 clearMediaPlayerAndAudioSourceProviderClient(); 3325 clearMediaPlayerAndAudioSourceProviderClient();
3149 3326
3150 stopPeriodicTimers(); 3327 stopPeriodicTimers();
3151 m_loadTimer.stop(); 3328 m_loadTimer.stop();
3329 m_audioTracksTimer.stop();
acolwell GONE FROM CHROMIUM 2014/06/11 19:01:04 Perhaps put this in forgetResourceSpecificTracks()
philipj_slow 2014/06/12 12:08:24 Done.
3152 3330
3153 m_pendingActionFlags &= ~flags; 3331 m_pendingActionFlags &= ~flags;
3154 m_loadState = WaitingForSource; 3332 m_loadState = WaitingForSource;
3155 3333
3156 if (m_textTracks) 3334 if (m_textTracks)
3157 configureTextTrackDisplay(AssumeNoVisibleChange); 3335 configureTextTrackDisplay(AssumeNoVisibleChange);
3158 } 3336 }
3159 3337
3160 void HTMLMediaElement::stop() 3338 void HTMLMediaElement::stop()
3161 { 3339 {
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
3583 m_fragmentStartTime = MediaPlayer::invalidTime(); 3761 m_fragmentStartTime = MediaPlayer::invalidTime();
3584 3762
3585 double end = fragmentParser.endTime(); 3763 double end = fragmentParser.endTime();
3586 if (end != MediaFragmentURIParser::invalidTimeValue() && end > 0 && end > m_ fragmentStartTime) { 3764 if (end != MediaFragmentURIParser::invalidTimeValue() && end > 0 && end > m_ fragmentStartTime) {
3587 m_fragmentEndTime = end; 3765 m_fragmentEndTime = end;
3588 if (m_fragmentEndTime > dur) 3766 if (m_fragmentEndTime > dur)
3589 m_fragmentEndTime = dur; 3767 m_fragmentEndTime = dur;
3590 } else 3768 } else
3591 m_fragmentEndTime = MediaPlayer::invalidTime(); 3769 m_fragmentEndTime = MediaPlayer::invalidTime();
3592 3770
3771 // FIXME: Add support for selecting tracks by ID with the Media Fragments tr ack dimension.
3772
3593 if (m_fragmentStartTime != MediaPlayer::invalidTime() && m_readyState < HAVE _FUTURE_DATA) 3773 if (m_fragmentStartTime != MediaPlayer::invalidTime() && m_readyState < HAVE _FUTURE_DATA)
3594 prepareToPlay(); 3774 prepareToPlay();
3595 } 3775 }
3596 3776
3597 void HTMLMediaElement::applyMediaFragmentURI() 3777 void HTMLMediaElement::applyMediaFragmentURI()
3598 { 3778 {
3599 if (m_fragmentStartTime != MediaPlayer::invalidTime()) { 3779 if (m_fragmentStartTime != MediaPlayer::invalidTime()) {
3600 m_sentEndEvent = false; 3780 m_sentEndEvent = false;
3601 UseCounter::count(document(), UseCounter::HTMLMediaElementSeekToFragment Start); 3781 UseCounter::count(document(), UseCounter::HTMLMediaElementSeekToFragment Start);
3602 seek(m_fragmentStartTime, IGNORE_EXCEPTION); 3782 seek(m_fragmentStartTime, IGNORE_EXCEPTION);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3647 mediaControls()->mediaElementFocused(); 3827 mediaControls()->mediaElementFocused();
3648 } 3828 }
3649 HTMLElement::defaultEventHandler(event); 3829 HTMLElement::defaultEventHandler(event);
3650 } 3830 }
3651 3831
3652 void HTMLMediaElement::trace(Visitor* visitor) 3832 void HTMLMediaElement::trace(Visitor* visitor)
3653 { 3833 {
3654 visitor->trace(m_error); 3834 visitor->trace(m_error);
3655 visitor->trace(m_currentSourceNode); 3835 visitor->trace(m_currentSourceNode);
3656 visitor->trace(m_nextChildNodeToConsider); 3836 visitor->trace(m_nextChildNodeToConsider);
3837 visitor->trace(m_audioTracks);
3838 visitor->trace(m_videoTracks);
3657 visitor->trace(m_textTracks); 3839 visitor->trace(m_textTracks);
3658 visitor->trace(m_textTracksWhenResourceSelectionBegan); 3840 visitor->trace(m_textTracksWhenResourceSelectionBegan);
3659 visitor->trace(m_mediaController); 3841 visitor->trace(m_mediaController);
3660 WillBeHeapSupplementable<HTMLMediaElement>::trace(visitor); 3842 WillBeHeapSupplementable<HTMLMediaElement>::trace(visitor);
3661 HTMLElement::trace(visitor); 3843 HTMLElement::trace(visitor);
3662 } 3844 }
3663 3845
3846 void HTMLMediaElement::createPlaceholderTracksIfNecessary()
3847 {
3848 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
3849 return;
3850
3851 // Create a placeholder audio track if the player says it has audio but it d idn't explicitly announce the tracks.
3852 if (hasAudio() && !audioTracks().length())
3853 addAudioTrack("audio", WebMediaPlayerClient::AudioTrackKindMain, "Audio Track", "", true);
3854
3855 // Create a placeholder video track if the player says it has video but it d idn't explicitly announce the tracks.
3856 if (webMediaPlayer() && webMediaPlayer()->hasVideo() && !videoTracks().lengt h())
3857 addVideoTrack("video", WebMediaPlayerClient::VideoTrackKindMain, "Video Track", "", true);
3664 } 3858 }
3859
3860 void HTMLMediaElement::selectInitialTracksIfNecessary()
3861 {
3862 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
3863 return;
3864
3865 // Enable the first audio track if an audio track hasn't been enabled yet.
3866 if (audioTracks().length() > 0 && !audioTracks().hasEnabledTrack())
3867 audioTracks().anonymousIndexedGetter(0)->setEnabled(true);
3868
3869 // Select the first video track if a video track hasn't been selected yet.
3870 if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1)
3871 videoTracks().anonymousIndexedGetter(0)->setSelected(true);
3872 }
3873
3874 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698