OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
452 | 452 |
453 removeElementFromDocumentMap(this, &oldDocument); | 453 removeElementFromDocumentMap(this, &oldDocument); |
454 addElementToDocumentMap(this, &document()); | 454 addElementToDocumentMap(this, &document()); |
455 | 455 |
456 // FIXME: This is a temporary fix to prevent this object from causing the | 456 // FIXME: This is a temporary fix to prevent this object from causing the |
457 // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the | 457 // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the |
458 // previous document. This restarts the load, as if the src attribute had be en set. | 458 // previous document. This restarts the load, as if the src attribute had be en set. |
459 // A proper fix would provide a mechanism to allow this object to refresh | 459 // A proper fix would provide a mechanism to allow this object to refresh |
460 // the MediaPlayer's LocalFrame and FrameLoader references on | 460 // the MediaPlayer's LocalFrame and FrameLoader references on |
461 // document changes so that playback can be resumed properly. | 461 // document changes so that playback can be resumed properly. |
462 clearMediaPlayer(LoadMediaResource); | 462 invokeLoadAlgorithm(); |
ddorwin
2016/02/02 20:24:22
I don't know if this is related, but you are no lo
| |
463 scheduleDelayedAction(LoadMediaResource); | |
464 | 463 |
465 // Decrement the load event delay count on oldDocument now that m_webMediaPl ayer has been destroyed | 464 // Decrement the load event delay count on oldDocument now that m_webMediaPl ayer has been destroyed |
466 // and there is no risk of dispatching a load event from within the destruct or. | 465 // and there is no risk of dispatching a load event from within the destruct or. |
467 oldDocument.decrementLoadEventDelayCount(); | 466 oldDocument.decrementLoadEventDelayCount(); |
468 | 467 |
469 ActiveDOMObject::didMoveToNewExecutionContext(&document()); | 468 ActiveDOMObject::didMoveToNewExecutionContext(&document()); |
470 HTMLElement::didMoveToNewDocument(oldDocument); | 469 HTMLElement::didMoveToNewDocument(oldDocument); |
471 } | 470 } |
472 | 471 |
473 bool HTMLMediaElement::supportsFocus() const | 472 bool HTMLMediaElement::supportsFocus() const |
474 { | 473 { |
475 if (ownerDocument()->isMediaDocument()) | 474 if (ownerDocument()->isMediaDocument()) |
476 return false; | 475 return false; |
477 | 476 |
478 // If no controls specified, we should still be able to focus the element if it has tabIndex. | 477 // If no controls specified, we should still be able to focus the element if it has tabIndex. |
479 return shouldShowControls() || HTMLElement::supportsFocus(); | 478 return shouldShowControls() || HTMLElement::supportsFocus(); |
480 } | 479 } |
481 | 480 |
482 bool HTMLMediaElement::isMouseFocusable() const | 481 bool HTMLMediaElement::isMouseFocusable() const |
483 { | 482 { |
484 return false; | 483 return false; |
485 } | 484 } |
486 | 485 |
487 void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& oldValue, const AtomicString& value) | 486 void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& oldValue, const AtomicString& value) |
488 { | 487 { |
489 if (name == srcAttr) { | 488 if (name == srcAttr) { |
490 // Trigger a reload, as long as the 'src' attribute is present. | 489 // Trigger a reload, as long as the 'src' attribute is present. |
491 if (!value.isNull()) { | 490 if (!value.isNull()) { |
492 clearMediaPlayer(LoadMediaResource); | 491 invokeLoadAlgorithm(); |
493 scheduleDelayedAction(LoadMediaResource); | |
494 } | 492 } |
495 } else if (name == controlsAttr) { | 493 } else if (name == controlsAttr) { |
496 configureMediaControls(); | 494 configureMediaControls(); |
497 } else if (name == preloadAttr) { | 495 } else if (name == preloadAttr) { |
498 setPlayerPreload(); | 496 setPlayerPreload(); |
499 } else if (name == disableremoteplaybackAttr) { | 497 } else if (name == disableremoteplaybackAttr) { |
500 UseCounter::count(document(), UseCounter::DisableRemotePlaybackAttribute ); | 498 UseCounter::count(document(), UseCounter::DisableRemotePlaybackAttribute ); |
501 } else { | 499 } else { |
502 HTMLElement::parseAttribute(name, oldValue, value); | 500 HTMLElement::parseAttribute(name, oldValue, value); |
503 } | 501 } |
504 } | 502 } |
505 | 503 |
506 void HTMLMediaElement::finishParsingChildren() | 504 void HTMLMediaElement::finishParsingChildren() |
507 { | 505 { |
508 HTMLElement::finishParsingChildren(); | 506 HTMLElement::finishParsingChildren(); |
509 | 507 |
510 if (Traversal<HTMLTrackElement>::firstChild(*this)) | 508 if (Traversal<HTMLTrackElement>::firstChild(*this)) |
511 scheduleDelayedAction(LoadTextTrackResource); | 509 scheduleTextTrackResourceLoad(); |
512 } | 510 } |
513 | 511 |
514 bool HTMLMediaElement::layoutObjectIsNeeded(const ComputedStyle& style) | 512 bool HTMLMediaElement::layoutObjectIsNeeded(const ComputedStyle& style) |
515 { | 513 { |
516 return shouldShowControls() && HTMLElement::layoutObjectIsNeeded(style); | 514 return shouldShowControls() && HTMLElement::layoutObjectIsNeeded(style); |
517 } | 515 } |
518 | 516 |
519 LayoutObject* HTMLMediaElement::createLayoutObject(const ComputedStyle&) | 517 LayoutObject* HTMLMediaElement::createLayoutObject(const ComputedStyle&) |
520 { | 518 { |
521 return new LayoutMedia(this); | 519 return new LayoutMedia(this); |
522 } | 520 } |
523 | 521 |
524 Node::InsertionNotificationRequest HTMLMediaElement::insertedInto(ContainerNode* insertionPoint) | 522 Node::InsertionNotificationRequest HTMLMediaElement::insertedInto(ContainerNode* insertionPoint) |
525 { | 523 { |
526 WTF_LOG(Media, "HTMLMediaElement::insertedInto(%p, %p)", this, insertionPoin t); | 524 WTF_LOG(Media, "HTMLMediaElement::insertedInto(%p, %p)", this, insertionPoin t); |
527 | 525 |
528 HTMLElement::insertedInto(insertionPoint); | 526 HTMLElement::insertedInto(insertionPoint); |
529 if (insertionPoint->inDocument()) { | 527 if (insertionPoint->inDocument()) { |
530 if (!getAttribute(srcAttr).isEmpty() && m_networkState == NETWORK_EMPTY) | 528 if (!getAttribute(srcAttr).isEmpty() && m_networkState == NETWORK_EMPTY) { |
531 scheduleDelayedAction(LoadMediaResource); | 529 invokeResourceSelectionAlgorithm(); |
jrummell
2016/02/02 21:39:07
Is this correct? previous calls to scheduleDelayed
| |
530 } | |
532 } | 531 } |
533 | 532 |
534 return InsertionShouldCallDidNotifySubtreeInsertions; | 533 return InsertionShouldCallDidNotifySubtreeInsertions; |
535 } | 534 } |
536 | 535 |
537 void HTMLMediaElement::didNotifySubtreeInsertionsToDocument() | 536 void HTMLMediaElement::didNotifySubtreeInsertionsToDocument() |
538 { | 537 { |
539 configureMediaControls(); | 538 configureMediaControls(); |
540 } | 539 } |
541 | 540 |
(...skipping 16 matching lines...) Expand all Loading... | |
558 if (layoutObject()) | 557 if (layoutObject()) |
559 layoutObject()->updateFromElement(); | 558 layoutObject()->updateFromElement(); |
560 } | 559 } |
561 | 560 |
562 void HTMLMediaElement::didRecalcStyle(StyleRecalcChange) | 561 void HTMLMediaElement::didRecalcStyle(StyleRecalcChange) |
563 { | 562 { |
564 if (layoutObject()) | 563 if (layoutObject()) |
565 layoutObject()->updateFromElement(); | 564 layoutObject()->updateFromElement(); |
566 } | 565 } |
567 | 566 |
568 void HTMLMediaElement::scheduleDelayedAction(DelayedActionType actionType) | 567 void HTMLMediaElement::scheduleTextTrackResourceLoad() |
569 { | 568 { |
570 WTF_LOG(Media, "HTMLMediaElement::scheduleDelayedAction(%p)", this); | 569 WTF_LOG(Media, "HTMLMediaElement::scheduleTextTrackResourceLoad(%p)", this); |
571 | 570 |
572 if ((actionType & LoadMediaResource) && !(m_pendingActionFlags & LoadMediaRe source)) { | 571 m_pendingActionFlags |= LoadTextTrackResource; |
573 prepareForLoad(); | |
574 m_pendingActionFlags |= LoadMediaResource; | |
575 } | |
576 | |
577 if (actionType & LoadTextTrackResource) | |
578 m_pendingActionFlags |= LoadTextTrackResource; | |
579 | 572 |
580 if (!m_loadTimer.isActive()) | 573 if (!m_loadTimer.isActive()) |
581 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); | 574 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); |
582 } | 575 } |
583 | 576 |
584 void HTMLMediaElement::scheduleNextSourceChild() | 577 void HTMLMediaElement::scheduleNextSourceChild() |
585 { | 578 { |
586 // Schedule the timer to try the next <source> element WITHOUT resetting sta te ala prepareForLoad. | 579 // Schedule the timer to try the next <source> element WITHOUT resetting sta te ala prepareForLoad. |
587 m_pendingActionFlags |= LoadMediaResource; | 580 m_pendingActionFlags |= LoadMediaResource; |
588 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); | 581 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); |
jrummell
2016/02/02 21:39:07
The previous scheduleDelayedAction() only started
| |
589 } | 582 } |
590 | 583 |
591 void HTMLMediaElement::scheduleEvent(const AtomicString& eventName) | 584 void HTMLMediaElement::scheduleEvent(const AtomicString& eventName) |
592 { | 585 { |
593 scheduleEvent(Event::createCancelable(eventName)); | 586 scheduleEvent(Event::createCancelable(eventName)); |
594 } | 587 } |
595 | 588 |
596 void HTMLMediaElement::scheduleEvent(PassRefPtrWillBeRawPtr<Event> event) | 589 void HTMLMediaElement::scheduleEvent(PassRefPtrWillBeRawPtr<Event> event) |
597 { | 590 { |
598 #if LOG_MEDIA_EVENTS | 591 #if LOG_MEDIA_EVENTS |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
694 // they don't feel like such to the users and hence we don't want to | 687 // they don't feel like such to the users and hence we don't want to |
695 // count them for the purposes of metrics. | 688 // count them for the purposes of metrics. |
696 m_autoplayMediaCounted = true; | 689 m_autoplayMediaCounted = true; |
697 } | 690 } |
698 | 691 |
699 prepareForLoad(); | 692 prepareForLoad(); |
700 loadInternal(); | 693 loadInternal(); |
701 prepareToPlay(); | 694 prepareToPlay(); |
702 } | 695 } |
703 | 696 |
697 void HTMLMediaElement::invokeLoadAlgorithm() | |
698 { | |
699 WTF_LOG(Media, "HTMLMediaElement::invokeLoadAlgorithm(%p)", this); | |
700 | |
701 prepareForLoad(); | |
jrummell
2016/02/02 21:39:08
The previous scheduleDelayedAction() only called p
| |
702 scheduleNextSourceChild(); | |
703 } | |
704 | |
704 void HTMLMediaElement::prepareForLoad() | 705 void HTMLMediaElement::prepareForLoad() |
705 { | 706 { |
706 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this); | 707 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this); |
707 | 708 |
708 // Perform the cleanup required for the resource load algorithm to run. | 709 NetworkState networkState = m_networkState; |
709 stopPeriodicTimers(); | 710 resetMediaElement(LoadMediaResource); |
710 m_loadTimer.stop(); | |
711 cancelDeferredLoad(); | |
712 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec essary and set m_pendingActionFlags to 0 here. | |
713 m_pendingActionFlags &= ~LoadMediaResource; | |
714 m_sentEndEvent = false; | |
715 m_sentStalledEvent = false; | |
716 m_haveFiredLoadedData = false; | |
717 m_completelyLoaded = false; | |
718 m_havePreparedToPlay = false; | |
719 m_displayMode = Unknown; | |
720 | 711 |
721 // 1 - Abort any already-running instance of the resource selection algorith m for this element. | 712 // 1 - Abort any already-running instance of the resource selection algorith m for this element. |
722 m_loadState = WaitingForSource; | 713 m_loadState = WaitingForSource; |
723 m_currentSourceNode = nullptr; | 714 m_currentSourceNode = nullptr; |
724 | 715 |
725 // 2 - If there are any tasks from the media element's media element event t ask source in | 716 // 2 - If there are any tasks from the media element's media element event t ask source in |
726 // one of the task queues, then remove those tasks. | 717 // one of the task queues, then remove those tasks. |
727 cancelPendingEventsAndCallbacks(); | 718 cancelPendingEventsAndCallbacks(); |
728 | 719 |
729 // 3 - If the media element's networkState is set to NETWORK_LOADING or NETW ORK_IDLE, queue | 720 // 3 - If the media element's networkState is set to NETWORK_LOADING or NETW ORK_IDLE, queue |
730 // a task to fire a simple event named abort at the media element. | 721 // a task to fire a simple event named abort at the media element. |
731 if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE) | 722 if (networkState == NETWORK_LOADING || networkState == NETWORK_IDLE) |
732 scheduleEvent(EventTypeNames::abort); | 723 scheduleEvent(EventTypeNames::abort); |
733 | 724 |
734 resetMediaPlayerAndMediaSource(); | |
735 | |
736 // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps | 725 // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps |
737 if (m_networkState != NETWORK_EMPTY) { | 726 if (networkState != NETWORK_EMPTY) { |
738 // 4.1 - Queue a task to fire a simple event named emptied at the media element. | 727 // 4.1 - Queue a task to fire a simple event named emptied at the media element. |
739 scheduleEvent(EventTypeNames::emptied); | 728 scheduleEvent(EventTypeNames::emptied); |
740 | 729 |
741 // 4.2 - If a fetching process is in progress for the media element, the user agent should stop it. | 730 // 4.2 - If a fetching process is in progress for the media element, the user agent should stop it. |
742 setNetworkState(NETWORK_EMPTY); | 731 setNetworkState(NETWORK_EMPTY); |
743 | 732 |
744 // 4.3 - Forget the media element's media-resource-specific tracks. | 733 // 4.3 - Forget the media element's media-resource-specific tracks. |
745 forgetResourceSpecificTracks(); | 734 forgetResourceSpecificTracks(); |
746 | 735 |
747 // 4.4 - If readyState is not set to HAVE_NOTHING, then set it to that s tate. | 736 // 4.4 - If readyState is not set to HAVE_NOTHING, then set it to that s tate. |
(...skipping 22 matching lines...) Expand all Loading... | |
770 } | 759 } |
771 | 760 |
772 // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRat e attribute. | 761 // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRat e attribute. |
773 setPlaybackRate(defaultPlaybackRate()); | 762 setPlaybackRate(defaultPlaybackRate()); |
774 | 763 |
775 // 6 - Set the error attribute to null and the autoplaying flag to true. | 764 // 6 - Set the error attribute to null and the autoplaying flag to true. |
776 m_error = nullptr; | 765 m_error = nullptr; |
777 m_autoplaying = true; | 766 m_autoplaying = true; |
778 | 767 |
779 // 7 - Invoke the media element's resource selection algorithm. | 768 // 7 - Invoke the media element's resource selection algorithm. |
769 invokeResourceSelectionAlgorithm(); | |
780 | 770 |
781 // 8 - Note: Playback of any previously playing media resource for this elem ent stops. | 771 // 8 - Note: Playback of any previously playing media resource for this elem ent stops. |
772 } | |
782 | 773 |
774 void HTMLMediaElement::invokeResourceSelectionAlgorithm() | |
775 { | |
776 WTF_LOG(Media, "HTMLMediaElement::invokeResourceSelectionAlgorithm(%p)", thi s); | |
783 // The resource selection algorithm | 777 // The resource selection algorithm |
784 // 1 - Set the networkState to NETWORK_NO_SOURCE | 778 // 1 - Set the networkState to NETWORK_NO_SOURCE |
785 setNetworkState(NETWORK_NO_SOURCE); | 779 setNetworkState(NETWORK_NO_SOURCE); |
786 | 780 |
787 // 2 - Asynchronously await a stable state. | 781 // 2 - Set the element's show poster flag to true |
782 // TODO(srirama.m): Introduce show poster flag and update it as per spec | |
788 | 783 |
789 m_playedTimeRanges = TimeRanges::create(); | 784 m_playedTimeRanges = TimeRanges::create(); |
790 | 785 |
791 // FIXME: Investigate whether these can be moved into m_networkState != NETW ORK_EMPTY block above | 786 // FIXME: Investigate whether these can be moved into m_networkState != NETW ORK_EMPTY block above |
792 // so they are closer to the relevant spec steps. | 787 // so they are closer to the relevant spec steps. |
793 m_lastSeekTime = 0; | 788 m_lastSeekTime = 0; |
794 m_duration = std::numeric_limits<double>::quiet_NaN(); | 789 m_duration = std::numeric_limits<double>::quiet_NaN(); |
795 | 790 |
796 // The spec doesn't say to block the load event until we actually run the as ynchronous section | 791 // 3 - Set the media element's delaying-the-load-event flag to true (this de lays the load event) |
797 // algorithm, but do it now because we won't start that until after the time r fires and the | |
798 // event may have already fired by then. | |
799 setShouldDelayLoadEvent(true); | 792 setShouldDelayLoadEvent(true); |
800 if (mediaControls()) | 793 if (mediaControls()) |
801 mediaControls()->reset(); | 794 mediaControls()->reset(); |
795 | |
796 // 4 - Await a stable state, allowing the task that invoked this algorithm t o continue | |
797 // TODO(srirama.m): Schedule an async continuation of this algorithm as per the spec | |
802 } | 798 } |
803 | 799 |
804 void HTMLMediaElement::loadInternal() | 800 void HTMLMediaElement::loadInternal() |
805 { | 801 { |
806 // HTMLMediaElement::textTracksAreReady will need "... the text tracks whose mode was not in the | 802 // HTMLMediaElement::textTracksAreReady will need "... the text tracks whose mode was not in the |
807 // disabled state when the element's resource selection algorithm last start ed". | 803 // disabled state when the element's resource selection algorithm last start ed". |
808 m_textTracksWhenResourceSelectionBegan.clear(); | 804 m_textTracksWhenResourceSelectionBegan.clear(); |
809 if (m_textTracks) { | 805 if (m_textTracks) { |
810 for (unsigned i = 0; i < m_textTracks->length(); ++i) { | 806 for (unsigned i = 0; i < m_textTracks->length(); ++i) { |
811 TextTrack* track = m_textTracks->anonymousIndexedGetter(i); | 807 TextTrack* track = m_textTracks->anonymousIndexedGetter(i); |
(...skipping 1146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1958 { | 1954 { |
1959 WTF_LOG(Media, "HTMLMediaElement::playInternal(%p)", this); | 1955 WTF_LOG(Media, "HTMLMediaElement::playInternal(%p)", this); |
1960 | 1956 |
1961 // Always return the buffering strategy to normal when not paused, | 1957 // Always return the buffering strategy to normal when not paused, |
1962 // regardless of the cause. (In contrast with aggressive buffering which is | 1958 // regardless of the cause. (In contrast with aggressive buffering which is |
1963 // only enabled by pause(), not pauseInternal().) | 1959 // only enabled by pause(), not pauseInternal().) |
1964 if (webMediaPlayer()) | 1960 if (webMediaPlayer()) |
1965 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Normal); | 1961 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Normal); |
1966 | 1962 |
1967 // 4.8.10.9. Playing the media resource | 1963 // 4.8.10.9. Playing the media resource |
1968 if (m_networkState == NETWORK_EMPTY) | 1964 if (m_networkState == NETWORK_EMPTY) { |
1969 scheduleDelayedAction(LoadMediaResource); | 1965 invokeResourceSelectionAlgorithm(); |
1966 scheduleNextSourceChild(); | |
1967 } | |
1970 | 1968 |
1971 // Generally "ended" and "looping" are exclusive. Here, the loop attribute | 1969 // Generally "ended" and "looping" are exclusive. Here, the loop attribute |
1972 // is ignored to seek back to start in case loop was set after playback | 1970 // is ignored to seek back to start in case loop was set after playback |
1973 // ended. See http://crbug.com/364442 | 1971 // ended. See http://crbug.com/364442 |
1974 if (endedPlayback(LoopCondition::Ignored)) | 1972 if (endedPlayback(LoopCondition::Ignored)) |
1975 seek(0); | 1973 seek(0); |
1976 | 1974 |
1977 if (m_paused) { | 1975 if (m_paused) { |
1978 m_paused = false; | 1976 m_paused = false; |
1979 invalidateCachedTime(); | 1977 invalidateCachedTime(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2018 if (webMediaPlayer() && UserGestureIndicator::processingUserGesture()) | 2016 if (webMediaPlayer() && UserGestureIndicator::processingUserGesture()) |
2019 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Aggressive); | 2017 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Aggressive); |
2020 | 2018 |
2021 pauseInternal(); | 2019 pauseInternal(); |
2022 } | 2020 } |
2023 | 2021 |
2024 void HTMLMediaElement::pauseInternal() | 2022 void HTMLMediaElement::pauseInternal() |
2025 { | 2023 { |
2026 WTF_LOG(Media, "HTMLMediaElement::pauseInternal(%p)", this); | 2024 WTF_LOG(Media, "HTMLMediaElement::pauseInternal(%p)", this); |
2027 | 2025 |
2028 if (m_networkState == NETWORK_EMPTY) | 2026 if (m_networkState == NETWORK_EMPTY) { |
2029 scheduleDelayedAction(LoadMediaResource); | 2027 invokeResourceSelectionAlgorithm(); |
2028 scheduleNextSourceChild(); | |
2029 } | |
2030 | 2030 |
2031 m_autoplayHelper.pauseMethodCalled(); | 2031 m_autoplayHelper.pauseMethodCalled(); |
2032 | 2032 |
2033 m_autoplaying = false; | 2033 m_autoplaying = false; |
2034 | 2034 |
2035 if (!m_paused) { | 2035 if (!m_paused) { |
2036 recordMetricsIfPausing(); | 2036 recordMetricsIfPausing(); |
2037 | 2037 |
2038 m_paused = true; | 2038 m_paused = true; |
2039 scheduleTimeupdateEvent(false); | 2039 scheduleTimeupdateEvent(false); |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2332 // 5. Populate the new text track's list of cues with the cues parsed so far , folllowing the guidelines for exposing | 2332 // 5. Populate the new text track's list of cues with the cues parsed so far , folllowing the guidelines for exposing |
2333 // cues, and begin updating it dynamically as necessary. | 2333 // cues, and begin updating it dynamically as necessary. |
2334 // - Thess are all done by the media engine. | 2334 // - Thess are all done by the media engine. |
2335 | 2335 |
2336 // 6. Set the new text track's readiness state to loaded. | 2336 // 6. Set the new text track's readiness state to loaded. |
2337 textTrack->setReadinessState(TextTrack::Loaded); | 2337 textTrack->setReadinessState(TextTrack::Loaded); |
2338 | 2338 |
2339 // 7. Set the new text track's mode to the mode consistent with the user's p references and the requirements of | 2339 // 7. Set the new text track's mode to the mode consistent with the user's p references and the requirements of |
2340 // the relevant specification for the data. | 2340 // the relevant specification for the data. |
2341 // - This will happen in honorUserPreferencesForAutomaticTextTrackSelection () | 2341 // - This will happen in honorUserPreferencesForAutomaticTextTrackSelection () |
2342 scheduleDelayedAction(LoadTextTrackResource); | 2342 scheduleTextTrackResourceLoad(); |
2343 | 2343 |
2344 // 8. Add the new text track to the media element's list of text tracks. | 2344 // 8. Add the new text track to the media element's list of text tracks. |
2345 // 9. Fire an event with the name addtrack, that does not bubble and is not cancelable, and that uses the TrackEvent | 2345 // 9. Fire an event with the name addtrack, that does not bubble and is not cancelable, and that uses the TrackEvent |
2346 // interface, with the track attribute initialized to the text track's TextT rack object, at the media element's | 2346 // interface, with the track attribute initialized to the text track's TextT rack object, at the media element's |
2347 // textTracks attribute's TextTrackList object. | 2347 // textTracks attribute's TextTrackList object. |
2348 addTextTrack(textTrack); | 2348 addTextTrack(textTrack); |
2349 } | 2349 } |
2350 | 2350 |
2351 void HTMLMediaElement::removeTextTrack(WebInbandTextTrack* webTrack) | 2351 void HTMLMediaElement::removeTextTrack(WebInbandTextTrack* webTrack) |
2352 { | 2352 { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2452 // media element's list of text tracks ... [continues in TextTrackList::appe nd] | 2452 // media element's list of text tracks ... [continues in TextTrackList::appe nd] |
2453 TextTrack* textTrack = trackElement->track(); | 2453 TextTrack* textTrack = trackElement->track(); |
2454 if (!textTrack) | 2454 if (!textTrack) |
2455 return; | 2455 return; |
2456 | 2456 |
2457 addTextTrack(textTrack); | 2457 addTextTrack(textTrack); |
2458 | 2458 |
2459 // Do not schedule the track loading until parsing finishes so we don't star t before all tracks | 2459 // Do not schedule the track loading until parsing finishes so we don't star t before all tracks |
2460 // in the markup have been added. | 2460 // in the markup have been added. |
2461 if (isFinishedParsingChildren()) | 2461 if (isFinishedParsingChildren()) |
2462 scheduleDelayedAction(LoadTextTrackResource); | 2462 scheduleTextTrackResourceLoad(); |
2463 } | 2463 } |
2464 | 2464 |
2465 void HTMLMediaElement::didRemoveTrackElement(HTMLTrackElement* trackElement) | 2465 void HTMLMediaElement::didRemoveTrackElement(HTMLTrackElement* trackElement) |
2466 { | 2466 { |
2467 #if !LOG_DISABLED | 2467 #if !LOG_DISABLED |
2468 KURL url = trackElement->getNonEmptyURLAttribute(srcAttr); | 2468 KURL url = trackElement->getNonEmptyURLAttribute(srcAttr); |
2469 WTF_LOG(Media, "HTMLMediaElement::didRemoveTrackElement(%p) - 'src' is %s", this, urlForLoggingMedia(url).utf8().data()); | 2469 WTF_LOG(Media, "HTMLMediaElement::didRemoveTrackElement(%p) - 'src' is %s", this, urlForLoggingMedia(url).utf8().data()); |
2470 #endif | 2470 #endif |
2471 | 2471 |
2472 TextTrack* textTrack = trackElement->track(); | 2472 TextTrack* textTrack = trackElement->track(); |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2629 #endif | 2629 #endif |
2630 | 2630 |
2631 // We should only consider a <source> element when there is not src attribut e at all. | 2631 // We should only consider a <source> element when there is not src attribut e at all. |
2632 if (fastHasAttribute(srcAttr)) | 2632 if (fastHasAttribute(srcAttr)) |
2633 return; | 2633 return; |
2634 | 2634 |
2635 // 4.8.8 - If a source element is inserted as a child of a media element tha t has no src | 2635 // 4.8.8 - If a source element is inserted as a child of a media element tha t has no src |
2636 // attribute and whose networkState has the value NETWORK_EMPTY, the user ag ent must invoke | 2636 // attribute and whose networkState has the value NETWORK_EMPTY, the user ag ent must invoke |
2637 // the media element's resource selection algorithm. | 2637 // the media element's resource selection algorithm. |
2638 if (networkState() == HTMLMediaElement::NETWORK_EMPTY) { | 2638 if (networkState() == HTMLMediaElement::NETWORK_EMPTY) { |
2639 scheduleDelayedAction(LoadMediaResource); | 2639 invokeResourceSelectionAlgorithm(); |
2640 scheduleNextSourceChild(); | |
2640 m_nextChildNodeToConsider = source; | 2641 m_nextChildNodeToConsider = source; |
2641 return; | 2642 return; |
2642 } | 2643 } |
2643 | 2644 |
2644 if (m_currentSourceNode && source == m_currentSourceNode->nextSibling()) { | 2645 if (m_currentSourceNode && source == m_currentSourceNode->nextSibling()) { |
2645 WTF_LOG(Media, "HTMLMediaElement::sourceWasAdded(%p) - <source> inserted immediately after current source", this); | 2646 WTF_LOG(Media, "HTMLMediaElement::sourceWasAdded(%p) - <source> inserted immediately after current source", this); |
2646 m_nextChildNodeToConsider = source; | 2647 m_nextChildNodeToConsider = source; |
2647 return; | 2648 return; |
2648 } | 2649 } |
2649 | 2650 |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2979 | 2980 |
2980 void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClientWithoutLockin g() | 2981 void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClientWithoutLockin g() |
2981 { | 2982 { |
2982 audioSourceProvider().setClient(nullptr); | 2983 audioSourceProvider().setClient(nullptr); |
2983 if (m_webMediaPlayer) { | 2984 if (m_webMediaPlayer) { |
2984 m_audioSourceProvider.wrap(nullptr); | 2985 m_audioSourceProvider.wrap(nullptr); |
2985 m_webMediaPlayer.clear(); | 2986 m_webMediaPlayer.clear(); |
2986 } | 2987 } |
2987 } | 2988 } |
2988 | 2989 |
2989 void HTMLMediaElement::clearMediaPlayer(int flags) | 2990 void HTMLMediaElement::resetMediaElement(int flags) |
2990 { | 2991 { |
2991 forgetResourceSpecificTracks(); | 2992 forgetResourceSpecificTracks(); |
2992 | 2993 |
2993 closeMediaSource(); | 2994 closeMediaSource(); |
2994 | 2995 |
2995 cancelDeferredLoad(); | 2996 cancelDeferredLoad(); |
2996 | 2997 |
2997 { | 2998 { |
2998 AudioSourceProviderClientLockScope scope(*this); | 2999 AudioSourceProviderClientLockScope scope(*this); |
2999 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); | 3000 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); |
3000 } | 3001 } |
3001 | 3002 |
3003 #if ENABLE(WEB_AUDIO) | |
3004 if (m_audioSourceNode) | |
3005 audioSourceProvider().setClient(m_audioSourceNode); | |
3006 #endif | |
3007 | |
3002 stopPeriodicTimers(); | 3008 stopPeriodicTimers(); |
3003 m_loadTimer.stop(); | 3009 m_loadTimer.stop(); |
3004 | 3010 |
3005 m_pendingActionFlags &= ~flags; | 3011 m_pendingActionFlags &= ~flags; |
3006 m_loadState = WaitingForSource; | 3012 m_loadState = WaitingForSource; |
3007 | 3013 |
3008 // We can't cast if we don't have a media player. | 3014 // We can't cast if we don't have a media player. |
3009 m_remoteRoutesAvailable = false; | 3015 m_remoteRoutesAvailable = false; |
3010 m_playingRemotely = false; | 3016 m_playingRemotely = false; |
3017 | |
3018 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec essary and set m_pendingActionFlags to 0 here. | |
3019 m_sentEndEvent = false; | |
3020 m_sentStalledEvent = false; | |
3021 m_haveFiredLoadedData = false; | |
3022 m_completelyLoaded = false; | |
3023 m_havePreparedToPlay = false; | |
3024 m_displayMode = Unknown; | |
3025 | |
3026 m_readyState = HAVE_NOTHING; | |
3027 m_readyStateMaximum = HAVE_NOTHING; | |
3028 setNetworkState(NETWORK_EMPTY); | |
3029 setShouldDelayLoadEvent(false); | |
3030 m_currentSourceNode = nullptr; | |
3031 invalidateCachedTime(); | |
3032 cueTimeline().updateActiveCues(0); | |
3033 m_playing = false; | |
3034 m_paused = true; | |
3035 m_seeking = false; | |
3036 | |
3011 if (mediaControls()) | 3037 if (mediaControls()) |
3012 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); | 3038 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); |
3013 | 3039 |
3014 if (layoutObject()) | 3040 if (layoutObject()) |
3015 layoutObject()->setShouldDoFullPaintInvalidation(); | 3041 layoutObject()->setShouldDoFullPaintInvalidation(); |
3016 } | 3042 } |
3017 | 3043 |
3018 void HTMLMediaElement::stop() | 3044 void HTMLMediaElement::stop() |
3019 { | 3045 { |
3020 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); | 3046 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); |
3021 | 3047 |
3022 recordMetricsIfPausing(); | 3048 recordMetricsIfPausing(); |
3023 | 3049 |
3024 // Close the async event queue so that no events are enqueued. | 3050 // Close the async event queue so that no events are enqueued. |
3025 cancelPendingEventsAndCallbacks(); | 3051 cancelPendingEventsAndCallbacks(); |
3026 m_asyncEventQueue->close(); | 3052 m_asyncEventQueue->close(); |
3027 | 3053 |
3028 // Stop the playback without generating events | 3054 // Clear everything in the Media Element |
3029 clearMediaPlayer(-1); | 3055 resetMediaElement(-1); |
3030 m_readyState = HAVE_NOTHING; | |
3031 m_readyStateMaximum = HAVE_NOTHING; | |
3032 setNetworkState(NETWORK_EMPTY); | |
3033 setShouldDelayLoadEvent(false); | |
3034 m_currentSourceNode = nullptr; | |
3035 invalidateCachedTime(); | |
3036 cueTimeline().updateActiveCues(0); | |
3037 m_playing = false; | |
3038 m_paused = true; | |
3039 m_seeking = false; | |
3040 | 3056 |
3041 if (layoutObject()) | 3057 if (layoutObject()) |
3042 layoutObject()->updateFromElement(); | 3058 layoutObject()->updateFromElement(); |
3043 | 3059 |
3044 stopPeriodicTimers(); | |
3045 | |
3046 // Ensure that hasPendingActivity() is not preventing garbage collection, si nce otherwise this | 3060 // Ensure that hasPendingActivity() is not preventing garbage collection, si nce otherwise this |
3047 // media element will simply leak. | 3061 // media element will simply leak. |
3048 ASSERT(!hasPendingActivity()); | 3062 ASSERT(!hasPendingActivity()); |
3049 } | 3063 } |
3050 | 3064 |
3051 bool HTMLMediaElement::hasPendingActivity() const | 3065 bool HTMLMediaElement::hasPendingActivity() const |
3052 { | 3066 { |
3053 // The delaying-the-load-event flag is set by resource selection algorithm w hen looking for a | 3067 // The delaying-the-load-event flag is set by resource selection algorithm w hen looking for a |
3054 // resource to load, before networkState has reached to NETWORK_LOADING. | 3068 // resource to load, before networkState has reached to NETWORK_LOADING. |
3055 if (m_shouldDelayLoadEvent) | 3069 if (m_shouldDelayLoadEvent) |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3384 } | 3398 } |
3385 | 3399 |
3386 void* HTMLMediaElement::preDispatchEventHandler(Event* event) | 3400 void* HTMLMediaElement::preDispatchEventHandler(Event* event) |
3387 { | 3401 { |
3388 if (event && event->type() == EventTypeNames::webkitfullscreenchange) | 3402 if (event && event->type() == EventTypeNames::webkitfullscreenchange) |
3389 configureMediaControls(); | 3403 configureMediaControls(); |
3390 | 3404 |
3391 return nullptr; | 3405 return nullptr; |
3392 } | 3406 } |
3393 | 3407 |
3394 // TODO(srirama.m): Refactor this and clearMediaPlayer to the extent possible. | 3408 // TODO(srirama.m): Merge it to resetMediaElement if possible and remove it. |
3395 void HTMLMediaElement::resetMediaPlayerAndMediaSource() | 3409 void HTMLMediaElement::resetMediaPlayerAndMediaSource() |
3396 { | 3410 { |
3397 closeMediaSource(); | 3411 closeMediaSource(); |
3398 | 3412 |
3399 { | 3413 { |
3400 AudioSourceProviderClientLockScope scope(*this); | 3414 AudioSourceProviderClientLockScope scope(*this); |
3401 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); | 3415 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); |
3402 } | 3416 } |
3403 | 3417 |
3404 // We haven't yet found out if any remote routes are available. | 3418 // We haven't yet found out if any remote routes are available. |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3624 { | 3638 { |
3625 visitor->trace(m_client); | 3639 visitor->trace(m_client); |
3626 } | 3640 } |
3627 | 3641 |
3628 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) | 3642 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) |
3629 { | 3643 { |
3630 visitor->trace(m_client); | 3644 visitor->trace(m_client); |
3631 } | 3645 } |
3632 | 3646 |
3633 } // namespace blink | 3647 } // namespace blink |
OLD | NEW |