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

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: nits 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
« no previous file with comments | « Source/core/html/HTMLMediaElement.h ('k') | Source/core/html/HTMLMediaElement.idl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 10 matching lines...) Expand all
77 #include "wtf/text/CString.h" 81 #include "wtf/text/CString.h"
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 blink::WebInbandTextTrack; 88 using blink::WebInbandTextTrack;
85 using blink::WebMediaPlayer; 89 using blink::WebMediaPlayer;
86 using blink::WebMimeRegistry; 90 using blink::WebMimeRegistry;
91 using blink::WebMediaPlayerClient;
87 92
88 namespace WebCore { 93 namespace WebCore {
89 94
90 #if !LOG_DISABLED 95 #if !LOG_DISABLED
91 static String urlForLoggingMedia(const KURL& url) 96 static String urlForLoggingMedia(const KURL& url)
92 { 97 {
93 static const unsigned maximumURLLengthForLogging = 128; 98 static const unsigned maximumURLLengthForLogging = 128;
94 99
95 if (url.string().length() < maximumURLLengthForLogging) 100 if (url.string().length() < maximumURLLengthForLogging)
96 return url.string(); 101 return url.string();
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 ~TrackDisplayUpdateScope() 160 ~TrackDisplayUpdateScope()
156 { 161 {
157 ASSERT(m_mediaElement); 162 ASSERT(m_mediaElement);
158 m_mediaElement->endIgnoringTrackDisplayUpdateRequests(); 163 m_mediaElement->endIgnoringTrackDisplayUpdateRequests();
159 } 164 }
160 165
161 private: 166 private:
162 HTMLMediaElement* m_mediaElement; 167 HTMLMediaElement* m_mediaElement;
163 }; 168 };
164 169
170 static const AtomicString& AudioKindToString(WebMediaPlayerClient::AudioTrackKin d kind)
171 {
172 switch (kind) {
173 case WebMediaPlayerClient::AudioTrackKindNone:
174 return emptyAtom;
175 case WebMediaPlayerClient::AudioTrackKindAlternative:
176 return AudioTrack::alternativeKeyword();
177 case WebMediaPlayerClient::AudioTrackKindDescriptions:
178 return AudioTrack::descriptionsKeyword();
179 case WebMediaPlayerClient::AudioTrackKindMain:
180 return AudioTrack::mainKeyword();
181 case WebMediaPlayerClient::AudioTrackKindMainDescriptions:
182 return AudioTrack::mainDescriptionsKeyword();
183 case WebMediaPlayerClient::AudioTrackKindTranslation:
184 return AudioTrack::translationKeyword();
185 case WebMediaPlayerClient::AudioTrackKindCommentary:
186 return AudioTrack::commentaryKeyword();
187 }
188
189 ASSERT_NOT_REACHED();
190 return emptyAtom;
191 }
192
193 static const AtomicString& VideoKindToString(WebMediaPlayerClient::VideoTrackKin d kind)
194 {
195 switch (kind) {
196 case WebMediaPlayerClient::VideoTrackKindNone:
197 return emptyAtom;
198 case WebMediaPlayerClient::VideoTrackKindAlternative:
199 return VideoTrack::alternativeKeyword();
200 case WebMediaPlayerClient::VideoTrackKindCaptions:
201 return VideoTrack::captionsKeyword();
202 case WebMediaPlayerClient::VideoTrackKindMain:
203 return VideoTrack::mainKeyword();
204 case WebMediaPlayerClient::VideoTrackKindSign:
205 return VideoTrack::signKeyword();
206 case WebMediaPlayerClient::VideoTrackKindSubtitles:
207 return VideoTrack::subtitlesKeyword();
208 case WebMediaPlayerClient::VideoTrackKindCommentary:
209 return VideoTrack::commentaryKeyword();
210 }
211
212 ASSERT_NOT_REACHED();
213 return emptyAtom;
214 }
215
165 static bool canLoadURL(const KURL& url, const ContentType& contentType, const St ring& keySystem) 216 static bool canLoadURL(const KURL& url, const ContentType& contentType, const St ring& keySystem)
166 { 217 {
167 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); 218 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs"));
168 219
169 String contentMIMEType = contentType.type().lower(); 220 String contentMIMEType = contentType.type().lower();
170 String contentTypeCodecs = contentType.parameter(codecs); 221 String contentTypeCodecs = contentType.parameter(codecs);
171 222
172 // If the MIME type is missing or is not meaningful, try to figure it out fr om the URL. 223 // If the MIME type is missing or is not meaningful, try to figure it out fr om the URL.
173 if (contentMIMEType.isEmpty() || contentMIMEType == "application/octet-strea m" || contentMIMEType == "text/plain") { 224 if (contentMIMEType.isEmpty() || contentMIMEType == "application/octet-strea m" || contentMIMEType == "text/plain") {
174 if (url.protocolIsData()) 225 if (url.protocolIsData())
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 { 277 {
227 return s_mediaStreamRegistry ? s_mediaStreamRegistry->contains(url) : false; 278 return s_mediaStreamRegistry ? s_mediaStreamRegistry->contains(url) : false;
228 } 279 }
229 280
230 HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum ent) 281 HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum ent)
231 : HTMLElement(tagName, document) 282 : HTMLElement(tagName, document)
232 , ActiveDOMObject(&document) 283 , ActiveDOMObject(&document)
233 , m_loadTimer(this, &HTMLMediaElement::loadTimerFired) 284 , m_loadTimer(this, &HTMLMediaElement::loadTimerFired)
234 , m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired) 285 , m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired)
235 , m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFire d) 286 , m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFire d)
287 , m_audioTracksTimer(this, &HTMLMediaElement::audioTracksTimerFired)
236 , m_playedTimeRanges() 288 , m_playedTimeRanges()
237 , m_asyncEventQueue(GenericEventQueue::create(this)) 289 , m_asyncEventQueue(GenericEventQueue::create(this))
238 , m_playbackRate(1.0f) 290 , m_playbackRate(1.0f)
239 , m_defaultPlaybackRate(1.0f) 291 , m_defaultPlaybackRate(1.0f)
240 , m_networkState(NETWORK_EMPTY) 292 , m_networkState(NETWORK_EMPTY)
241 , m_readyState(HAVE_NOTHING) 293 , m_readyState(HAVE_NOTHING)
242 , m_readyStateMaximum(HAVE_NOTHING) 294 , m_readyStateMaximum(HAVE_NOTHING)
243 , m_volume(1.0f) 295 , m_volume(1.0f)
244 , m_lastSeekTime(0) 296 , m_lastSeekTime(0)
245 , m_previousProgressTime(std::numeric_limits<double>::max()) 297 , m_previousProgressTime(std::numeric_limits<double>::max())
(...skipping 26 matching lines...) Expand all
272 , m_completelyLoaded(false) 324 , m_completelyLoaded(false)
273 , m_havePreparedToPlay(false) 325 , m_havePreparedToPlay(false)
274 , m_delayingLoadForPreloadNone(false) 326 , m_delayingLoadForPreloadNone(false)
275 , m_tracksAreReady(true) 327 , m_tracksAreReady(true)
276 , m_haveVisibleTextTrack(false) 328 , m_haveVisibleTextTrack(false)
277 , m_processingPreferenceChange(false) 329 , m_processingPreferenceChange(false)
278 #if ENABLE(OILPAN) 330 #if ENABLE(OILPAN)
279 , m_isFinalizing(false) 331 , m_isFinalizing(false)
280 #endif 332 #endif
281 , m_lastTextTrackUpdateTime(-1) 333 , m_lastTextTrackUpdateTime(-1)
334 , m_audioTracks(AudioTrackList::create(*this))
335 , m_videoTracks(VideoTrackList::create(*this))
282 , m_textTracks(nullptr) 336 , m_textTracks(nullptr)
283 , m_ignoreTrackDisplayUpdate(0) 337 , m_ignoreTrackDisplayUpdate(0)
284 #if ENABLE(WEB_AUDIO) 338 #if ENABLE(WEB_AUDIO)
285 , m_audioSourceNode(nullptr) 339 , m_audioSourceNode(nullptr)
286 #endif 340 #endif
287 { 341 {
288 ASSERT(RuntimeEnabledFeatures::mediaEnabled()); 342 ASSERT(RuntimeEnabledFeatures::mediaEnabled());
289 343
290 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement"); 344 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement");
291 ScriptWrappable::init(this); 345 ScriptWrappable::init(this);
(...skipping 25 matching lines...) Expand all
317 #else 371 #else
318 // HTMLMediaElement and m_asyncEventQueue always become unreachable 372 // HTMLMediaElement and m_asyncEventQueue always become unreachable
319 // together. So HTMLMediaElemenet and m_asyncEventQueue are destructed in 373 // together. So HTMLMediaElemenet and m_asyncEventQueue are destructed in
320 // the same GC. We don't need to close it explicitly in Oilpan. 374 // the same GC. We don't need to close it explicitly in Oilpan.
321 m_asyncEventQueue->close(); 375 m_asyncEventQueue->close();
322 376
323 setShouldDelayLoadEvent(false); 377 setShouldDelayLoadEvent(false);
324 378
325 if (m_textTracks) 379 if (m_textTracks)
326 m_textTracks->clearOwner(); 380 m_textTracks->clearOwner();
381 m_audioTracks->shutdown();
382 m_videoTracks->shutdown();
327 383
328 if (m_mediaController) { 384 if (m_mediaController) {
329 m_mediaController->removeMediaElement(this); 385 m_mediaController->removeMediaElement(this);
330 m_mediaController = nullptr; 386 m_mediaController = nullptr;
331 } 387 }
332 #endif 388 #endif
333 389
334 closeMediaSource(); 390 closeMediaSource();
335 391
336 #if !ENABLE(OILPAN) 392 #if !ENABLE(OILPAN)
(...skipping 1305 matching lines...) Expand 10 before | Expand all | Expand 10 after
1642 finishSeek(); 1698 finishSeek();
1643 } else { 1699 } else {
1644 if (wasPotentiallyPlaying && m_readyState < HAVE_FUTURE_DATA) { 1700 if (wasPotentiallyPlaying && m_readyState < HAVE_FUTURE_DATA) {
1645 // 4.8.10.8 1701 // 4.8.10.8
1646 scheduleTimeupdateEvent(false); 1702 scheduleTimeupdateEvent(false);
1647 scheduleEvent(EventTypeNames::waiting); 1703 scheduleEvent(EventTypeNames::waiting);
1648 } 1704 }
1649 } 1705 }
1650 1706
1651 if (m_readyState >= HAVE_METADATA && oldState < HAVE_METADATA) { 1707 if (m_readyState >= HAVE_METADATA && oldState < HAVE_METADATA) {
1708 createPlaceholderTracksIfNecessary();
1709
1652 prepareMediaFragmentURI(); 1710 prepareMediaFragmentURI();
1711
1712 selectInitialTracksIfNecessary();
1713
1653 scheduleEvent(EventTypeNames::durationchange); 1714 scheduleEvent(EventTypeNames::durationchange);
1654 if (isHTMLVideoElement(*this)) 1715 if (isHTMLVideoElement(*this))
1655 scheduleEvent(EventTypeNames::resize); 1716 scheduleEvent(EventTypeNames::resize);
1656 scheduleEvent(EventTypeNames::loadedmetadata); 1717 scheduleEvent(EventTypeNames::loadedmetadata);
1657 if (hasMediaControls()) 1718 if (hasMediaControls())
1658 mediaControls()->reset(); 1719 mediaControls()->reset();
1659 if (renderer()) 1720 if (renderer())
1660 renderer()->updateFromElement(); 1721 renderer()->updateFromElement();
1661 } 1722 }
1662 1723
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
2254 else 2315 else
2255 m_mediaController->pause(); 2316 m_mediaController->pause();
2256 } else { 2317 } else {
2257 if (paused()) 2318 if (paused())
2258 play(); 2319 play();
2259 else 2320 else
2260 pause(); 2321 pause();
2261 } 2322 }
2262 } 2323 }
2263 2324
2325 AudioTrackList& HTMLMediaElement::audioTracks()
2326 {
2327 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
2328 return *m_audioTracks;
2329 }
2330
2331 void HTMLMediaElement::audioTrackChanged()
2332 {
2333 WTF_LOG(Media, "HTMLMediaElement::audioTrackChanged()");
2334 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
2335
2336 audioTracks().scheduleChangeEvent();
2337
2338 // FIXME: Add call on m_mediaSource to notify it of track changes once the S ourceBuffer.audioTracks attribute is added.
2339
2340 if (!m_audioTracksTimer.isActive())
2341 m_audioTracksTimer.startOneShot(0, FROM_HERE);
2342 }
2343
2344 void HTMLMediaElement::audioTracksTimerFired(Timer<HTMLMediaElement>*)
2345 {
2346 Vector<WebMediaPlayer::TrackId> enabledTrackIds;
2347 for (unsigned i = 0; i < audioTracks().length(); ++i) {
2348 AudioTrack* track = audioTracks().anonymousIndexedGetter(i);
2349 if (track->enabled())
2350 enabledTrackIds.append(track->trackId());
2351 }
2352
2353 webMediaPlayer()->enabledAudioTracksChanged(enabledTrackIds);
2354 }
2355
2356 WebMediaPlayer::TrackId HTMLMediaElement::addAudioTrack(const String& id, blink: :WebMediaPlayerClient::AudioTrackKind kind, const AtomicString& label, const Ato micString& language, bool enabled)
2357 {
2358 AtomicString kindString = AudioKindToString(kind);
2359 WTF_LOG(Media, "HTMLMediaElement::addAudioTrack('%s', '%s', '%s', '%s', %d)" ,
2360 id.ascii().data(), kindString.ascii().data(), label.ascii().data(), lang uage.ascii().data(), enabled);
2361
2362 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
2363 return 0;
2364
2365 RefPtrWillBeRawPtr<AudioTrack> audioTrack = AudioTrack::create(id, kindStrin g, label, language, enabled);
2366 audioTracks().add(audioTrack);
2367
2368 return audioTrack->trackId();
2369 }
2370
2371 void HTMLMediaElement::removeAudioTrack(WebMediaPlayer::TrackId trackId)
2372 {
2373 WTF_LOG(Media, "HTMLMediaElement::removeAudioTrack()");
2374
2375 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
2376 return;
2377
2378 audioTracks().remove(trackId);
2379 }
2380
2381 VideoTrackList& HTMLMediaElement::videoTracks()
2382 {
2383 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
2384 return *m_videoTracks;
2385 }
2386
2387 void HTMLMediaElement::selectedVideoTrackChanged(WebMediaPlayer::TrackId* select edTrackId)
2388 {
2389 WTF_LOG(Media, "HTMLMediaElement::selectedVideoTrackChanged()");
2390 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
2391
2392 if (selectedTrackId)
2393 videoTracks().trackSelected(*selectedTrackId);
2394
2395 // FIXME: Add call on m_mediaSource to notify it of track changes once the S ourceBuffer.videoTracks attribute is added.
2396
2397 webMediaPlayer()->selectedVideoTrackChanged(selectedTrackId);
2398 }
2399
2400 WebMediaPlayer::TrackId HTMLMediaElement::addVideoTrack(const String& id, blink: :WebMediaPlayerClient::VideoTrackKind kind, const AtomicString& label, const Ato micString& language, bool selected)
2401 {
2402 AtomicString kindString = VideoKindToString(kind);
2403 WTF_LOG(Media, "HTMLMediaElement::addVideoTrack('%s', '%s', '%s', '%s', %d)" ,
2404 id.ascii().data(), kindString.ascii().data(), label.ascii().data(), lang uage.ascii().data(), selected);
2405
2406 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
2407 return 0;
2408
2409 // If another track was selected (potentially by the user), leave it selecte d.
2410 if (selected && videoTracks().selectedIndex() != -1)
2411 selected = false;
2412
2413 RefPtrWillBeRawPtr<VideoTrack> videoTrack = VideoTrack::create(id, kindStrin g, label, language, selected);
2414 videoTracks().add(videoTrack);
2415
2416 return videoTrack->trackId();
2417 }
2418
2419 void HTMLMediaElement::removeVideoTrack(WebMediaPlayer::TrackId trackId)
2420 {
2421 WTF_LOG(Media, "HTMLMediaElement::removeVideoTrack()");
2422
2423 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
2424 return;
2425
2426 videoTracks().remove(trackId);
2427 }
2428
2264 void HTMLMediaElement::mediaPlayerDidAddTextTrack(WebInbandTextTrack* webTrack) 2429 void HTMLMediaElement::mediaPlayerDidAddTextTrack(WebInbandTextTrack* webTrack)
2265 { 2430 {
2266 // 4.8.10.12.2 Sourcing in-band text tracks 2431 // 4.8.10.12.2 Sourcing in-band text tracks
2267 // 1. Associate the relevant data with a new text track and its correspondin g new TextTrack object. 2432 // 1. Associate the relevant data with a new text track and its correspondin g new TextTrack object.
2268 RefPtrWillBeRawPtr<InbandTextTrack> textTrack = InbandTextTrack::create(docu ment(), webTrack); 2433 RefPtrWillBeRawPtr<InbandTextTrack> textTrack = InbandTextTrack::create(docu ment(), webTrack);
2269 2434
2270 // 2. Set the new text track's kind, label, and language based on the semant ics of the relevant data, 2435 // 2. Set the new text track's kind, label, and language based on the semant ics of the relevant data,
2271 // as defined by the relevant specification. If there is no label in that da ta, then the label must 2436 // as defined by the relevant specification. If there is no label in that da ta, then the label must
2272 // be set to the empty string. 2437 // be set to the empty string.
2273 // 3. Associate the text track list of cues with the rules for updating the text track rendering appropriate 2438 // 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
2323 void HTMLMediaElement::removeTextTrack(TextTrack* track) 2488 void HTMLMediaElement::removeTextTrack(TextTrack* track)
2324 { 2489 {
2325 TrackDisplayUpdateScope scope(this); 2490 TrackDisplayUpdateScope scope(this);
2326 m_textTracks->remove(track); 2491 m_textTracks->remove(track);
2327 2492
2328 closeCaptionTracksChanged(); 2493 closeCaptionTracksChanged();
2329 } 2494 }
2330 2495
2331 void HTMLMediaElement::forgetResourceSpecificTracks() 2496 void HTMLMediaElement::forgetResourceSpecificTracks()
2332 { 2497 {
2498 // Implements the "forget the media element's media-resource-specific tracks " algorithm.
2499 // The order is explicitly specified as text, then audio, and finally video. Also
2500 // 'removetrack' events should not be fired.
2333 if (m_textTracks) { 2501 if (m_textTracks) {
2334 TrackDisplayUpdateScope scope(this); 2502 TrackDisplayUpdateScope scope(this);
2335 m_textTracks->removeAllInbandTracks(); 2503 m_textTracks->removeAllInbandTracks();
2336 closeCaptionTracksChanged(); 2504 closeCaptionTracksChanged();
2337 } 2505 }
2506
2507 m_audioTracks->removeAll();
2508 m_videoTracks->removeAll();
2509
2510 m_audioTracksTimer.stop();
2338 } 2511 }
2339 2512
2340 PassRefPtrWillBeRawPtr<TextTrack> HTMLMediaElement::addTextTrack(const AtomicStr ing& kind, const AtomicString& label, const AtomicString& language, ExceptionSta te& exceptionState) 2513 PassRefPtrWillBeRawPtr<TextTrack> HTMLMediaElement::addTextTrack(const AtomicStr ing& kind, const AtomicString& label, const AtomicString& language, ExceptionSta te& exceptionState)
2341 { 2514 {
2342 // 4.8.10.12.4 Text track API 2515 // 4.8.10.12.4 Text track API
2343 // The addTextTrack(kind, label, language) method of media elements, when in voked, must run the following steps: 2516 // The addTextTrack(kind, label, language) method of media elements, when in voked, must run the following steps:
2344 2517
2345 // 1. If kind is not one of the following strings, then throw a SyntaxError exception and abort these steps 2518 // 1. If kind is not one of the following strings, then throw a SyntaxError exception and abort these steps
2346 if (!TextTrack::isValidKindKeyword(kind)) { 2519 if (!TextTrack::isValidKindKeyword(kind)) {
2347 exceptionState.throwDOMException(SyntaxError, "The 'kind' provided ('" + kind + "') is invalid."); 2520 exceptionState.throwDOMException(SyntaxError, "The 'kind' provided ('" + kind + "') is invalid.");
(...skipping 1241 matching lines...) Expand 10 before | Expand all | Expand 10 after
3589 m_fragmentStartTime = MediaPlayer::invalidTime(); 3762 m_fragmentStartTime = MediaPlayer::invalidTime();
3590 3763
3591 double end = fragmentParser.endTime(); 3764 double end = fragmentParser.endTime();
3592 if (end != MediaFragmentURIParser::invalidTimeValue() && end > 0 && end > m_ fragmentStartTime) { 3765 if (end != MediaFragmentURIParser::invalidTimeValue() && end > 0 && end > m_ fragmentStartTime) {
3593 m_fragmentEndTime = end; 3766 m_fragmentEndTime = end;
3594 if (m_fragmentEndTime > dur) 3767 if (m_fragmentEndTime > dur)
3595 m_fragmentEndTime = dur; 3768 m_fragmentEndTime = dur;
3596 } else 3769 } else
3597 m_fragmentEndTime = MediaPlayer::invalidTime(); 3770 m_fragmentEndTime = MediaPlayer::invalidTime();
3598 3771
3772 // FIXME: Add support for selecting tracks by ID with the Media Fragments tr ack dimension.
3773
3599 if (m_fragmentStartTime != MediaPlayer::invalidTime() && m_readyState < HAVE _FUTURE_DATA) 3774 if (m_fragmentStartTime != MediaPlayer::invalidTime() && m_readyState < HAVE _FUTURE_DATA)
3600 prepareToPlay(); 3775 prepareToPlay();
3601 } 3776 }
3602 3777
3603 void HTMLMediaElement::applyMediaFragmentURI() 3778 void HTMLMediaElement::applyMediaFragmentURI()
3604 { 3779 {
3605 if (m_fragmentStartTime != MediaPlayer::invalidTime()) { 3780 if (m_fragmentStartTime != MediaPlayer::invalidTime()) {
3606 m_sentEndEvent = false; 3781 m_sentEndEvent = false;
3607 UseCounter::count(document(), UseCounter::HTMLMediaElementSeekToFragment Start); 3782 UseCounter::count(document(), UseCounter::HTMLMediaElementSeekToFragment Start);
3608 seek(m_fragmentStartTime, IGNORE_EXCEPTION); 3783 seek(m_fragmentStartTime, IGNORE_EXCEPTION);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3654 } 3829 }
3655 HTMLElement::defaultEventHandler(event); 3830 HTMLElement::defaultEventHandler(event);
3656 } 3831 }
3657 3832
3658 void HTMLMediaElement::trace(Visitor* visitor) 3833 void HTMLMediaElement::trace(Visitor* visitor)
3659 { 3834 {
3660 visitor->trace(m_asyncEventQueue); 3835 visitor->trace(m_asyncEventQueue);
3661 visitor->trace(m_error); 3836 visitor->trace(m_error);
3662 visitor->trace(m_currentSourceNode); 3837 visitor->trace(m_currentSourceNode);
3663 visitor->trace(m_nextChildNodeToConsider); 3838 visitor->trace(m_nextChildNodeToConsider);
3839 visitor->trace(m_audioTracks);
3840 visitor->trace(m_videoTracks);
3664 visitor->trace(m_textTracks); 3841 visitor->trace(m_textTracks);
3665 visitor->trace(m_textTracksWhenResourceSelectionBegan); 3842 visitor->trace(m_textTracksWhenResourceSelectionBegan);
3666 visitor->trace(m_mediaController); 3843 visitor->trace(m_mediaController);
3667 #if ENABLE(WEB_AUDIO) 3844 #if ENABLE(WEB_AUDIO)
3668 visitor->registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::clearWeakM embers>(this); 3845 visitor->registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::clearWeakM embers>(this);
3669 #endif 3846 #endif
3670 WillBeHeapSupplementable<HTMLMediaElement>::trace(visitor); 3847 WillBeHeapSupplementable<HTMLMediaElement>::trace(visitor);
3671 HTMLElement::trace(visitor); 3848 HTMLElement::trace(visitor);
3672 } 3849 }
3673 3850
3851 void HTMLMediaElement::createPlaceholderTracksIfNecessary()
3852 {
3853 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
3854 return;
3855
3856 // Create a placeholder audio track if the player says it has audio but it d idn't explicitly announce the tracks.
3857 if (hasAudio() && !audioTracks().length())
3858 addAudioTrack("audio", WebMediaPlayerClient::AudioTrackKindMain, "Audio Track", "", true);
3859
3860 // Create a placeholder video track if the player says it has video but it d idn't explicitly announce the tracks.
3861 if (webMediaPlayer() && webMediaPlayer()->hasVideo() && !videoTracks().lengt h())
3862 addVideoTrack("video", WebMediaPlayerClient::VideoTrackKindMain, "Video Track", "", true);
3863 }
3864
3865 void HTMLMediaElement::selectInitialTracksIfNecessary()
3866 {
3867 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
3868 return;
3869
3870 // Enable the first audio track if an audio track hasn't been enabled yet.
3871 if (audioTracks().length() > 0 && !audioTracks().hasEnabledTrack())
3872 audioTracks().anonymousIndexedGetter(0)->setEnabled(true);
3873
3874 // Select the first video track if a video track hasn't been selected yet.
3875 if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1)
3876 videoTracks().anonymousIndexedGetter(0)->setSelected(true);
3877 }
3878
3674 #if ENABLE(WEB_AUDIO) 3879 #if ENABLE(WEB_AUDIO)
3675 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) 3880 void HTMLMediaElement::clearWeakMembers(Visitor* visitor)
3676 { 3881 {
3677 if (!visitor->isAlive(m_audioSourceNode) && audioSourceProvider()) 3882 if (!visitor->isAlive(m_audioSourceNode) && audioSourceProvider())
3678 audioSourceProvider()->setClient(0); 3883 audioSourceProvider()->setClient(0);
3679 } 3884 }
3680 #endif 3885 #endif
3681 3886
3682 } 3887 }
OLDNEW
« no previous file with comments | « Source/core/html/HTMLMediaElement.h ('k') | Source/core/html/HTMLMediaElement.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698