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

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: Created 6 years, 10 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 #include "core/html/HTMLMediaSource.h" 47 #include "core/html/HTMLMediaSource.h"
48 #include "core/html/HTMLSourceElement.h" 48 #include "core/html/HTMLSourceElement.h"
49 #include "core/html/HTMLTrackElement.h" 49 #include "core/html/HTMLTrackElement.h"
50 #include "core/html/MediaController.h" 50 #include "core/html/MediaController.h"
51 #include "core/html/MediaError.h" 51 #include "core/html/MediaError.h"
52 #include "core/html/MediaFragmentURIParser.h" 52 #include "core/html/MediaFragmentURIParser.h"
53 #include "core/html/MediaKeyError.h" 53 #include "core/html/MediaKeyError.h"
54 #include "core/html/MediaKeyEvent.h" 54 #include "core/html/MediaKeyEvent.h"
55 #include "core/html/TimeRanges.h" 55 #include "core/html/TimeRanges.h"
56 #include "core/html/shadow/MediaControls.h" 56 #include "core/html/shadow/MediaControls.h"
57 #include "core/html/track/AudioTrack.h"
58 #include "core/html/track/AudioTrackList.h"
57 #include "core/html/track/InbandTextTrack.h" 59 #include "core/html/track/InbandTextTrack.h"
58 #include "core/html/track/TextTrackCueList.h" 60 #include "core/html/track/TextTrackCueList.h"
59 #include "core/html/track/TextTrackList.h" 61 #include "core/html/track/TextTrackList.h"
62 #include "core/html/track/VideoTrack.h"
63 #include "core/html/track/VideoTrackList.h"
60 #include "core/loader/FrameLoader.h" 64 #include "core/loader/FrameLoader.h"
61 #include "core/rendering/RenderLayerCompositor.h" 65 #include "core/rendering/RenderLayerCompositor.h"
62 #include "core/rendering/RenderVideo.h" 66 #include "core/rendering/RenderVideo.h"
63 #include "core/rendering/RenderView.h" 67 #include "core/rendering/RenderView.h"
64 // FIXME: Remove dependency on modules/encryptedmedia (http://crbug.com/242754). 68 // FIXME: Remove dependency on modules/encryptedmedia (http://crbug.com/242754).
65 #include "modules/encryptedmedia/MediaKeyNeededEvent.h" 69 #include "modules/encryptedmedia/MediaKeyNeededEvent.h"
66 #include "modules/encryptedmedia/MediaKeys.h" 70 #include "modules/encryptedmedia/MediaKeys.h"
67 #include "platform/ContentType.h" 71 #include "platform/ContentType.h"
68 #include "platform/Language.h" 72 #include "platform/Language.h"
69 #include "platform/Logging.h" 73 #include "platform/Logging.h"
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 , m_sentStalledEvent(false) 299 , m_sentStalledEvent(false)
296 , m_sentEndEvent(false) 300 , m_sentEndEvent(false)
297 , m_pausedInternal(false) 301 , m_pausedInternal(false)
298 , m_closedCaptionsVisible(false) 302 , m_closedCaptionsVisible(false)
299 , m_completelyLoaded(false) 303 , m_completelyLoaded(false)
300 , m_havePreparedToPlay(false) 304 , m_havePreparedToPlay(false)
301 , m_tracksAreReady(true) 305 , m_tracksAreReady(true)
302 , m_haveVisibleTextTrack(false) 306 , m_haveVisibleTextTrack(false)
303 , m_processingPreferenceChange(false) 307 , m_processingPreferenceChange(false)
304 , m_lastTextTrackUpdateTime(-1) 308 , m_lastTextTrackUpdateTime(-1)
309 , m_audioTracks(nullptr)
310 , m_videoTracks(nullptr)
305 , m_textTracks(nullptr) 311 , m_textTracks(nullptr)
306 , m_ignoreTrackDisplayUpdate(0) 312 , m_ignoreTrackDisplayUpdate(0)
307 #if ENABLE(WEB_AUDIO) 313 #if ENABLE(WEB_AUDIO)
308 , m_audioSourceNode(0) 314 , m_audioSourceNode(0)
309 #endif 315 #endif
310 , m_emeMode(EmeModeNotSelected) 316 , m_emeMode(EmeModeNotSelected)
311 { 317 {
312 ASSERT(RuntimeEnabledFeatures::mediaEnabled()); 318 ASSERT(RuntimeEnabledFeatures::mediaEnabled());
313 319
314 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement"); 320 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement");
(...skipping 13 matching lines...) Expand all
328 addElementToDocumentMap(this, &document); 334 addElementToDocumentMap(this, &document);
329 } 335 }
330 336
331 HTMLMediaElement::~HTMLMediaElement() 337 HTMLMediaElement::~HTMLMediaElement()
332 { 338 {
333 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement"); 339 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement");
334 340
335 m_asyncEventQueue->close(); 341 m_asyncEventQueue->close();
336 342
337 setShouldDelayLoadEvent(false); 343 setShouldDelayLoadEvent(false);
344 if (m_audioTracks)
345 m_audioTracks->clearOwner();
346 if (m_videoTracks)
347 m_videoTracks->clearOwner();
338 if (m_textTracks) 348 if (m_textTracks)
339 m_textTracks->clearOwner(); 349 m_textTracks->clearOwnerAndClients();
340 if (m_textTracks) {
341 for (unsigned i = 0; i < m_textTracks->length(); ++i)
342 m_textTracks->item(i)->clearClient();
343 }
344 350
345 if (m_mediaController) { 351 if (m_mediaController) {
346 m_mediaController->removeMediaElement(this); 352 m_mediaController->removeMediaElement(this);
347 m_mediaController = nullptr; 353 m_mediaController = nullptr;
348 } 354 }
349 355
350 closeMediaSource(); 356 closeMediaSource();
351 357
352 setMediaKeysInternal(0); 358 setMediaKeysInternal(0);
353 359
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 // a task to fire a simple event named abort at the media element. 662 // a task to fire a simple event named abort at the media element.
657 if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE) 663 if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE)
658 scheduleEvent(EventTypeNames::abort); 664 scheduleEvent(EventTypeNames::abort);
659 665
660 closeMediaSource(); 666 closeMediaSource();
661 667
662 createMediaPlayer(); 668 createMediaPlayer();
663 669
664 // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps 670 // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps
665 if (m_networkState != NETWORK_EMPTY) { 671 if (m_networkState != NETWORK_EMPTY) {
672 // 4.1 - Queue a task to fire a simple event named emptied at the media element.
673 scheduleEvent(EventTypeNames::emptied);
674
675 // 4.2 - If a fetching process is in progress for the media element, the user agent should stop it.
666 m_networkState = NETWORK_EMPTY; 676 m_networkState = NETWORK_EMPTY;
677
678 // 4.3 - Forget the media element's media-resource-specific tracks.
679 forgetResourceSpecificTracks();
680
681 // 4.4 - If readyState is not set to HAVE_NOTHING, then set it to that s tate.
667 m_readyState = HAVE_NOTHING; 682 m_readyState = HAVE_NOTHING;
668 m_readyStateMaximum = HAVE_NOTHING; 683 m_readyStateMaximum = HAVE_NOTHING;
684
685 // 4.5 - If the paused attribute is false, then set it to true.
686 m_paused = true;
687
688 // 4.6 - If seeking is true, set it to false.
689 m_seeking = false;
690
691 // 4.7 - Set the current playback position to 0.
692 // Set the official playback position to 0.
693 // If this changed the official playback position, then queue a ta sk to fire a simple event named timeupdate at the media element.
694
695 // 4.8 - Set the initial playback position to 0.
696 // FIXME: Make this less subtle. The position only becomes 0 because of the createMediaPlayer() call
697 // above.
669 refreshCachedTime(); 698 refreshCachedTime();
670 m_paused = true;
671 m_seeking = false;
672 invalidateCachedTime(); 699 invalidateCachedTime();
673 scheduleEvent(EventTypeNames::emptied); 700
701 // 4.9 - Set the timeline offset to Not-a-Number (NaN).
702 // 4.10 - Update the duration attribute to Not-a-Number (NaN).
703
674 updateMediaController(); 704 updateMediaController();
675 if (RuntimeEnabledFeatures::videoTrackEnabled()) 705 if (RuntimeEnabledFeatures::videoTrackEnabled())
676 updateActiveTextTrackCues(0); 706 updateActiveTextTrackCues(0);
677 } 707 }
678 708
679 // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRat e attribute. 709 // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRat e attribute.
680 setPlaybackRate(defaultPlaybackRate()); 710 setPlaybackRate(defaultPlaybackRate());
681 711
682 // 6 - Set the error attribute to null and the autoplaying flag to true. 712 // 6 - Set the error attribute to null and the autoplaying flag to true.
683 m_error = nullptr; 713 m_error = nullptr;
684 m_autoplaying = true; 714 m_autoplaying = true;
685 715
686 // 7 - Invoke the media element's resource selection algorithm. 716 // 7 - Invoke the media element's resource selection algorithm.
687 717
688 // 8 - Note: Playback of any previously playing media resource for this elem ent stops. 718 // 8 - Note: Playback of any previously playing media resource for this elem ent stops.
689 719
690 // The resource selection algorithm 720 // The resource selection algorithm
691 // 1 - Set the networkState to NETWORK_NO_SOURCE 721 // 1 - Set the networkState to NETWORK_NO_SOURCE
692 m_networkState = NETWORK_NO_SOURCE; 722 m_networkState = NETWORK_NO_SOURCE;
693 723
694 // 2 - Asynchronously await a stable state. 724 // 2 - Asynchronously await a stable state.
695 725
696 m_playedTimeRanges = TimeRanges::create(); 726 m_playedTimeRanges = TimeRanges::create();
727
728 // FIXME: Investigate whether these can be moved into m_networkState != NETW ORK_EMPTY block above
729 // so they are closer to the relevant spec steps.
697 m_lastSeekTime = 0; 730 m_lastSeekTime = 0;
698 m_duration = numeric_limits<double>::quiet_NaN(); 731 m_duration = numeric_limits<double>::quiet_NaN();
699 732
700 // The spec doesn't say to block the load event until we actually run the as ynchronous section 733 // The spec doesn't say to block the load event until we actually run the as ynchronous section
701 // algorithm, but do it now because we won't start that until after the time r fires and the 734 // algorithm, but do it now because we won't start that until after the time r fires and the
702 // event may have already fired by then. 735 // event may have already fired by then.
703 setShouldDelayLoadEvent(true); 736 setShouldDelayLoadEvent(true);
704 737
705 configureMediaControls(); 738 configureMediaControls();
706 } 739 }
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after
1357 1390
1358 // 4.8.10.5 1391 // 4.8.10.5
1359 // 6 - Reaching this step indicates that the media resource failed to load o r that the given 1392 // 6 - Reaching this step indicates that the media resource failed to load o r that the given
1360 // URL could not be resolved. In one atomic operation, run the following ste ps: 1393 // URL could not be resolved. In one atomic operation, run the following ste ps:
1361 1394
1362 // 6.1 - Set the error attribute to a new MediaError object whose code attri bute is set to 1395 // 6.1 - Set the error attribute to a new MediaError object whose code attri bute is set to
1363 // MEDIA_ERR_SRC_NOT_SUPPORTED. 1396 // MEDIA_ERR_SRC_NOT_SUPPORTED.
1364 m_error = MediaError::create(MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED); 1397 m_error = MediaError::create(MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED);
1365 1398
1366 // 6.2 - Forget the media element's media-resource-specific text tracks. 1399 // 6.2 - Forget the media element's media-resource-specific text tracks.
1400 forgetResourceSpecificTracks();
1367 1401
1368 // 6.3 - Set the element's networkState attribute to the NETWORK_NO_SOURCE v alue. 1402 // 6.3 - Set the element's networkState attribute to the NETWORK_NO_SOURCE v alue.
1369 m_networkState = NETWORK_NO_SOURCE; 1403 m_networkState = NETWORK_NO_SOURCE;
1370 1404
1371 // 7 - Queue a task to fire a simple event named error at the media element. 1405 // 7 - Queue a task to fire a simple event named error at the media element.
1372 scheduleEvent(EventTypeNames::error); 1406 scheduleEvent(EventTypeNames::error);
1373 1407
1374 closeMediaSource(); 1408 closeMediaSource();
1375 1409
1376 // 8 - Set the element's delaying-the-load-event flag to false. This stops d elaying the load event. 1410 // 8 - Set the element's delaying-the-load-event flag to false. This stops d elaying the load event.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1430 setNetworkState(m_player->networkState()); 1464 setNetworkState(m_player->networkState());
1431 } 1465 }
1432 1466
1433 void HTMLMediaElement::mediaLoadingFailed(MediaPlayer::NetworkState error) 1467 void HTMLMediaElement::mediaLoadingFailed(MediaPlayer::NetworkState error)
1434 { 1468 {
1435 stopPeriodicTimers(); 1469 stopPeriodicTimers();
1436 1470
1437 // If we failed while trying to load a <source> element, the movie was never parsed, and there are more 1471 // If we failed while trying to load a <source> element, the movie was never parsed, and there are more
1438 // <source> children, schedule the next one 1472 // <source> children, schedule the next one
1439 if (m_readyState < HAVE_METADATA && m_loadState == LoadingFromSourceElement) { 1473 if (m_readyState < HAVE_METADATA && m_loadState == LoadingFromSourceElement) {
1440 1474 // resource selection algorithm
1475 // Step 9.Otherwise.9 - Failed with elements: Queue a task, using the DO M manipulation task source, to fire a simple event named error at the candidate element.
1441 if (m_currentSourceNode) 1476 if (m_currentSourceNode)
1442 m_currentSourceNode->scheduleErrorEvent(); 1477 m_currentSourceNode->scheduleErrorEvent();
1443 else 1478 else
1444 WTF_LOG(Media, "HTMLMediaElement::setNetworkState - error event not sent, <source> was removed"); 1479 WTF_LOG(Media, "HTMLMediaElement::setNetworkState - error event not sent, <source> was removed");
1445 1480
1481 // 9.Otherwise.10 - Asynchronously await a stable state. The synchronous section consists of all the remaining steps of this algorithm until the algorit hm says the synchronous section has ended. (Steps in synchronous sections are ma rked with ⌛.)
1482
1483 // 9.Otherwise.11 Forget the media element's media-resource-specific tra cks.
1484 forgetResourceSpecificTracks();
1485
1446 if (havePotentialSourceChild()) { 1486 if (havePotentialSourceChild()) {
1447 WTF_LOG(Media, "HTMLMediaElement::setNetworkState - scheduling next <source>"); 1487 WTF_LOG(Media, "HTMLMediaElement::setNetworkState - scheduling next <source>");
1448 scheduleNextSourceChild(); 1488 scheduleNextSourceChild();
1449 } else { 1489 } else {
1450 WTF_LOG(Media, "HTMLMediaElement::setNetworkState - no more <source> elements, waiting"); 1490 WTF_LOG(Media, "HTMLMediaElement::setNetworkState - no more <source> elements, waiting");
1451 waitForSourceChange(); 1491 waitForSourceChange();
1452 } 1492 }
1453 1493
1454 return; 1494 return;
1455 } 1495 }
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1567 finishSeek(); 1607 finishSeek();
1568 } else { 1608 } else {
1569 if (wasPotentiallyPlaying && m_readyState < HAVE_FUTURE_DATA) { 1609 if (wasPotentiallyPlaying && m_readyState < HAVE_FUTURE_DATA) {
1570 // 4.8.10.8 1610 // 4.8.10.8
1571 scheduleTimeupdateEvent(false); 1611 scheduleTimeupdateEvent(false);
1572 scheduleEvent(EventTypeNames::waiting); 1612 scheduleEvent(EventTypeNames::waiting);
1573 } 1613 }
1574 } 1614 }
1575 1615
1576 if (m_readyState >= HAVE_METADATA && oldState < HAVE_METADATA) { 1616 if (m_readyState >= HAVE_METADATA && oldState < HAVE_METADATA) {
1617 createPlaceholderTracksIfNecessary();
1618
1577 prepareMediaFragmentURI(); 1619 prepareMediaFragmentURI();
1620
1621 selectInitialTracksIfNecessary();
1622
1578 scheduleEvent(EventTypeNames::durationchange); 1623 scheduleEvent(EventTypeNames::durationchange);
1579 if (isVideo()) 1624 if (isVideo())
1580 scheduleEvent(EventTypeNames::resize); 1625 scheduleEvent(EventTypeNames::resize);
1581 scheduleEvent(EventTypeNames::loadedmetadata); 1626 scheduleEvent(EventTypeNames::loadedmetadata);
1582 if (hasMediaControls()) 1627 if (hasMediaControls())
1583 mediaControls()->reset(); 1628 mediaControls()->reset();
1584 if (renderer()) 1629 if (renderer())
1585 renderer()->updateFromElement(); 1630 renderer()->updateFromElement();
1586 } 1631 }
1587 1632
(...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after
2445 m_lastTimeUpdateEventWallTime = now; 2490 m_lastTimeUpdateEventWallTime = now;
2446 m_lastTimeUpdateEventMovieTime = movieTime; 2491 m_lastTimeUpdateEventMovieTime = movieTime;
2447 } 2492 }
2448 } 2493 }
2449 2494
2450 bool HTMLMediaElement::canPlay() const 2495 bool HTMLMediaElement::canPlay() const
2451 { 2496 {
2452 return paused() || ended() || m_readyState < HAVE_METADATA; 2497 return paused() || ended() || m_readyState < HAVE_METADATA;
2453 } 2498 }
2454 2499
2455 void HTMLMediaElement::mediaPlayerDidAddTrack(WebInbandTextTrack* webTrack) 2500 AudioTrackList* HTMLMediaElement::audioTracks()
2501 {
2502 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
2503
2504 if (!m_audioTracks)
2505 m_audioTracks = AudioTrackList::create(this);
2506
2507 return m_audioTracks.get();
2508 }
2509
2510 void HTMLMediaElement::didEnabledAudioTrackChange(const AtomicString& audioTrack ID, bool enabled)
2511 {
2512 WTF_LOG(Media, "HTMLMediaElement::didEnabledAudioTrackChange('%s', %d)", aud ioTrackID.ascii().data(), enabled);
2513 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
2514 ASSERT(!audioTrackID.isEmpty());
2515
2516 if (webMediaPlayer())
2517 webMediaPlayer()->enabledAudioTrackChange(audioTrackID, enabled);
2518 }
2519
2520 VideoTrackList* HTMLMediaElement::videoTracks()
2521 {
2522 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
2523
2524 if (!m_videoTracks)
2525 m_videoTracks = VideoTrackList::create(this);
2526
2527 return m_videoTracks.get();
2528 }
2529
2530 void HTMLMediaElement::didSelectedVideoTrackChange(const AtomicString& unselecte dTrackID, const AtomicString& selectedTrackID)
2531 {
2532 WTF_LOG(Media, "HTMLMediaElement::didSelectedVideoTrackChange('%s', '%s')", unselectedTrackID.ascii().data(), selectedTrackID.ascii().data());
2533 ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
2534 ASSERT(!unselectedTrackID.isEmpty() || !selectedTrackID.isEmpty());
2535
2536 if (webMediaPlayer())
2537 webMediaPlayer()->selectedVideoTrackChange(unselectedTrackID, selectedTr ackID);
2538 }
2539
2540 void HTMLMediaElement::mediaPlayerDidAddVideoTrack(const AtomicString& id, const AtomicString& kind, const AtomicString& label, const AtomicString& language, bo ol selected)
2541 {
2542 WTF_LOG(Media, "HTMLMediaElement::mediaPlayerDidAddVideoTrack('%s', '%s', '% s', '%s', %d)",
2543 id.ascii().data(), kind.ascii().data(), label.ascii().data(), language.a scii().data(), selected);
2544 ASSERT(!id.isEmpty());
2545
2546 RefPtr<VideoTrack> videoTrack = VideoTrack::create(videoTracks(), id, kind, label, language);
2547 videoTracks()->add(videoTrack.get());
2548
2549 if (selected)
2550 videoTrack->setSelected(true);
2551 }
2552
2553 void HTMLMediaElement::mediaPlayerDidRemoveVideoTrack(const AtomicString& id)
2554 {
2555 WTF_LOG(Media, "HTMLMediaElement::mediaPlayerDidRevmoeVideoTrack('%s')", id. ascii().data());
2556 ASSERT(!id.isEmpty());
2557
2558 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
2559 return;
2560
2561 videoTracks()->remove(id);
2562 }
2563
2564 void HTMLMediaElement::mediaPlayerDidAddAudioTrack(const AtomicString& id, const AtomicString& kind, const AtomicString& label, const AtomicString& language, bo ol enabled)
2565 {
2566 WTF_LOG(Media, "HTMLMediaElement::mediaPlayerDidAddAudioTrack('%s', '%s', '% s', '%s', %d)",
2567 id.ascii().data(), kind.ascii().data(), label.ascii().data(), language.a scii().data(), enabled);
2568 ASSERT(!id.isEmpty());
2569
2570 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
2571 return;
2572
2573 AtomicString kindString;
2574 RefPtr<AudioTrack> audioTrack = AudioTrack::create(audioTracks(), id, kind, label, language);
2575 audioTracks()->add(audioTrack.get());
2576
2577 if (enabled)
2578 audioTrack->setEnabled(true);
2579 }
2580
2581 void HTMLMediaElement::mediaPlayerDidRemoveAudioTrack(const AtomicString& id)
2582 {
2583 WTF_LOG(Media, "HTMLMediaElement::mediaPlayerDidRevmoeAudioTrack('%s')", id. ascii().data());
2584 ASSERT(!id.isEmpty());
2585
2586 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
2587 return;
2588
2589 audioTracks()->remove(id);
2590 }
2591
2592 void HTMLMediaElement::mediaPlayerDidAddTextTrack(WebInbandTextTrack* webTrack)
2456 { 2593 {
2457 if (!RuntimeEnabledFeatures::videoTrackEnabled()) 2594 if (!RuntimeEnabledFeatures::videoTrackEnabled())
2458 return; 2595 return;
2459 2596
2460 // 4.8.10.12.2 Sourcing in-band text tracks 2597 // 4.8.10.12.2 Sourcing in-band text tracks
2461 // 1. Associate the relevant data with a new text track and its correspondin g new TextTrack object. 2598 // 1. Associate the relevant data with a new text track and its correspondin g new TextTrack object.
2462 RefPtr<InbandTextTrack> textTrack = InbandTextTrack::create(document(), this , webTrack); 2599 RefPtr<InbandTextTrack> textTrack = InbandTextTrack::create(document(), this , webTrack);
2463 2600
2464 // 2. Set the new text track's kind, label, and language based on the semant ics of the relevant data, 2601 // 2. Set the new text track's kind, label, and language based on the semant ics of the relevant data,
2465 // as defined by the relevant specification. If there is no label in that da ta, then the label must 2602 // as defined by the relevant specification. If there is no label in that da ta, then the label must
(...skipping 11 matching lines...) Expand all
2477 2614
2478 // 7. Set the new text track's mode to the mode consistent with the user's p references and the requirements of 2615 // 7. Set the new text track's mode to the mode consistent with the user's p references and the requirements of
2479 // the relevant specification for the data. 2616 // the relevant specification for the data.
2480 // - This will happen in configureTextTracks() 2617 // - This will happen in configureTextTracks()
2481 scheduleDelayedAction(LoadTextTrackResource); 2618 scheduleDelayedAction(LoadTextTrackResource);
2482 2619
2483 // 8. Add the new text track to the media element's list of text tracks. 2620 // 8. Add the new text track to the media element's list of text tracks.
2484 // 9. Fire an event with the name addtrack, that does not bubble and is not cancelable, and that uses the TrackEvent 2621 // 9. Fire an event with the name addtrack, that does not bubble and is not cancelable, and that uses the TrackEvent
2485 // interface, with the track attribute initialized to the text track's TextT rack object, at the media element's 2622 // interface, with the track attribute initialized to the text track's TextT rack object, at the media element's
2486 // textTracks attribute's TextTrackList object. 2623 // textTracks attribute's TextTrackList object.
2487 addTrack(textTrack.get()); 2624 addTextTrack(textTrack.get());
2488 } 2625 }
2489 2626
2490 void HTMLMediaElement::mediaPlayerDidRemoveTrack(WebInbandTextTrack* webTrack) 2627 void HTMLMediaElement::mediaPlayerDidRemoveTextTrack(WebInbandTextTrack* webTrac k)
2491 { 2628 {
2492 if (!RuntimeEnabledFeatures::videoTrackEnabled()) 2629 if (!RuntimeEnabledFeatures::videoTrackEnabled())
2493 return; 2630 return;
2494 2631
2495 if (!m_textTracks) 2632 if (!m_textTracks)
2496 return; 2633 return;
2497 2634
2498 // This cast is safe because we created the InbandTextTrack with the WebInba ndTextTrack 2635 // This cast is safe because we created the InbandTextTrack with the WebInba ndTextTrack
2499 // passed to mediaPlayerDidAddTrack. 2636 // passed to mediaPlayerDidAddTrack.
2500 RefPtr<InbandTextTrack> textTrack = static_cast<InbandTextTrack*>(webTrack-> client()); 2637 RefPtr<InbandTextTrack> textTrack = static_cast<InbandTextTrack*>(webTrack-> client());
2501 if (!textTrack) 2638 if (!textTrack)
2502 return; 2639 return;
2503 2640
2504 removeTrack(textTrack.get()); 2641 removeTextTrack(textTrack.get(), true);
2505 } 2642 }
2506 2643
2507 void HTMLMediaElement::closeCaptionTracksChanged() 2644 void HTMLMediaElement::closeCaptionTracksChanged()
2508 { 2645 {
2509 if (hasMediaControls()) 2646 if (hasMediaControls())
2510 mediaControls()->closedCaptionTracksChanged(); 2647 mediaControls()->closedCaptionTracksChanged();
2511 } 2648 }
2512 2649
2513 void HTMLMediaElement::addTrack(TextTrack* track) 2650 void HTMLMediaElement::addTextTrack(TextTrack* track)
2514 { 2651 {
2515 textTracks()->append(track); 2652 textTracks()->append(track);
2516 2653
2517 closeCaptionTracksChanged(); 2654 closeCaptionTracksChanged();
2518 } 2655 }
2519 2656
2520 void HTMLMediaElement::removeTrack(TextTrack* track) 2657 void HTMLMediaElement::removeTextTrack(TextTrack* track, bool fireRemoveTrackEve nt)
2521 { 2658 {
2522 TrackDisplayUpdateScope scope(this); 2659 TrackDisplayUpdateScope scope(this);
2523 TextTrackCueList* cues = track->cues(); 2660 TextTrackCueList* cues = track->cues();
2524 if (cues) 2661 if (cues)
2525 textTrackRemoveCues(track, cues); 2662 textTrackRemoveCues(track, cues);
2526 m_textTracks->remove(track); 2663 m_textTracks->remove(track, fireRemoveTrackEvent);
2527 2664
2528 closeCaptionTracksChanged(); 2665 closeCaptionTracksChanged();
2529 } 2666 }
2530 2667
2531 void HTMLMediaElement::removeAllInbandTracks() 2668 void HTMLMediaElement::forgetResourceSpecificTracks()
2532 { 2669 {
2533 if (!m_textTracks) 2670 // Implements the "forget the media element's media-resource-specific tracks " algorithm.
2534 return; 2671 // The order is explicitly specified as text, then audio, and finally video. Also
2672 // 'removetrack' events should not be fired.
2673 if (m_textTracks) {
2674 TrackDisplayUpdateScope scope(this);
2675 for (int i = m_textTracks->length() - 1; i >= 0; --i) {
2676 TextTrack* track = m_textTracks->item(i);
2535 2677
2536 TrackDisplayUpdateScope scope(this); 2678 if (track->trackType() == TextTrack::InBand)
2537 for (int i = m_textTracks->length() - 1; i >= 0; --i) { 2679 removeTextTrack(track, false);
2538 TextTrack* track = m_textTracks->item(i); 2680 }
2681 }
2539 2682
2540 if (track->trackType() == TextTrack::InBand) 2683 if (m_audioTracks)
2541 removeTrack(track); 2684 m_audioTracks->removeAll();
2542 } 2685
2686 if (m_videoTracks)
2687 m_videoTracks->removeAll();
2543 } 2688 }
2544 2689
2545 PassRefPtr<TextTrack> HTMLMediaElement::addTextTrack(const AtomicString& kind, c onst AtomicString& label, const AtomicString& language, ExceptionState& exceptio nState) 2690 PassRefPtr<TextTrack> HTMLMediaElement::addTextTrack(const AtomicString& kind, c onst AtomicString& label, const AtomicString& language, ExceptionState& exceptio nState)
2546 { 2691 {
2547 ASSERT(RuntimeEnabledFeatures::videoTrackEnabled()); 2692 ASSERT(RuntimeEnabledFeatures::videoTrackEnabled());
2548 2693
2549 // 4.8.10.12.4 Text track API 2694 // 4.8.10.12.4 Text track API
2550 // The addTextTrack(kind, label, language) method of media elements, when in voked, must run the following steps: 2695 // The addTextTrack(kind, label, language) method of media elements, when in voked, must run the following steps:
2551 2696
2552 // 1. If kind is not one of the following strings, then throw a SyntaxError exception and abort these steps 2697 // 1. If kind is not one of the following strings, then throw a SyntaxError exception and abort these steps
2553 if (!TextTrack::isValidKindKeyword(kind)) { 2698 if (!TextTrack::isValidKindKeyword(kind)) {
2554 exceptionState.throwDOMException(SyntaxError, "The 'kind' provided ('" + kind + "') is invalid."); 2699 exceptionState.throwDOMException(SyntaxError, "The 'kind' provided ('" + kind + "') is invalid.");
2555 return nullptr; 2700 return nullptr;
2556 } 2701 }
2557 2702
2558 // 2. If the label argument was omitted, let label be the empty string. 2703 // 2. If the label argument was omitted, let label be the empty string.
2559 // 3. If the language argument was omitted, let language be the empty string . 2704 // 3. If the language argument was omitted, let language be the empty string .
2560 // 4. Create a new TextTrack object. 2705 // 4. Create a new TextTrack object.
2561 2706
2562 // 5. Create a new text track corresponding to the new object, and set its t ext track kind to kind, its text 2707 // 5. Create a new text track corresponding to the new object, and set its t ext track kind to kind, its text
2563 // track label to label, its text track language to language... 2708 // track label to label, its text track language to language...
2564 RefPtr<TextTrack> textTrack = TextTrack::create(document(), this, kind, labe l, language); 2709 RefPtr<TextTrack> textTrack = TextTrack::create(document(), this, kind, labe l, language);
2565 2710
2566 // Note, due to side effects when changing track parameters, we have to 2711 // Note, due to side effects when changing track parameters, we have to
2567 // first append the track to the text track list. 2712 // first append the track to the text track list.
2568 2713
2569 // 6. Add the new text track to the media element's list of text tracks. 2714 // 6. Add the new text track to the media element's list of text tracks.
2570 addTrack(textTrack.get()); 2715 addTextTrack(textTrack.get());
2571 2716
2572 // ... its text track readiness state to the text track loaded state ... 2717 // ... its text track readiness state to the text track loaded state ...
2573 textTrack->setReadinessState(TextTrack::Loaded); 2718 textTrack->setReadinessState(TextTrack::Loaded);
2574 2719
2575 // ... its text track mode to the text track hidden mode, and its text track list of cues to an empty list ... 2720 // ... its text track mode to the text track hidden mode, and its text track list of cues to an empty list ...
2576 textTrack->setMode(TextTrack::hiddenKeyword()); 2721 textTrack->setMode(TextTrack::hiddenKeyword());
2577 2722
2578 return textTrack.release(); 2723 return textTrack.release();
2579 } 2724 }
2580 2725
(...skipping 15 matching lines...) Expand all
2596 return; 2741 return;
2597 2742
2598 // 4.8.10.12.3 Sourcing out-of-band text tracks 2743 // 4.8.10.12.3 Sourcing out-of-band text tracks
2599 // When a track element's parent element changes and the new parent is a med ia element, 2744 // When a track element's parent element changes and the new parent is a med ia element,
2600 // then the user agent must add the track element's corresponding text track to the 2745 // then the user agent must add the track element's corresponding text track to the
2601 // media element's list of text tracks ... [continues in TextTrackList::appe nd] 2746 // media element's list of text tracks ... [continues in TextTrackList::appe nd]
2602 RefPtr<TextTrack> textTrack = trackElement->track(); 2747 RefPtr<TextTrack> textTrack = trackElement->track();
2603 if (!textTrack) 2748 if (!textTrack)
2604 return; 2749 return;
2605 2750
2606 addTrack(textTrack.get()); 2751 addTextTrack(textTrack.get());
2607 2752
2608 // Do not schedule the track loading until parsing finishes so we don't star t before all tracks 2753 // Do not schedule the track loading until parsing finishes so we don't star t before all tracks
2609 // in the markup have been added. 2754 // in the markup have been added.
2610 if (isFinishedParsingChildren()) 2755 if (isFinishedParsingChildren())
2611 scheduleDelayedAction(LoadTextTrackResource); 2756 scheduleDelayedAction(LoadTextTrackResource);
2612 2757
2613 if (hasMediaControls()) 2758 if (hasMediaControls())
2614 mediaControls()->closedCaptionTracksChanged(); 2759 mediaControls()->closedCaptionTracksChanged();
2615 } 2760 }
2616 2761
(...skipping 17 matching lines...) Expand all
2634 2779
2635 textTrack->setHasBeenConfigured(false); 2780 textTrack->setHasBeenConfigured(false);
2636 2781
2637 if (!m_textTracks) 2782 if (!m_textTracks)
2638 return; 2783 return;
2639 2784
2640 // 4.8.10.12.3 Sourcing out-of-band text tracks 2785 // 4.8.10.12.3 Sourcing out-of-band text tracks
2641 // When a track element's parent element changes and the old parent was a me dia element, 2786 // When a track element's parent element changes and the old parent was a me dia element,
2642 // then the user agent must remove the track element's corresponding text tr ack from the 2787 // then the user agent must remove the track element's corresponding text tr ack from the
2643 // media element's list of text tracks. 2788 // media element's list of text tracks.
2644 removeTrack(textTrack.get()); 2789 removeTextTrack(textTrack.get(), true);
2645 2790
2646 size_t index = m_textTracksWhenResourceSelectionBegan.find(textTrack.get()); 2791 size_t index = m_textTracksWhenResourceSelectionBegan.find(textTrack.get());
2647 if (index != kNotFound) 2792 if (index != kNotFound)
2648 m_textTracksWhenResourceSelectionBegan.remove(index); 2793 m_textTracksWhenResourceSelectionBegan.remove(index);
2649 } 2794 }
2650 2795
2651 static int textTrackLanguageSelectionScore(const TextTrack& track) 2796 static int textTrackLanguageSelectionScore(const TextTrack& track)
2652 { 2797 {
2653 if (track.language().isEmpty()) 2798 if (track.language().isEmpty())
2654 return 0; 2799 return 0;
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after
3387 m_player.clear(); 3532 m_player.clear();
3388 3533
3389 #if ENABLE(WEB_AUDIO) 3534 #if ENABLE(WEB_AUDIO)
3390 if (m_audioSourceNode) 3535 if (m_audioSourceNode)
3391 m_audioSourceNode->unlock(); 3536 m_audioSourceNode->unlock();
3392 #endif 3537 #endif
3393 } 3538 }
3394 3539
3395 void HTMLMediaElement::clearMediaPlayer(int flags) 3540 void HTMLMediaElement::clearMediaPlayer(int flags)
3396 { 3541 {
3397 removeAllInbandTracks(); 3542 forgetResourceSpecificTracks();
3398 3543
3399 closeMediaSource(); 3544 closeMediaSource();
3400 3545
3401 setMediaKeysInternal(0); 3546 setMediaKeysInternal(0);
3402 3547
3403 clearMediaPlayerAndAudioSourceProviderClient(); 3548 clearMediaPlayerAndAudioSourceProviderClient();
3404 3549
3405 stopPeriodicTimers(); 3550 stopPeriodicTimers();
3406 m_loadTimer.stop(); 3551 m_loadTimer.stop();
3407 3552
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
3854 m_fragmentStartTime = MediaPlayer::invalidTime(); 3999 m_fragmentStartTime = MediaPlayer::invalidTime();
3855 4000
3856 double end = fragmentParser.endTime(); 4001 double end = fragmentParser.endTime();
3857 if (end != MediaFragmentURIParser::invalidTimeValue() && end > 0 && end > m_ fragmentStartTime) { 4002 if (end != MediaFragmentURIParser::invalidTimeValue() && end > 0 && end > m_ fragmentStartTime) {
3858 m_fragmentEndTime = end; 4003 m_fragmentEndTime = end;
3859 if (m_fragmentEndTime > dur) 4004 if (m_fragmentEndTime > dur)
3860 m_fragmentEndTime = dur; 4005 m_fragmentEndTime = dur;
3861 } else 4006 } else
3862 m_fragmentEndTime = MediaPlayer::invalidTime(); 4007 m_fragmentEndTime = MediaPlayer::invalidTime();
3863 4008
4009 // FIXME: Add support for selecting tracks by ID with the Media Fragments tr ack dimension.
4010
3864 if (m_fragmentStartTime != MediaPlayer::invalidTime() && m_readyState < HAVE _FUTURE_DATA) 4011 if (m_fragmentStartTime != MediaPlayer::invalidTime() && m_readyState < HAVE _FUTURE_DATA)
3865 prepareToPlay(); 4012 prepareToPlay();
3866 } 4013 }
3867 4014
3868 void HTMLMediaElement::applyMediaFragmentURI() 4015 void HTMLMediaElement::applyMediaFragmentURI()
3869 { 4016 {
3870 if (m_fragmentStartTime != MediaPlayer::invalidTime()) { 4017 if (m_fragmentStartTime != MediaPlayer::invalidTime()) {
3871 m_sentEndEvent = false; 4018 m_sentEndEvent = false;
3872 seek(m_fragmentStartTime, IGNORE_EXCEPTION); 4019 seek(m_fragmentStartTime, IGNORE_EXCEPTION);
3873 } 4020 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
3916 void HTMLMediaElement::mediaPlayerMediaSourceOpened(blink::WebMediaSource* webMe diaSource) 4063 void HTMLMediaElement::mediaPlayerMediaSourceOpened(blink::WebMediaSource* webMe diaSource)
3917 { 4064 {
3918 m_mediaSource->setWebMediaSourceAndOpen(adoptPtr(webMediaSource)); 4065 m_mediaSource->setWebMediaSourceAndOpen(adoptPtr(webMediaSource));
3919 } 4066 }
3920 4067
3921 bool HTMLMediaElement::isInteractiveContent() const 4068 bool HTMLMediaElement::isInteractiveContent() const
3922 { 4069 {
3923 return fastHasAttribute(controlsAttr); 4070 return fastHasAttribute(controlsAttr);
3924 } 4071 }
3925 4072
4073 void HTMLMediaElement::createPlaceholderTracksIfNecessary()
4074 {
4075 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
4076 return;
4077
4078 // Create a placeholder audio track if |m_player| says it has audio but it d idn't explicitly announce the tracks.
4079 if (m_player->hasAudio() && !audioTracks()->length())
4080 mediaPlayerDidAddAudioTrack("audio", AudioTrack::mainKeyword(), "Audio T rack", "", true);
4081
4082 // Create a placeholder video track if |m_player| says it has video but it d idn't explicitly announce the tracks.
4083 if (m_player->hasVideo() && !videoTracks()->length())
4084 mediaPlayerDidAddVideoTrack("video", VideoTrack::mainKeyword(), "Video T rack", "", true);
3926 } 4085 }
4086
4087 void HTMLMediaElement::selectInitialTracksIfNecessary()
4088 {
4089 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
4090 return;
4091
4092 // Enable the first audio track if an audio track hasn't been enabled yet.
4093 if (audioTracks()->length() > 0 && !audioTracks()->hasEnabledTrack())
4094 audioTracks()->anonymousIndexedGetter(0)->setEnabled(true);
4095
4096 // Select the first video track if a video track hasn't been selected yet.
4097 if (videoTracks()->length() > 0 && videoTracks()->selectedIndex() == -1)
4098 videoTracks()->anonymousIndexedGetter(0)->setSelected(true);
4099 }
4100
4101 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698