Chromium Code Reviews| 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 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 464 | 464 |
| 465 removeElementFromDocumentMap(this, &oldDocument); | 465 removeElementFromDocumentMap(this, &oldDocument); |
| 466 addElementToDocumentMap(this, &document()); | 466 addElementToDocumentMap(this, &document()); |
| 467 | 467 |
| 468 // FIXME: This is a temporary fix to prevent this object from causing the | 468 // FIXME: This is a temporary fix to prevent this object from causing the |
| 469 // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the | 469 // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the |
| 470 // previous document. This restarts the load, as if the src attribute had be en set. | 470 // previous document. This restarts the load, as if the src attribute had be en set. |
| 471 // A proper fix would provide a mechanism to allow this object to refresh | 471 // A proper fix would provide a mechanism to allow this object to refresh |
| 472 // the MediaPlayer's LocalFrame and FrameLoader references on | 472 // the MediaPlayer's LocalFrame and FrameLoader references on |
| 473 // document changes so that playback can be resumed properly. | 473 // document changes so that playback can be resumed properly. |
| 474 clearMediaPlayer(LoadMediaResource); | 474 prepareForLoad(); |
| 475 scheduleDelayedAction(LoadMediaResource); | 475 scheduleNextSourceChild(); |
| 476 | 476 |
| 477 // Decrement the load event delay count on oldDocument now that m_webMediaPl ayer has been destroyed | 477 // Decrement the load event delay count on oldDocument now that m_webMediaPl ayer has been destroyed |
| 478 // and there is no risk of dispatching a load event from within the destruct or. | 478 // and there is no risk of dispatching a load event from within the destruct or. |
| 479 oldDocument.decrementLoadEventDelayCount(); | 479 oldDocument.decrementLoadEventDelayCount(); |
| 480 | 480 |
| 481 ActiveDOMObject::didMoveToNewExecutionContext(&document()); | 481 ActiveDOMObject::didMoveToNewExecutionContext(&document()); |
| 482 HTMLElement::didMoveToNewDocument(oldDocument); | 482 HTMLElement::didMoveToNewDocument(oldDocument); |
| 483 } | 483 } |
| 484 | 484 |
| 485 bool HTMLMediaElement::supportsFocus() const | 485 bool HTMLMediaElement::supportsFocus() const |
| 486 { | 486 { |
| 487 if (ownerDocument()->isMediaDocument()) | 487 if (ownerDocument()->isMediaDocument()) |
| 488 return false; | 488 return false; |
| 489 | 489 |
| 490 // If no controls specified, we should still be able to focus the element if it has tabIndex. | 490 // If no controls specified, we should still be able to focus the element if it has tabIndex. |
| 491 return shouldShowControls() || HTMLElement::supportsFocus(); | 491 return shouldShowControls() || HTMLElement::supportsFocus(); |
| 492 } | 492 } |
| 493 | 493 |
| 494 bool HTMLMediaElement::isMouseFocusable() const | 494 bool HTMLMediaElement::isMouseFocusable() const |
| 495 { | 495 { |
| 496 return false; | 496 return false; |
| 497 } | 497 } |
| 498 | 498 |
| 499 void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& oldValue, const AtomicString& value) | 499 void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& oldValue, const AtomicString& value) |
| 500 { | 500 { |
| 501 if (name == srcAttr) { | 501 if (name == srcAttr) { |
| 502 // Trigger a reload, as long as the 'src' attribute is present. | 502 // Trigger a reload, as long as the 'src' attribute is present. |
| 503 if (!value.isNull()) { | 503 if (!value.isNull()) { |
| 504 clearMediaPlayer(LoadMediaResource); | 504 prepareForLoad(); |
|
philipj_slow
2016/01/21 12:48:11
The spec says "If a src attribute of a media eleme
Srirama
2016/01/28 11:31:03
Done.
| |
| 505 scheduleDelayedAction(LoadMediaResource); | 505 scheduleNextSourceChild(); |
| 506 } | 506 } |
| 507 } else if (name == controlsAttr) { | 507 } else if (name == controlsAttr) { |
| 508 configureMediaControls(); | 508 configureMediaControls(); |
| 509 } else if (name == preloadAttr) { | 509 } else if (name == preloadAttr) { |
| 510 setPlayerPreload(); | 510 setPlayerPreload(); |
| 511 } else if (name == disableremoteplaybackAttr) { | 511 } else if (name == disableremoteplaybackAttr) { |
| 512 UseCounter::count(document(), UseCounter::DisableRemotePlaybackAttribute ); | 512 UseCounter::count(document(), UseCounter::DisableRemotePlaybackAttribute ); |
| 513 } else { | 513 } else { |
| 514 HTMLElement::parseAttribute(name, oldValue, value); | 514 HTMLElement::parseAttribute(name, oldValue, value); |
| 515 } | 515 } |
| 516 } | 516 } |
| 517 | 517 |
| 518 void HTMLMediaElement::finishParsingChildren() | 518 void HTMLMediaElement::finishParsingChildren() |
| 519 { | 519 { |
| 520 HTMLElement::finishParsingChildren(); | 520 HTMLElement::finishParsingChildren(); |
| 521 | 521 |
| 522 if (Traversal<HTMLTrackElement>::firstChild(*this)) | 522 if (Traversal<HTMLTrackElement>::firstChild(*this)) |
| 523 scheduleDelayedAction(LoadTextTrackResource); | 523 scheduleTextTrackResourceLoad(); |
| 524 } | 524 } |
| 525 | 525 |
| 526 bool HTMLMediaElement::layoutObjectIsNeeded(const ComputedStyle& style) | 526 bool HTMLMediaElement::layoutObjectIsNeeded(const ComputedStyle& style) |
| 527 { | 527 { |
| 528 return shouldShowControls() && HTMLElement::layoutObjectIsNeeded(style); | 528 return shouldShowControls() && HTMLElement::layoutObjectIsNeeded(style); |
| 529 } | 529 } |
| 530 | 530 |
| 531 LayoutObject* HTMLMediaElement::createLayoutObject(const ComputedStyle&) | 531 LayoutObject* HTMLMediaElement::createLayoutObject(const ComputedStyle&) |
| 532 { | 532 { |
| 533 return new LayoutMedia(this); | 533 return new LayoutMedia(this); |
| 534 } | 534 } |
| 535 | 535 |
| 536 Node::InsertionNotificationRequest HTMLMediaElement::insertedInto(ContainerNode* insertionPoint) | 536 Node::InsertionNotificationRequest HTMLMediaElement::insertedInto(ContainerNode* insertionPoint) |
| 537 { | 537 { |
| 538 WTF_LOG(Media, "HTMLMediaElement::insertedInto(%p, %p)", this, insertionPoin t); | 538 WTF_LOG(Media, "HTMLMediaElement::insertedInto(%p, %p)", this, insertionPoin t); |
| 539 | 539 |
| 540 HTMLElement::insertedInto(insertionPoint); | 540 HTMLElement::insertedInto(insertionPoint); |
| 541 if (insertionPoint->inDocument()) { | 541 if (insertionPoint->inDocument()) { |
| 542 if (!getAttribute(srcAttr).isEmpty() && m_networkState == NETWORK_EMPTY) | 542 if (!getAttribute(srcAttr).isEmpty() && m_networkState == NETWORK_EMPTY) { |
| 543 scheduleDelayedAction(LoadMediaResource); | 543 if (!(m_pendingActionFlags & LoadMediaResource)) |
|
philipj_slow
2016/01/21 12:48:11
I'm not sure I understand these changes. The exist
Srirama
2016/01/28 11:31:03
Removed unneeded conditions. But i couldn't exactl
| |
| 544 prepareForLoad(); | |
| 545 | |
| 546 scheduleNextSourceChild(); | |
| 547 } | |
| 544 } | 548 } |
| 545 | 549 |
| 546 return InsertionShouldCallDidNotifySubtreeInsertions; | 550 return InsertionShouldCallDidNotifySubtreeInsertions; |
| 547 } | 551 } |
| 548 | 552 |
| 549 void HTMLMediaElement::didNotifySubtreeInsertionsToDocument() | 553 void HTMLMediaElement::didNotifySubtreeInsertionsToDocument() |
| 550 { | 554 { |
| 551 configureMediaControls(); | 555 configureMediaControls(); |
| 552 } | 556 } |
| 553 | 557 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 570 if (layoutObject()) | 574 if (layoutObject()) |
| 571 layoutObject()->updateFromElement(); | 575 layoutObject()->updateFromElement(); |
| 572 } | 576 } |
| 573 | 577 |
| 574 void HTMLMediaElement::didRecalcStyle(StyleRecalcChange) | 578 void HTMLMediaElement::didRecalcStyle(StyleRecalcChange) |
| 575 { | 579 { |
| 576 if (layoutObject()) | 580 if (layoutObject()) |
| 577 layoutObject()->updateFromElement(); | 581 layoutObject()->updateFromElement(); |
| 578 } | 582 } |
| 579 | 583 |
| 580 void HTMLMediaElement::scheduleDelayedAction(DelayedActionType actionType) | 584 void HTMLMediaElement::scheduleTextTrackResourceLoad() |
| 581 { | 585 { |
| 582 WTF_LOG(Media, "HTMLMediaElement::scheduleDelayedAction(%p)", this); | 586 WTF_LOG(Media, "HTMLMediaElement::scheduleTextTrackResourceLoad(%p)", this); |
| 583 | 587 |
| 584 if ((actionType & LoadMediaResource) && !(m_pendingActionFlags & LoadMediaRe source)) { | 588 m_pendingActionFlags |= LoadTextTrackResource; |
| 585 prepareForLoad(); | |
| 586 m_pendingActionFlags |= LoadMediaResource; | |
| 587 } | |
| 588 | |
| 589 if (actionType & LoadTextTrackResource) | |
| 590 m_pendingActionFlags |= LoadTextTrackResource; | |
| 591 | 589 |
| 592 if (!m_loadTimer.isActive()) | 590 if (!m_loadTimer.isActive()) |
| 593 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); | 591 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); |
| 594 } | 592 } |
| 595 | 593 |
| 596 void HTMLMediaElement::scheduleNextSourceChild() | 594 void HTMLMediaElement::scheduleNextSourceChild() |
| 597 { | 595 { |
| 598 // Schedule the timer to try the next <source> element WITHOUT resetting sta te ala prepareForLoad. | 596 // Schedule the timer to try the next <source> element WITHOUT resetting sta te ala prepareForLoad. |
| 599 m_pendingActionFlags |= LoadMediaResource; | 597 m_pendingActionFlags |= LoadMediaResource; |
| 600 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); | 598 if (!m_loadTimer.isActive()) |
|
philipj_slow
2016/01/21 12:48:11
Why was this change needed?
Srirama
2016/01/28 11:31:03
Removed, not needed, i have added it to fix layout
| |
| 599 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); | |
| 601 } | 600 } |
| 602 | 601 |
| 603 void HTMLMediaElement::scheduleEvent(const AtomicString& eventName) | 602 void HTMLMediaElement::scheduleEvent(const AtomicString& eventName) |
| 604 { | 603 { |
| 605 scheduleEvent(Event::createCancelable(eventName)); | 604 scheduleEvent(Event::createCancelable(eventName)); |
| 606 } | 605 } |
| 607 | 606 |
| 608 void HTMLMediaElement::scheduleEvent(PassRefPtrWillBeRawPtr<Event> event) | 607 void HTMLMediaElement::scheduleEvent(PassRefPtrWillBeRawPtr<Event> event) |
| 609 { | 608 { |
| 610 #if LOG_MEDIA_EVENTS | 609 #if LOG_MEDIA_EVENTS |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 710 | 709 |
| 711 prepareForLoad(); | 710 prepareForLoad(); |
| 712 loadInternal(); | 711 loadInternal(); |
| 713 prepareToPlay(); | 712 prepareToPlay(); |
| 714 } | 713 } |
| 715 | 714 |
| 716 void HTMLMediaElement::prepareForLoad() | 715 void HTMLMediaElement::prepareForLoad() |
| 717 { | 716 { |
| 718 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this); | 717 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this); |
| 719 | 718 |
| 720 // Perform the cleanup required for the resource load algorithm to run. | 719 NetworkState networkState = m_networkState; |
| 721 stopPeriodicTimers(); | 720 resetMediaElement(LoadMediaResource); |
|
philipj_slow
2016/01/21 12:48:10
This will now be the only place where resetMediaEl
Srirama
2016/01/28 11:31:03
passing -1 is resetting all the flags and because
| |
| 722 m_loadTimer.stop(); | |
| 723 cancelDeferredLoad(); | |
| 724 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec essary and set m_pendingActionFlags to 0 here. | |
| 725 m_pendingActionFlags &= ~LoadMediaResource; | |
| 726 m_sentEndEvent = false; | |
| 727 m_sentStalledEvent = false; | |
| 728 m_haveFiredLoadedData = false; | |
| 729 m_completelyLoaded = false; | |
| 730 m_havePreparedToPlay = false; | |
| 731 m_displayMode = Unknown; | |
| 732 | 721 |
| 733 // 1 - Abort any already-running instance of the resource selection algorith m for this element. | 722 // 1 - Abort any already-running instance of the resource selection algorith m for this element. |
| 734 m_loadState = WaitingForSource; | 723 m_loadState = WaitingForSource; |
| 735 m_currentSourceNode = nullptr; | 724 m_currentSourceNode = nullptr; |
| 736 | 725 |
| 737 // 2 - If there are any tasks from the media element's media element event t ask source in | 726 // 2 - If there are any tasks from the media element's media element event t ask source in |
| 738 // one of the task queues, then remove those tasks. | 727 // one of the task queues, then remove those tasks. |
| 739 cancelPendingEventsAndCallbacks(); | 728 cancelPendingEventsAndCallbacks(); |
| 740 | 729 |
| 741 // 3 - If the media element's networkState is set to NETWORK_LOADING or NETW ORK_IDLE, queue | 730 // 3 - If the media element's networkState is set to NETWORK_LOADING or NETW ORK_IDLE, queue |
| 742 // a task to fire a simple event named abort at the media element. | 731 // a task to fire a simple event named abort at the media element. |
| 743 if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE) | 732 if (networkState == NETWORK_LOADING || networkState == NETWORK_IDLE) |
| 744 scheduleEvent(EventTypeNames::abort); | 733 scheduleEvent(EventTypeNames::abort); |
| 745 | 734 |
| 746 resetMediaPlayerAndMediaSource(); | |
| 747 | |
| 748 // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps | 735 // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps |
| 749 if (m_networkState != NETWORK_EMPTY) { | 736 if (networkState != NETWORK_EMPTY) { |
| 750 // 4.1 - Queue a task to fire a simple event named emptied at the media element. | 737 // 4.1 - Queue a task to fire a simple event named emptied at the media element. |
| 751 scheduleEvent(EventTypeNames::emptied); | 738 scheduleEvent(EventTypeNames::emptied); |
| 752 | 739 |
| 753 // 4.2 - If a fetching process is in progress for the media element, the user agent should stop it. | 740 // 4.2 - If a fetching process is in progress for the media element, the user agent should stop it. |
| 754 setNetworkState(NETWORK_EMPTY); | 741 setNetworkState(NETWORK_EMPTY); |
| 755 | 742 |
| 756 // 4.3 - Forget the media element's media-resource-specific tracks. | 743 // 4.3 - Forget the media element's media-resource-specific tracks. |
| 757 forgetResourceSpecificTracks(); | 744 forgetResourceSpecificTracks(); |
| 758 | 745 |
| 759 // 4.4 - If readyState is not set to HAVE_NOTHING, then set it to that s tate. | 746 // 4.4 - If readyState is not set to HAVE_NOTHING, then set it to that s tate. |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 782 } | 769 } |
| 783 | 770 |
| 784 // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRat e attribute. | 771 // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRat e attribute. |
| 785 setPlaybackRate(defaultPlaybackRate()); | 772 setPlaybackRate(defaultPlaybackRate()); |
| 786 | 773 |
| 787 // 6 - Set the error attribute to null and the autoplaying flag to true. | 774 // 6 - Set the error attribute to null and the autoplaying flag to true. |
| 788 m_error = nullptr; | 775 m_error = nullptr; |
| 789 m_autoplaying = true; | 776 m_autoplaying = true; |
| 790 | 777 |
| 791 // 7 - Invoke the media element's resource selection algorithm. | 778 // 7 - Invoke the media element's resource selection algorithm. |
| 779 invokeResourceSelectionAlgorithm(); | |
| 792 | 780 |
| 793 // 8 - Note: Playback of any previously playing media resource for this elem ent stops. | 781 // 8 - Note: Playback of any previously playing media resource for this elem ent stops. |
| 782 } | |
| 794 | 783 |
| 784 void HTMLMediaElement::invokeResourceSelectionAlgorithm() | |
| 785 { | |
| 786 WTF_LOG(Media, "HTMLMediaElement::invokeResourceSelectionAlgorithm(%p)", thi s); | |
| 795 // The resource selection algorithm | 787 // The resource selection algorithm |
| 796 // 1 - Set the networkState to NETWORK_NO_SOURCE | 788 // 1 - Set the networkState to NETWORK_NO_SOURCE |
| 797 setNetworkState(NETWORK_NO_SOURCE); | 789 setNetworkState(NETWORK_NO_SOURCE); |
| 798 | 790 |
| 799 // 2 - Asynchronously await a stable state. | |
|
philipj_slow
2016/01/21 12:48:11
Why was this comment removed? The spec presumably
Srirama
2016/01/28 11:31:03
Done.
| |
| 800 | |
| 801 m_playedTimeRanges = TimeRanges::create(); | 791 m_playedTimeRanges = TimeRanges::create(); |
| 802 | 792 |
| 803 // FIXME: Investigate whether these can be moved into m_networkState != NETW ORK_EMPTY block above | 793 // FIXME: Investigate whether these can be moved into m_networkState != NETW ORK_EMPTY block above |
| 804 // so they are closer to the relevant spec steps. | 794 // so they are closer to the relevant spec steps. |
| 805 m_lastSeekTime = 0; | 795 m_lastSeekTime = 0; |
| 806 m_duration = std::numeric_limits<double>::quiet_NaN(); | 796 m_duration = std::numeric_limits<double>::quiet_NaN(); |
| 807 | 797 |
| 808 // The spec doesn't say to block the load event until we actually run the as ynchronous section | 798 // The spec doesn't say to block the load event until we actually run the as ynchronous section |
| 809 // algorithm, but do it now because we won't start that until after the time r fires and the | 799 // algorithm, but do it now because we won't start that until after the time r fires and the |
| 810 // event may have already fired by then. | 800 // event may have already fired by then. |
| (...skipping 1163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1974 { | 1964 { |
| 1975 WTF_LOG(Media, "HTMLMediaElement::playInternal(%p)", this); | 1965 WTF_LOG(Media, "HTMLMediaElement::playInternal(%p)", this); |
| 1976 | 1966 |
| 1977 // Always return the buffering strategy to normal when not paused, | 1967 // Always return the buffering strategy to normal when not paused, |
| 1978 // regardless of the cause. (In contrast with aggressive buffering which is | 1968 // regardless of the cause. (In contrast with aggressive buffering which is |
| 1979 // only enabled by pause(), not pauseInternal().) | 1969 // only enabled by pause(), not pauseInternal().) |
| 1980 if (webMediaPlayer()) | 1970 if (webMediaPlayer()) |
| 1981 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Normal); | 1971 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Normal); |
| 1982 | 1972 |
| 1983 // 4.8.10.9. Playing the media resource | 1973 // 4.8.10.9. Playing the media resource |
| 1984 if (m_networkState == NETWORK_EMPTY) | 1974 if (m_networkState == NETWORK_EMPTY) { |
|
philipj_slow
2016/01/21 12:48:11
Can this simply be invokeResourceSelectionAlgorith
Srirama
2016/01/28 11:31:03
Done. Do you want me to remove scheduleNextSourceC
| |
| 1985 scheduleDelayedAction(LoadMediaResource); | 1975 if (!(m_pendingActionFlags & LoadMediaResource)) |
| 1976 invokeResourceSelectionAlgorithm(); | |
| 1977 | |
| 1978 scheduleNextSourceChild(); | |
| 1979 } | |
| 1986 | 1980 |
| 1987 // Generally "ended" and "looping" are exclusive. Here, the loop attribute | 1981 // Generally "ended" and "looping" are exclusive. Here, the loop attribute |
| 1988 // is ignored to seek back to start in case loop was set after playback | 1982 // is ignored to seek back to start in case loop was set after playback |
| 1989 // ended. See http://crbug.com/364442 | 1983 // ended. See http://crbug.com/364442 |
| 1990 if (endedPlayback(LoopCondition::Ignored)) | 1984 if (endedPlayback(LoopCondition::Ignored)) |
| 1991 seek(0); | 1985 seek(0); |
| 1992 | 1986 |
| 1993 if (m_paused) { | 1987 if (m_paused) { |
| 1994 m_paused = false; | 1988 m_paused = false; |
| 1995 invalidateCachedTime(); | 1989 invalidateCachedTime(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2034 if (webMediaPlayer() && UserGestureIndicator::processingUserGesture()) | 2028 if (webMediaPlayer() && UserGestureIndicator::processingUserGesture()) |
| 2035 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Aggressive); | 2029 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Aggressive); |
| 2036 | 2030 |
| 2037 pauseInternal(); | 2031 pauseInternal(); |
| 2038 } | 2032 } |
| 2039 | 2033 |
| 2040 void HTMLMediaElement::pauseInternal() | 2034 void HTMLMediaElement::pauseInternal() |
| 2041 { | 2035 { |
| 2042 WTF_LOG(Media, "HTMLMediaElement::pauseInternal(%p)", this); | 2036 WTF_LOG(Media, "HTMLMediaElement::pauseInternal(%p)", this); |
| 2043 | 2037 |
| 2044 if (m_networkState == NETWORK_EMPTY) | 2038 if (m_networkState == NETWORK_EMPTY) { |
| 2045 scheduleDelayedAction(LoadMediaResource); | 2039 if (!(m_pendingActionFlags & LoadMediaResource)) |
|
philipj_slow
2016/01/21 12:48:11
Same as for playInternal().
Srirama
2016/01/28 11:31:03
Done.
| |
| 2040 invokeResourceSelectionAlgorithm(); | |
| 2041 | |
| 2042 scheduleNextSourceChild(); | |
| 2043 } | |
| 2046 | 2044 |
| 2047 m_autoplayHelper.pauseMethodCalled(); | 2045 m_autoplayHelper.pauseMethodCalled(); |
| 2048 | 2046 |
| 2049 m_autoplaying = false; | 2047 m_autoplaying = false; |
| 2050 | 2048 |
| 2051 if (!m_paused) { | 2049 if (!m_paused) { |
| 2052 recordMetricsIfPausing(); | 2050 recordMetricsIfPausing(); |
| 2053 | 2051 |
| 2054 m_paused = true; | 2052 m_paused = true; |
| 2055 scheduleTimeupdateEvent(false); | 2053 scheduleTimeupdateEvent(false); |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2348 // 5. Populate the new text track's list of cues with the cues parsed so far , folllowing the guidelines for exposing | 2346 // 5. Populate the new text track's list of cues with the cues parsed so far , folllowing the guidelines for exposing |
| 2349 // cues, and begin updating it dynamically as necessary. | 2347 // cues, and begin updating it dynamically as necessary. |
| 2350 // - Thess are all done by the media engine. | 2348 // - Thess are all done by the media engine. |
| 2351 | 2349 |
| 2352 // 6. Set the new text track's readiness state to loaded. | 2350 // 6. Set the new text track's readiness state to loaded. |
| 2353 textTrack->setReadinessState(TextTrack::Loaded); | 2351 textTrack->setReadinessState(TextTrack::Loaded); |
| 2354 | 2352 |
| 2355 // 7. Set the new text track's mode to the mode consistent with the user's p references and the requirements of | 2353 // 7. Set the new text track's mode to the mode consistent with the user's p references and the requirements of |
| 2356 // the relevant specification for the data. | 2354 // the relevant specification for the data. |
| 2357 // - This will happen in honorUserPreferencesForAutomaticTextTrackSelection () | 2355 // - This will happen in honorUserPreferencesForAutomaticTextTrackSelection () |
| 2358 scheduleDelayedAction(LoadTextTrackResource); | 2356 scheduleTextTrackResourceLoad(); |
| 2359 | 2357 |
| 2360 // 8. Add the new text track to the media element's list of text tracks. | 2358 // 8. Add the new text track to the media element's list of text tracks. |
| 2361 // 9. Fire an event with the name addtrack, that does not bubble and is not cancelable, and that uses the TrackEvent | 2359 // 9. Fire an event with the name addtrack, that does not bubble and is not cancelable, and that uses the TrackEvent |
| 2362 // interface, with the track attribute initialized to the text track's TextT rack object, at the media element's | 2360 // interface, with the track attribute initialized to the text track's TextT rack object, at the media element's |
| 2363 // textTracks attribute's TextTrackList object. | 2361 // textTracks attribute's TextTrackList object. |
| 2364 addTextTrack(textTrack); | 2362 addTextTrack(textTrack); |
| 2365 } | 2363 } |
| 2366 | 2364 |
| 2367 void HTMLMediaElement::removeTextTrack(WebInbandTextTrack* webTrack) | 2365 void HTMLMediaElement::removeTextTrack(WebInbandTextTrack* webTrack) |
| 2368 { | 2366 { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2468 // media element's list of text tracks ... [continues in TextTrackList::appe nd] | 2466 // media element's list of text tracks ... [continues in TextTrackList::appe nd] |
| 2469 TextTrack* textTrack = trackElement->track(); | 2467 TextTrack* textTrack = trackElement->track(); |
| 2470 if (!textTrack) | 2468 if (!textTrack) |
| 2471 return; | 2469 return; |
| 2472 | 2470 |
| 2473 addTextTrack(textTrack); | 2471 addTextTrack(textTrack); |
| 2474 | 2472 |
| 2475 // Do not schedule the track loading until parsing finishes so we don't star t before all tracks | 2473 // Do not schedule the track loading until parsing finishes so we don't star t before all tracks |
| 2476 // in the markup have been added. | 2474 // in the markup have been added. |
| 2477 if (isFinishedParsingChildren()) | 2475 if (isFinishedParsingChildren()) |
| 2478 scheduleDelayedAction(LoadTextTrackResource); | 2476 scheduleTextTrackResourceLoad(); |
| 2479 } | 2477 } |
| 2480 | 2478 |
| 2481 void HTMLMediaElement::didRemoveTrackElement(HTMLTrackElement* trackElement) | 2479 void HTMLMediaElement::didRemoveTrackElement(HTMLTrackElement* trackElement) |
| 2482 { | 2480 { |
| 2483 #if !LOG_DISABLED | 2481 #if !LOG_DISABLED |
| 2484 KURL url = trackElement->getNonEmptyURLAttribute(srcAttr); | 2482 KURL url = trackElement->getNonEmptyURLAttribute(srcAttr); |
| 2485 WTF_LOG(Media, "HTMLMediaElement::didRemoveTrackElement(%p) - 'src' is %s", this, urlForLoggingMedia(url).utf8().data()); | 2483 WTF_LOG(Media, "HTMLMediaElement::didRemoveTrackElement(%p) - 'src' is %s", this, urlForLoggingMedia(url).utf8().data()); |
| 2486 #endif | 2484 #endif |
| 2487 | 2485 |
| 2488 TextTrack* textTrack = trackElement->track(); | 2486 TextTrack* textTrack = trackElement->track(); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2645 #endif | 2643 #endif |
| 2646 | 2644 |
| 2647 // We should only consider a <source> element when there is not src attribut e at all. | 2645 // We should only consider a <source> element when there is not src attribut e at all. |
| 2648 if (fastHasAttribute(srcAttr)) | 2646 if (fastHasAttribute(srcAttr)) |
| 2649 return; | 2647 return; |
| 2650 | 2648 |
| 2651 // 4.8.8 - If a source element is inserted as a child of a media element tha t has no src | 2649 // 4.8.8 - If a source element is inserted as a child of a media element tha t has no src |
| 2652 // attribute and whose networkState has the value NETWORK_EMPTY, the user ag ent must invoke | 2650 // attribute and whose networkState has the value NETWORK_EMPTY, the user ag ent must invoke |
| 2653 // the media element's resource selection algorithm. | 2651 // the media element's resource selection algorithm. |
| 2654 if (networkState() == HTMLMediaElement::NETWORK_EMPTY) { | 2652 if (networkState() == HTMLMediaElement::NETWORK_EMPTY) { |
| 2655 scheduleDelayedAction(LoadMediaResource); | 2653 if (!(m_pendingActionFlags & LoadMediaResource)) |
|
philipj_slow
2016/01/21 12:48:11
Here too, can we just invoke the resource selectio
Srirama
2016/01/28 11:31:03
Done.
| |
| 2654 invokeResourceSelectionAlgorithm(); | |
| 2655 | |
| 2656 scheduleNextSourceChild(); | |
| 2656 m_nextChildNodeToConsider = source; | 2657 m_nextChildNodeToConsider = source; |
| 2657 return; | 2658 return; |
| 2658 } | 2659 } |
| 2659 | 2660 |
| 2660 if (m_currentSourceNode && source == m_currentSourceNode->nextSibling()) { | 2661 if (m_currentSourceNode && source == m_currentSourceNode->nextSibling()) { |
| 2661 WTF_LOG(Media, "HTMLMediaElement::sourceWasAdded(%p) - <source> inserted immediately after current source", this); | 2662 WTF_LOG(Media, "HTMLMediaElement::sourceWasAdded(%p) - <source> inserted immediately after current source", this); |
| 2662 m_nextChildNodeToConsider = source; | 2663 m_nextChildNodeToConsider = source; |
| 2663 return; | 2664 return; |
| 2664 } | 2665 } |
| 2665 | 2666 |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2999 audioSourceProvider().setClient(nullptr); | 3000 audioSourceProvider().setClient(nullptr); |
| 3000 #endif | 3001 #endif |
| 3001 if (m_webMediaPlayer) { | 3002 if (m_webMediaPlayer) { |
| 3002 #if ENABLE(WEB_AUDIO) | 3003 #if ENABLE(WEB_AUDIO) |
| 3003 m_audioSourceProvider.wrap(nullptr); | 3004 m_audioSourceProvider.wrap(nullptr); |
| 3004 #endif | 3005 #endif |
| 3005 m_webMediaPlayer.clear(); | 3006 m_webMediaPlayer.clear(); |
| 3006 } | 3007 } |
| 3007 } | 3008 } |
| 3008 | 3009 |
| 3009 void HTMLMediaElement::clearMediaPlayer(int flags) | 3010 void HTMLMediaElement::resetMediaElement(int flags) |
| 3010 { | 3011 { |
| 3011 forgetResourceSpecificTracks(); | 3012 forgetResourceSpecificTracks(); |
| 3012 | 3013 |
| 3013 closeMediaSource(); | 3014 closeMediaSource(); |
| 3014 | 3015 |
| 3015 cancelDeferredLoad(); | 3016 cancelDeferredLoad(); |
| 3016 | 3017 |
| 3017 { | 3018 { |
| 3018 AudioSourceProviderClientLockScope scope(*this); | 3019 AudioSourceProviderClientLockScope scope(*this); |
| 3019 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); | 3020 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); |
| 3020 } | 3021 } |
| 3021 | 3022 |
| 3023 #if ENABLE(WEB_AUDIO) | |
| 3024 if (m_audioSourceNode) | |
| 3025 audioSourceProvider().setClient(m_audioSourceNode); | |
| 3026 #endif | |
| 3027 | |
| 3022 stopPeriodicTimers(); | 3028 stopPeriodicTimers(); |
| 3023 m_loadTimer.stop(); | 3029 m_loadTimer.stop(); |
| 3024 | 3030 |
| 3025 m_pendingActionFlags &= ~flags; | 3031 m_pendingActionFlags &= ~flags; |
| 3026 m_loadState = WaitingForSource; | 3032 m_loadState = WaitingForSource; |
| 3027 | 3033 |
| 3028 // We can't cast if we don't have a media player. | 3034 // We can't cast if we don't have a media player. |
| 3029 m_remoteRoutesAvailable = false; | 3035 m_remoteRoutesAvailable = false; |
| 3030 m_playingRemotely = false; | 3036 m_playingRemotely = false; |
| 3037 | |
| 3038 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec essary and set m_pendingActionFlags to 0 here. | |
| 3039 m_sentEndEvent = false; | |
| 3040 m_sentStalledEvent = false; | |
| 3041 m_haveFiredLoadedData = false; | |
| 3042 m_completelyLoaded = false; | |
| 3043 m_havePreparedToPlay = false; | |
| 3044 m_displayMode = Unknown; | |
| 3045 | |
| 3046 m_readyState = HAVE_NOTHING; | |
| 3047 m_readyStateMaximum = HAVE_NOTHING; | |
| 3048 setNetworkState(NETWORK_EMPTY); | |
| 3049 setShouldDelayLoadEvent(false); | |
| 3050 m_currentSourceNode = nullptr; | |
| 3051 invalidateCachedTime(); | |
| 3052 cueTimeline().updateActiveCues(0); | |
| 3053 m_playing = false; | |
| 3054 m_paused = true; | |
| 3055 m_seeking = false; | |
| 3056 | |
| 3031 if (mediaControls()) | 3057 if (mediaControls()) |
| 3032 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); | 3058 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); |
| 3033 | 3059 |
| 3034 if (layoutObject()) | 3060 if (layoutObject()) |
| 3035 layoutObject()->setShouldDoFullPaintInvalidation(); | 3061 layoutObject()->setShouldDoFullPaintInvalidation(); |
| 3036 } | 3062 } |
| 3037 | 3063 |
| 3038 void HTMLMediaElement::stop() | 3064 void HTMLMediaElement::stop() |
| 3039 { | 3065 { |
| 3040 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); | 3066 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); |
| 3041 | 3067 |
| 3042 recordMetricsIfPausing(); | 3068 recordMetricsIfPausing(); |
| 3043 | 3069 |
| 3044 // Close the async event queue so that no events are enqueued. | 3070 // Close the async event queue so that no events are enqueued. |
| 3045 cancelPendingEventsAndCallbacks(); | 3071 cancelPendingEventsAndCallbacks(); |
| 3046 m_asyncEventQueue->close(); | 3072 m_asyncEventQueue->close(); |
| 3047 | 3073 |
| 3048 // Stop the playback without generating events | 3074 // Clear everything in the Media Element |
| 3049 clearMediaPlayer(-1); | 3075 resetMediaElement(-1); |
| 3050 m_readyState = HAVE_NOTHING; | |
| 3051 m_readyStateMaximum = HAVE_NOTHING; | |
| 3052 setNetworkState(NETWORK_EMPTY); | |
| 3053 setShouldDelayLoadEvent(false); | |
| 3054 m_currentSourceNode = nullptr; | |
| 3055 invalidateCachedTime(); | |
| 3056 cueTimeline().updateActiveCues(0); | |
| 3057 m_playing = false; | |
| 3058 m_paused = true; | |
| 3059 m_seeking = false; | |
| 3060 | 3076 |
| 3061 if (layoutObject()) | 3077 if (layoutObject()) |
| 3062 layoutObject()->updateFromElement(); | 3078 layoutObject()->updateFromElement(); |
| 3063 | 3079 |
| 3064 stopPeriodicTimers(); | |
| 3065 | |
| 3066 // Ensure that hasPendingActivity() is not preventing garbage collection, si nce otherwise this | 3080 // Ensure that hasPendingActivity() is not preventing garbage collection, si nce otherwise this |
| 3067 // media element will simply leak. | 3081 // media element will simply leak. |
| 3068 ASSERT(!hasPendingActivity()); | 3082 ASSERT(!hasPendingActivity()); |
| 3069 } | 3083 } |
| 3070 | 3084 |
| 3071 bool HTMLMediaElement::hasPendingActivity() const | 3085 bool HTMLMediaElement::hasPendingActivity() const |
| 3072 { | 3086 { |
| 3073 // The delaying-the-load-event flag is set by resource selection algorithm w hen looking for a | 3087 // The delaying-the-load-event flag is set by resource selection algorithm w hen looking for a |
| 3074 // resource to load, before networkState has reached to NETWORK_LOADING. | 3088 // resource to load, before networkState has reached to NETWORK_LOADING. |
| 3075 if (m_shouldDelayLoadEvent) | 3089 if (m_shouldDelayLoadEvent) |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3404 } | 3418 } |
| 3405 | 3419 |
| 3406 void* HTMLMediaElement::preDispatchEventHandler(Event* event) | 3420 void* HTMLMediaElement::preDispatchEventHandler(Event* event) |
| 3407 { | 3421 { |
| 3408 if (event && event->type() == EventTypeNames::webkitfullscreenchange) | 3422 if (event && event->type() == EventTypeNames::webkitfullscreenchange) |
| 3409 configureMediaControls(); | 3423 configureMediaControls(); |
| 3410 | 3424 |
| 3411 return nullptr; | 3425 return nullptr; |
| 3412 } | 3426 } |
| 3413 | 3427 |
| 3414 // TODO(srirama.m): Refactor this and clearMediaPlayer to the extent possible. | 3428 // TODO(srirama.m): Merge it to resetMediaElement if possible and remove it. |
| 3415 void HTMLMediaElement::resetMediaPlayerAndMediaSource() | 3429 void HTMLMediaElement::resetMediaPlayerAndMediaSource() |
| 3416 { | 3430 { |
| 3417 closeMediaSource(); | 3431 closeMediaSource(); |
| 3418 | 3432 |
| 3419 { | 3433 { |
| 3420 AudioSourceProviderClientLockScope scope(*this); | 3434 AudioSourceProviderClientLockScope scope(*this); |
| 3421 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); | 3435 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); |
| 3422 } | 3436 } |
| 3423 | 3437 |
| 3424 // We haven't yet found out if any remote routes are available. | 3438 // We haven't yet found out if any remote routes are available. |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3652 visitor->trace(m_client); | 3666 visitor->trace(m_client); |
| 3653 } | 3667 } |
| 3654 | 3668 |
| 3655 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) | 3669 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) |
| 3656 { | 3670 { |
| 3657 visitor->trace(m_client); | 3671 visitor->trace(m_client); |
| 3658 } | 3672 } |
| 3659 #endif | 3673 #endif |
| 3660 | 3674 |
| 3661 } | 3675 } |
| OLD | NEW |