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 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 325 , m_playing(false) | 325 , m_playing(false) |
| 326 , m_shouldDelayLoadEvent(false) | 326 , m_shouldDelayLoadEvent(false) |
| 327 , m_haveFiredLoadedData(false) | 327 , m_haveFiredLoadedData(false) |
| 328 , m_autoplaying(true) | 328 , m_autoplaying(true) |
| 329 , m_muted(false) | 329 , m_muted(false) |
| 330 , m_paused(true) | 330 , m_paused(true) |
| 331 , m_seeking(false) | 331 , m_seeking(false) |
| 332 , m_sentStalledEvent(false) | 332 , m_sentStalledEvent(false) |
| 333 , m_sentEndEvent(false) | 333 , m_sentEndEvent(false) |
| 334 , m_closedCaptionsVisible(false) | 334 , m_closedCaptionsVisible(false) |
| 335 , m_havePreparedToPlay(false) | 335 , m_ignorePreloadNone(false) |
| 336 , m_tracksAreReady(true) | 336 , m_tracksAreReady(true) |
| 337 , m_processingPreferenceChange(false) | 337 , m_processingPreferenceChange(false) |
| 338 , m_remoteRoutesAvailable(false) | 338 , m_remoteRoutesAvailable(false) |
| 339 , m_playingRemotely(false) | 339 , m_playingRemotely(false) |
| 340 , m_isFinalizing(false) | 340 , m_isFinalizing(false) |
| 341 , m_initialPlayWithoutUserGesture(false) | 341 , m_initialPlayWithoutUserGesture(false) |
| 342 , m_autoplayMediaCounted(false) | 342 , m_autoplayMediaCounted(false) |
| 343 , m_inOverlayFullscreenVideo(false) | 343 , m_inOverlayFullscreenVideo(false) |
| 344 , m_audioTracks(AudioTrackList::create(*this)) | 344 , m_audioTracks(AudioTrackList::create(*this)) |
| 345 , m_videoTracks(VideoTrackList::create(*this)) | 345 , m_videoTracks(VideoTrackList::create(*this)) |
| (...skipping 118 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 invokeLoadAlgorithm(); |
| 475 scheduleDelayedAction(LoadMediaResource); | |
| 476 | 475 |
| 477 // Decrement the load event delay count on oldDocument now that m_webMediaPl ayer has been destroyed | 476 // 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. | 477 // and there is no risk of dispatching a load event from within the destruct or. |
| 479 oldDocument.decrementLoadEventDelayCount(); | 478 oldDocument.decrementLoadEventDelayCount(); |
| 480 | 479 |
| 481 ActiveDOMObject::didMoveToNewExecutionContext(&document()); | 480 ActiveDOMObject::didMoveToNewExecutionContext(&document()); |
| 482 HTMLElement::didMoveToNewDocument(oldDocument); | 481 HTMLElement::didMoveToNewDocument(oldDocument); |
| 483 } | 482 } |
| 484 | 483 |
| 485 bool HTMLMediaElement::supportsFocus() const | 484 bool HTMLMediaElement::supportsFocus() const |
| 486 { | 485 { |
| 487 if (ownerDocument()->isMediaDocument()) | 486 if (ownerDocument()->isMediaDocument()) |
| 488 return false; | 487 return false; |
| 489 | 488 |
| 490 // If no controls specified, we should still be able to focus the element if it has tabIndex. | 489 // If no controls specified, we should still be able to focus the element if it has tabIndex. |
| 491 return shouldShowControls() || HTMLElement::supportsFocus(); | 490 return shouldShowControls() || HTMLElement::supportsFocus(); |
| 492 } | 491 } |
| 493 | 492 |
| 494 bool HTMLMediaElement::isMouseFocusable() const | 493 bool HTMLMediaElement::isMouseFocusable() const |
| 495 { | 494 { |
| 496 return false; | 495 return false; |
| 497 } | 496 } |
| 498 | 497 |
| 499 void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& oldValue, const AtomicString& value) | 498 void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& oldValue, const AtomicString& value) |
| 500 { | 499 { |
| 501 if (name == srcAttr) { | 500 if (name == srcAttr) { |
| 502 // Trigger a reload, as long as the 'src' attribute is present. | 501 // Trigger a reload, as long as the 'src' attribute is present. |
| 503 if (!value.isNull()) { | 502 if (!value.isNull()) { |
| 504 clearMediaPlayer(LoadMediaResource); | 503 invokeLoadAlgorithm(); |
| 505 scheduleDelayedAction(LoadMediaResource); | |
| 506 } | 504 } |
| 507 } else if (name == controlsAttr) { | 505 } else if (name == controlsAttr) { |
| 508 UseCounter::count(document(), UseCounter::HTMLMediaElementControlsAttrib ute); | 506 UseCounter::count(document(), UseCounter::HTMLMediaElementControlsAttrib ute); |
| 509 configureMediaControls(); | 507 configureMediaControls(); |
| 510 } else if (name == preloadAttr) { | 508 } else if (name == preloadAttr) { |
| 511 setPlayerPreload(); | 509 setPlayerPreload(); |
| 512 } else if (name == disableremoteplaybackAttr) { | 510 } else if (name == disableremoteplaybackAttr) { |
| 513 UseCounter::count(document(), UseCounter::DisableRemotePlaybackAttribute ); | 511 UseCounter::count(document(), UseCounter::DisableRemotePlaybackAttribute ); |
| 514 } else { | 512 } else { |
| 515 HTMLElement::parseAttribute(name, oldValue, value); | 513 HTMLElement::parseAttribute(name, oldValue, value); |
| 516 } | 514 } |
| 517 } | 515 } |
| 518 | 516 |
| 519 void HTMLMediaElement::finishParsingChildren() | 517 void HTMLMediaElement::finishParsingChildren() |
| 520 { | 518 { |
| 521 HTMLElement::finishParsingChildren(); | 519 HTMLElement::finishParsingChildren(); |
| 522 | 520 |
| 523 if (Traversal<HTMLTrackElement>::firstChild(*this)) | 521 if (Traversal<HTMLTrackElement>::firstChild(*this)) |
| 524 scheduleDelayedAction(LoadTextTrackResource); | 522 scheduleTextTrackResourceLoad(); |
| 525 } | 523 } |
| 526 | 524 |
| 527 bool HTMLMediaElement::layoutObjectIsNeeded(const ComputedStyle& style) | 525 bool HTMLMediaElement::layoutObjectIsNeeded(const ComputedStyle& style) |
| 528 { | 526 { |
| 529 return shouldShowControls() && HTMLElement::layoutObjectIsNeeded(style); | 527 return shouldShowControls() && HTMLElement::layoutObjectIsNeeded(style); |
| 530 } | 528 } |
| 531 | 529 |
| 532 LayoutObject* HTMLMediaElement::createLayoutObject(const ComputedStyle&) | 530 LayoutObject* HTMLMediaElement::createLayoutObject(const ComputedStyle&) |
| 533 { | 531 { |
| 534 return new LayoutMedia(this); | 532 return new LayoutMedia(this); |
| 535 } | 533 } |
| 536 | 534 |
| 537 Node::InsertionNotificationRequest HTMLMediaElement::insertedInto(ContainerNode* insertionPoint) | 535 Node::InsertionNotificationRequest HTMLMediaElement::insertedInto(ContainerNode* insertionPoint) |
| 538 { | 536 { |
| 539 WTF_LOG(Media, "HTMLMediaElement::insertedInto(%p, %p)", this, insertionPoin t); | 537 WTF_LOG(Media, "HTMLMediaElement::insertedInto(%p, %p)", this, insertionPoin t); |
| 540 | 538 |
| 541 HTMLElement::insertedInto(insertionPoint); | 539 HTMLElement::insertedInto(insertionPoint); |
| 542 if (insertionPoint->inDocument()) { | 540 if (insertionPoint->inDocument()) { |
| 543 UseCounter::count(document(), UseCounter::HTMLMediaElementInDocument); | 541 UseCounter::count(document(), UseCounter::HTMLMediaElementInDocument); |
| 544 if (!getAttribute(srcAttr).isEmpty() && m_networkState == NETWORK_EMPTY) | 542 if (!getAttribute(srcAttr).isEmpty() && m_networkState == NETWORK_EMPTY) |
| 545 scheduleDelayedAction(LoadMediaResource); | 543 invokeLoadAlgorithm(); |
| 546 } | 544 } |
| 547 | 545 |
| 548 return InsertionShouldCallDidNotifySubtreeInsertions; | 546 return InsertionShouldCallDidNotifySubtreeInsertions; |
| 549 } | 547 } |
| 550 | 548 |
| 551 void HTMLMediaElement::didNotifySubtreeInsertionsToDocument() | 549 void HTMLMediaElement::didNotifySubtreeInsertionsToDocument() |
| 552 { | 550 { |
| 553 configureMediaControls(); | 551 configureMediaControls(); |
| 554 } | 552 } |
| 555 | 553 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 572 if (layoutObject()) | 570 if (layoutObject()) |
| 573 layoutObject()->updateFromElement(); | 571 layoutObject()->updateFromElement(); |
| 574 } | 572 } |
| 575 | 573 |
| 576 void HTMLMediaElement::didRecalcStyle(StyleRecalcChange) | 574 void HTMLMediaElement::didRecalcStyle(StyleRecalcChange) |
| 577 { | 575 { |
| 578 if (layoutObject()) | 576 if (layoutObject()) |
| 579 layoutObject()->updateFromElement(); | 577 layoutObject()->updateFromElement(); |
| 580 } | 578 } |
| 581 | 579 |
| 582 void HTMLMediaElement::scheduleDelayedAction(DelayedActionType actionType) | 580 void HTMLMediaElement::scheduleTextTrackResourceLoad() |
| 583 { | 581 { |
| 584 WTF_LOG(Media, "HTMLMediaElement::scheduleDelayedAction(%p)", this); | 582 WTF_LOG(Media, "HTMLMediaElement::scheduleTextTrackResourceLoad(%p)", this); |
| 585 | 583 |
| 586 if ((actionType & LoadMediaResource) && !(m_pendingActionFlags & LoadMediaRe source)) { | 584 m_pendingActionFlags |= LoadTextTrackResource; |
| 587 prepareForLoad(); | |
| 588 m_pendingActionFlags |= LoadMediaResource; | |
| 589 } | |
| 590 | |
| 591 if (actionType & LoadTextTrackResource) | |
| 592 m_pendingActionFlags |= LoadTextTrackResource; | |
| 593 | 585 |
| 594 if (!m_loadTimer.isActive()) | 586 if (!m_loadTimer.isActive()) |
| 595 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); | 587 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); |
| 596 } | 588 } |
| 597 | 589 |
| 598 void HTMLMediaElement::scheduleNextSourceChild() | 590 void HTMLMediaElement::scheduleNextSourceChild() |
| 599 { | 591 { |
| 600 // Schedule the timer to try the next <source> element WITHOUT resetting sta te ala prepareForLoad. | 592 // Schedule the timer to try the next <source> element WITHOUT resetting sta te ala prepareForLoad. |
| 601 m_pendingActionFlags |= LoadMediaResource; | 593 m_pendingActionFlags |= LoadMediaResource; |
| 602 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); | 594 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 703 | 695 |
| 704 if (UserGestureIndicator::processingUserGesture() && m_userGestureRequiredFo rPlay) { | 696 if (UserGestureIndicator::processingUserGesture() && m_userGestureRequiredFo rPlay) { |
| 705 recordAutoplayMetric(AutoplayEnabledThroughLoad); | 697 recordAutoplayMetric(AutoplayEnabledThroughLoad); |
| 706 m_userGestureRequiredForPlay = false; | 698 m_userGestureRequiredForPlay = false; |
| 707 // While usergesture-initiated load()s technically count as autoplayed, | 699 // While usergesture-initiated load()s technically count as autoplayed, |
| 708 // they don't feel like such to the users and hence we don't want to | 700 // they don't feel like such to the users and hence we don't want to |
| 709 // count them for the purposes of metrics. | 701 // count them for the purposes of metrics. |
| 710 m_autoplayMediaCounted = true; | 702 m_autoplayMediaCounted = true; |
| 711 } | 703 } |
| 712 | 704 |
| 705 m_ignorePreloadNone = true; | |
| 713 prepareForLoad(); | 706 prepareForLoad(); |
|
philipj_slow
2016/03/09 09:15:59
There ought to be a call to invokeLoadAlgorithm()
philipj_slow
2016/03/09 09:27:23
But I suppose you will need if (loadIsDeferred())
philipj_slow
2016/03/09 09:30:22
Sorry, I'm writing comments out of order. This cou
Srirama
2016/03/09 12:26:22
Replaced prepareForLoad + loadInternal with invoke
| |
| 714 loadInternal(); | 707 loadInternal(); |
| 715 prepareToPlay(); | 708 } |
| 709 | |
| 710 void HTMLMediaElement::invokeLoadAlgorithm() | |
| 711 { | |
| 712 WTF_LOG(Media, "HTMLMediaElement::invokeLoadAlgorithm(%p)", this); | |
| 713 | |
| 714 prepareForLoad(); | |
| 715 scheduleNextSourceChild(); | |
| 716 } | 716 } |
| 717 | 717 |
| 718 void HTMLMediaElement::prepareForLoad() | 718 void HTMLMediaElement::prepareForLoad() |
| 719 { | 719 { |
| 720 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this); | 720 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this); |
| 721 | 721 |
| 722 // Perform the cleanup required for the resource load algorithm to run. | 722 // Perform the cleanup required for the resource load algorithm to run. |
| 723 stopPeriodicTimers(); | 723 stopPeriodicTimers(); |
| 724 m_loadTimer.stop(); | 724 m_loadTimer.stop(); |
| 725 cancelDeferredLoad(); | 725 cancelDeferredLoad(); |
| 726 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec essary and set m_pendingActionFlags to 0 here. | 726 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec essary and set m_pendingActionFlags to 0 here. |
| 727 m_pendingActionFlags &= ~LoadMediaResource; | 727 m_pendingActionFlags &= ~LoadMediaResource; |
| 728 m_sentEndEvent = false; | 728 m_sentEndEvent = false; |
| 729 m_sentStalledEvent = false; | 729 m_sentStalledEvent = false; |
| 730 m_haveFiredLoadedData = false; | 730 m_haveFiredLoadedData = false; |
| 731 m_havePreparedToPlay = false; | |
| 732 m_displayMode = Unknown; | 731 m_displayMode = Unknown; |
| 733 | 732 |
| 734 // 1 - Abort any already-running instance of the resource selection algorith m for this element. | 733 // 1 - Abort any already-running instance of the resource selection algorith m for this element. |
| 735 m_loadState = WaitingForSource; | 734 m_loadState = WaitingForSource; |
| 736 m_currentSourceNode = nullptr; | 735 m_currentSourceNode = nullptr; |
| 737 | 736 |
| 738 // 2 - If there are any tasks from the media element's media element event t ask source in | 737 // 2 - If there are any tasks from the media element's media element event t ask source in |
| 739 // one of the task queues, then remove those tasks. | 738 // one of the task queues, then remove those tasks. |
| 740 cancelPendingEventsAndCallbacks(); | 739 cancelPendingEventsAndCallbacks(); |
| 741 | 740 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 785 } | 784 } |
| 786 | 785 |
| 787 // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRat e attribute. | 786 // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRat e attribute. |
| 788 setPlaybackRate(defaultPlaybackRate()); | 787 setPlaybackRate(defaultPlaybackRate()); |
| 789 | 788 |
| 790 // 6 - Set the error attribute to null and the autoplaying flag to true. | 789 // 6 - Set the error attribute to null and the autoplaying flag to true. |
| 791 m_error = nullptr; | 790 m_error = nullptr; |
| 792 m_autoplaying = true; | 791 m_autoplaying = true; |
| 793 | 792 |
| 794 // 7 - Invoke the media element's resource selection algorithm. | 793 // 7 - Invoke the media element's resource selection algorithm. |
| 794 invokeResourceSelectionAlgorithm(); | |
| 795 | 795 |
| 796 // 8 - Note: Playback of any previously playing media resource for this elem ent stops. | 796 // 8 - Note: Playback of any previously playing media resource for this elem ent stops. |
| 797 } | |
| 797 | 798 |
| 799 void HTMLMediaElement::invokeResourceSelectionAlgorithm() | |
| 800 { | |
| 801 WTF_LOG(Media, "HTMLMediaElement::invokeResourceSelectionAlgorithm(%p)", thi s); | |
| 798 // The resource selection algorithm | 802 // The resource selection algorithm |
| 799 // 1 - Set the networkState to NETWORK_NO_SOURCE | 803 // 1 - Set the networkState to NETWORK_NO_SOURCE |
| 800 setNetworkState(NETWORK_NO_SOURCE); | 804 setNetworkState(NETWORK_NO_SOURCE); |
| 801 | 805 |
| 802 // 2 - Asynchronously await a stable state. | 806 // 2 - Set the element's show poster flag to true |
| 807 // TODO(srirama.m): Introduce show poster flag and update it as per spec | |
| 803 | 808 |
| 804 m_playedTimeRanges = TimeRanges::create(); | 809 m_playedTimeRanges = TimeRanges::create(); |
| 805 | 810 |
| 806 // FIXME: Investigate whether these can be moved into m_networkState != NETW ORK_EMPTY block above | 811 // FIXME: Investigate whether these can be moved into m_networkState != NETW ORK_EMPTY block above |
| 807 // so they are closer to the relevant spec steps. | 812 // so they are closer to the relevant spec steps. |
| 808 m_lastSeekTime = 0; | 813 m_lastSeekTime = 0; |
| 809 m_duration = std::numeric_limits<double>::quiet_NaN(); | 814 m_duration = std::numeric_limits<double>::quiet_NaN(); |
| 810 | 815 |
| 811 // The spec doesn't say to block the load event until we actually run the as ynchronous section | 816 // 3 - Set the media element's delaying-the-load-event flag to true (this de lays the load event) |
| 812 // algorithm, but do it now because we won't start that until after the time r fires and the | |
| 813 // event may have already fired by then. | |
| 814 setShouldDelayLoadEvent(true); | 817 setShouldDelayLoadEvent(true); |
| 815 if (mediaControls()) | 818 if (mediaControls()) |
| 816 mediaControls()->reset(); | 819 mediaControls()->reset(); |
| 820 | |
| 821 // 4 - Await a stable state, allowing the task that invoked this algorithm t o continue | |
| 822 // TODO(srirama.m): Schedule an async continuation of this algorithm as per the spec | |
| 817 } | 823 } |
| 818 | 824 |
| 819 void HTMLMediaElement::loadInternal() | 825 void HTMLMediaElement::loadInternal() |
| 820 { | 826 { |
| 821 // HTMLMediaElement::textTracksAreReady will need "... the text tracks whose mode was not in the | 827 // HTMLMediaElement::textTracksAreReady will need "... the text tracks whose mode was not in the |
| 822 // disabled state when the element's resource selection algorithm last start ed". | 828 // disabled state when the element's resource selection algorithm last start ed". |
| 823 m_textTracksWhenResourceSelectionBegan.clear(); | 829 m_textTracksWhenResourceSelectionBegan.clear(); |
| 824 if (m_textTracks) { | 830 if (m_textTracks) { |
| 825 for (unsigned i = 0; i < m_textTracks->length(); ++i) { | 831 for (unsigned i = 0; i < m_textTracks->length(); ++i) { |
| 826 TextTrack* track = m_textTracks->anonymousIndexedGetter(i); | 832 TextTrack* track = m_textTracks->anonymousIndexedGetter(i); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 968 m_mediaSource = nullptr; | 974 m_mediaSource = nullptr; |
| 969 attemptLoad = false; | 975 attemptLoad = false; |
| 970 } | 976 } |
| 971 } | 977 } |
| 972 } | 978 } |
| 973 } | 979 } |
| 974 | 980 |
| 975 if (attemptLoad && canLoadURL(url, contentType)) { | 981 if (attemptLoad && canLoadURL(url, contentType)) { |
| 976 ASSERT(!webMediaPlayer()); | 982 ASSERT(!webMediaPlayer()); |
| 977 | 983 |
| 978 if (!m_havePreparedToPlay && effectivePreloadType() == WebMediaPlayer::P reloadNone) { | 984 if (effectivePreloadType() == WebMediaPlayer::PreloadNone) { |
| 979 WTF_LOG(Media, "HTMLMediaElement::loadResource(%p) : Delaying load b ecause preload == 'none'", this); | 985 WTF_LOG(Media, "HTMLMediaElement::loadResource(%p) : Delaying load b ecause preload == 'none'", this); |
| 980 deferLoad(); | 986 deferLoad(); |
| 981 } else { | 987 } else { |
| 982 startPlayerLoad(); | 988 startPlayerLoad(); |
| 983 } | 989 } |
| 984 } else { | 990 } else { |
| 985 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); | 991 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); |
| 986 } | 992 } |
| 987 | 993 |
| 988 // If there is no poster to display, allow the media engine to render video frames as soon as | 994 // If there is no poster to display, allow the media engine to render video frames as soon as |
| (...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1599 if (!m_playedTimeRanges) | 1605 if (!m_playedTimeRanges) |
| 1600 m_playedTimeRanges = TimeRanges::create(); | 1606 m_playedTimeRanges = TimeRanges::create(); |
| 1601 m_playedTimeRanges->add(start, end); | 1607 m_playedTimeRanges->add(start, end); |
| 1602 } | 1608 } |
| 1603 | 1609 |
| 1604 bool HTMLMediaElement::supportsSave() const | 1610 bool HTMLMediaElement::supportsSave() const |
| 1605 { | 1611 { |
| 1606 return webMediaPlayer() && webMediaPlayer()->supportsSave(); | 1612 return webMediaPlayer() && webMediaPlayer()->supportsSave(); |
| 1607 } | 1613 } |
| 1608 | 1614 |
| 1609 void HTMLMediaElement::prepareToPlay() | |
| 1610 { | |
| 1611 WTF_LOG(Media, "HTMLMediaElement::prepareToPlay(%p)", this); | |
| 1612 if (m_havePreparedToPlay) | |
| 1613 return; | |
| 1614 m_havePreparedToPlay = true; | |
| 1615 | |
| 1616 if (loadIsDeferred()) | |
| 1617 startDeferredLoad(); | |
|
philipj_slow
2016/03/09 09:27:23
OK, so the removal is this code is the "deferred l
Srirama
2016/03/09 12:26:22
Added prepareToPlay again and modified as suggeste
| |
| 1618 } | |
| 1619 | |
| 1620 void HTMLMediaElement::seek(double time) | 1615 void HTMLMediaElement::seek(double time) |
| 1621 { | 1616 { |
| 1622 WTF_LOG(Media, "HTMLMediaElement::seek(%p, %f)", this, time); | 1617 WTF_LOG(Media, "HTMLMediaElement::seek(%p, %f)", this, time); |
| 1623 | 1618 |
| 1624 // 2 - If the media element's readyState is HAVE_NOTHING, abort these steps. | 1619 // 2 - If the media element's readyState is HAVE_NOTHING, abort these steps. |
| 1625 if (m_readyState == HAVE_NOTHING) | 1620 if (m_readyState == HAVE_NOTHING) |
| 1626 return; | 1621 return; |
| 1627 | 1622 |
| 1628 // If the media engine has been told to postpone loading data, let it go ahe ad now. | 1623 // If the media engine has been told to postpone loading data, let it go ahe ad now. |
| 1629 if (preloadType() < WebMediaPlayer::PreloadAuto && m_readyState < HAVE_FUTUR E_DATA) | 1624 if (preloadType() < WebMediaPlayer::PreloadAuto && m_readyState < HAVE_FUTUR E_DATA && loadIsDeferred()) |
| 1630 prepareToPlay(); | 1625 startDeferredLoad(); |
| 1631 | 1626 |
| 1632 // Get the current time before setting m_seeking, m_lastSeekTime is returned once it is set. | 1627 // Get the current time before setting m_seeking, m_lastSeekTime is returned once it is set. |
| 1633 refreshCachedTime(); | 1628 refreshCachedTime(); |
| 1634 // This is needed to avoid getting default playback start position from curr entTime(). | 1629 // This is needed to avoid getting default playback start position from curr entTime(). |
| 1635 double now = m_cachedTime; | 1630 double now = m_cachedTime; |
| 1636 | 1631 |
| 1637 // 3 - If the element's seeking IDL attribute is true, then another instance of this algorithm is | 1632 // 3 - If the element's seeking IDL attribute is true, then another instance of this algorithm is |
| 1638 // already running. Abort that other instance of the algorithm without waiti ng for the step that | 1633 // already running. Abort that other instance of the algorithm without waiti ng for the step that |
| 1639 // it is running to complete. | 1634 // it is running to complete. |
| 1640 // Nothing specific to be done here. | 1635 // Nothing specific to be done here. |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1936 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=28950 | 1931 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=28950 |
| 1937 | 1932 |
| 1938 // TODO(philipj): Try to make "metadata" the default preload state: | 1933 // TODO(philipj): Try to make "metadata" the default preload state: |
| 1939 // https://crbug.com/310450 | 1934 // https://crbug.com/310450 |
| 1940 UseCounter::count(document(), UseCounter::HTMLMediaElementPreloadDefault); | 1935 UseCounter::count(document(), UseCounter::HTMLMediaElementPreloadDefault); |
| 1941 return WebMediaPlayer::PreloadAuto; | 1936 return WebMediaPlayer::PreloadAuto; |
| 1942 } | 1937 } |
| 1943 | 1938 |
| 1944 WebMediaPlayer::Preload HTMLMediaElement::effectivePreloadType() const | 1939 WebMediaPlayer::Preload HTMLMediaElement::effectivePreloadType() const |
| 1945 { | 1940 { |
| 1946 return autoplay() ? WebMediaPlayer::PreloadAuto : preloadType(); | 1941 if (autoplay()) |
| 1942 return WebMediaPlayer::PreloadAuto; | |
| 1943 | |
| 1944 WebMediaPlayer::Preload preload = preloadType(); | |
| 1945 if (m_ignorePreloadNone && preload == WebMediaPlayer::PreloadNone) | |
| 1946 return WebMediaPlayer::PreloadAuto; | |
| 1947 | |
| 1948 return preload; | |
| 1947 } | 1949 } |
| 1948 | 1950 |
| 1949 ScriptPromise HTMLMediaElement::playForBindings(ScriptState* scriptState) | 1951 ScriptPromise HTMLMediaElement::playForBindings(ScriptState* scriptState) |
| 1950 { | 1952 { |
| 1951 Nullable<ExceptionCode> code = play(); | 1953 Nullable<ExceptionCode> code = play(); |
| 1952 if (!code.isNull()) { | 1954 if (!code.isNull()) { |
| 1953 String message; | 1955 String message; |
| 1954 switch (code.get()) { | 1956 switch (code.get()) { |
| 1955 case NotAllowedError: | 1957 case NotAllowedError: |
| 1956 message = "play() can only be initiated by a user gesture."; | 1958 message = "play() can only be initiated by a user gesture."; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2007 { | 2009 { |
| 2008 WTF_LOG(Media, "HTMLMediaElement::playInternal(%p)", this); | 2010 WTF_LOG(Media, "HTMLMediaElement::playInternal(%p)", this); |
| 2009 | 2011 |
| 2010 // Always return the buffering strategy to normal when not paused, | 2012 // Always return the buffering strategy to normal when not paused, |
| 2011 // regardless of the cause. (In contrast with aggressive buffering which is | 2013 // regardless of the cause. (In contrast with aggressive buffering which is |
| 2012 // only enabled by pause(), not pauseInternal().) | 2014 // only enabled by pause(), not pauseInternal().) |
| 2013 if (webMediaPlayer()) | 2015 if (webMediaPlayer()) |
| 2014 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Normal); | 2016 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Normal); |
| 2015 | 2017 |
| 2016 // 4.8.10.9. Playing the media resource | 2018 // 4.8.10.9. Playing the media resource |
| 2017 if (m_networkState == NETWORK_EMPTY) | 2019 if (m_networkState == NETWORK_EMPTY) { |
| 2018 scheduleDelayedAction(LoadMediaResource); | 2020 invokeResourceSelectionAlgorithm(); |
| 2021 scheduleNextSourceChild(); | |
|
philipj_slow
2016/03/09 09:16:00
Remove scheduleNextSourceChild(), if it's breaks t
Srirama
2016/03/09 12:26:22
Right now invokeResourceSelectionAlgorithm doesn't
| |
| 2022 } | |
| 2019 | 2023 |
| 2020 // Generally "ended" and "looping" are exclusive. Here, the loop attribute | 2024 // Generally "ended" and "looping" are exclusive. Here, the loop attribute |
| 2021 // is ignored to seek back to start in case loop was set after playback | 2025 // is ignored to seek back to start in case loop was set after playback |
| 2022 // ended. See http://crbug.com/364442 | 2026 // ended. See http://crbug.com/364442 |
| 2023 if (endedPlayback(LoopCondition::Ignored)) | 2027 if (endedPlayback(LoopCondition::Ignored)) |
| 2024 seek(0); | 2028 seek(0); |
| 2025 | 2029 |
| 2026 if (m_paused) { | 2030 if (m_paused) { |
| 2027 m_paused = false; | 2031 m_paused = false; |
| 2028 invalidateCachedTime(); | 2032 invalidateCachedTime(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2070 if (webMediaPlayer() && UserGestureIndicator::processingUserGesture()) | 2074 if (webMediaPlayer() && UserGestureIndicator::processingUserGesture()) |
| 2071 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Aggressive); | 2075 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Aggressive); |
| 2072 | 2076 |
| 2073 pauseInternal(); | 2077 pauseInternal(); |
| 2074 } | 2078 } |
| 2075 | 2079 |
| 2076 void HTMLMediaElement::pauseInternal() | 2080 void HTMLMediaElement::pauseInternal() |
| 2077 { | 2081 { |
| 2078 WTF_LOG(Media, "HTMLMediaElement::pauseInternal(%p)", this); | 2082 WTF_LOG(Media, "HTMLMediaElement::pauseInternal(%p)", this); |
| 2079 | 2083 |
| 2080 if (m_networkState == NETWORK_EMPTY) | 2084 if (m_networkState == NETWORK_EMPTY) { |
| 2081 scheduleDelayedAction(LoadMediaResource); | 2085 invokeResourceSelectionAlgorithm(); |
| 2086 scheduleNextSourceChild(); | |
|
philipj_slow
2016/03/09 09:16:00
Ditto
Srirama
2016/03/09 12:26:22
See my comment above.
| |
| 2087 } | |
| 2082 | 2088 |
| 2083 m_autoplayHelper.pauseMethodCalled(); | 2089 m_autoplayHelper.pauseMethodCalled(); |
| 2084 | 2090 |
| 2085 m_autoplaying = false; | 2091 m_autoplaying = false; |
| 2086 | 2092 |
| 2087 if (!m_paused) { | 2093 if (!m_paused) { |
| 2088 recordMetricsIfPausing(); | 2094 recordMetricsIfPausing(); |
| 2089 | 2095 |
| 2090 m_paused = true; | 2096 m_paused = true; |
| 2091 scheduleTimeupdateEvent(false); | 2097 scheduleTimeupdateEvent(false); |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2407 // 5. Populate the new text track's list of cues with the cues parsed so far , folllowing the guidelines for exposing | 2413 // 5. Populate the new text track's list of cues with the cues parsed so far , folllowing the guidelines for exposing |
| 2408 // cues, and begin updating it dynamically as necessary. | 2414 // cues, and begin updating it dynamically as necessary. |
| 2409 // - Thess are all done by the media engine. | 2415 // - Thess are all done by the media engine. |
| 2410 | 2416 |
| 2411 // 6. Set the new text track's readiness state to loaded. | 2417 // 6. Set the new text track's readiness state to loaded. |
| 2412 textTrack->setReadinessState(TextTrack::Loaded); | 2418 textTrack->setReadinessState(TextTrack::Loaded); |
| 2413 | 2419 |
| 2414 // 7. Set the new text track's mode to the mode consistent with the user's p references and the requirements of | 2420 // 7. Set the new text track's mode to the mode consistent with the user's p references and the requirements of |
| 2415 // the relevant specification for the data. | 2421 // the relevant specification for the data. |
| 2416 // - This will happen in honorUserPreferencesForAutomaticTextTrackSelection () | 2422 // - This will happen in honorUserPreferencesForAutomaticTextTrackSelection () |
| 2417 scheduleDelayedAction(LoadTextTrackResource); | 2423 scheduleTextTrackResourceLoad(); |
| 2418 | 2424 |
| 2419 // 8. Add the new text track to the media element's list of text tracks. | 2425 // 8. Add the new text track to the media element's list of text tracks. |
| 2420 // 9. Fire an event with the name addtrack, that does not bubble and is not cancelable, and that uses the TrackEvent | 2426 // 9. Fire an event with the name addtrack, that does not bubble and is not cancelable, and that uses the TrackEvent |
| 2421 // interface, with the track attribute initialized to the text track's TextT rack object, at the media element's | 2427 // interface, with the track attribute initialized to the text track's TextT rack object, at the media element's |
| 2422 // textTracks attribute's TextTrackList object. | 2428 // textTracks attribute's TextTrackList object. |
| 2423 addTextTrack(textTrack); | 2429 addTextTrack(textTrack); |
| 2424 } | 2430 } |
| 2425 | 2431 |
| 2426 void HTMLMediaElement::removeTextTrack(WebInbandTextTrack* webTrack) | 2432 void HTMLMediaElement::removeTextTrack(WebInbandTextTrack* webTrack) |
| 2427 { | 2433 { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2527 // media element's list of text tracks ... [continues in TextTrackList::appe nd] | 2533 // media element's list of text tracks ... [continues in TextTrackList::appe nd] |
| 2528 TextTrack* textTrack = trackElement->track(); | 2534 TextTrack* textTrack = trackElement->track(); |
| 2529 if (!textTrack) | 2535 if (!textTrack) |
| 2530 return; | 2536 return; |
| 2531 | 2537 |
| 2532 addTextTrack(textTrack); | 2538 addTextTrack(textTrack); |
| 2533 | 2539 |
| 2534 // Do not schedule the track loading until parsing finishes so we don't star t before all tracks | 2540 // Do not schedule the track loading until parsing finishes so we don't star t before all tracks |
| 2535 // in the markup have been added. | 2541 // in the markup have been added. |
| 2536 if (isFinishedParsingChildren()) | 2542 if (isFinishedParsingChildren()) |
| 2537 scheduleDelayedAction(LoadTextTrackResource); | 2543 scheduleTextTrackResourceLoad(); |
| 2538 } | 2544 } |
| 2539 | 2545 |
| 2540 void HTMLMediaElement::didRemoveTrackElement(HTMLTrackElement* trackElement) | 2546 void HTMLMediaElement::didRemoveTrackElement(HTMLTrackElement* trackElement) |
| 2541 { | 2547 { |
| 2542 #if !LOG_DISABLED | 2548 #if !LOG_DISABLED |
| 2543 KURL url = trackElement->getNonEmptyURLAttribute(srcAttr); | 2549 KURL url = trackElement->getNonEmptyURLAttribute(srcAttr); |
| 2544 WTF_LOG(Media, "HTMLMediaElement::didRemoveTrackElement(%p) - 'src' is %s", this, urlForLoggingMedia(url).utf8().data()); | 2550 WTF_LOG(Media, "HTMLMediaElement::didRemoveTrackElement(%p) - 'src' is %s", this, urlForLoggingMedia(url).utf8().data()); |
| 2545 #endif | 2551 #endif |
| 2546 | 2552 |
| 2547 TextTrack* textTrack = trackElement->track(); | 2553 TextTrack* textTrack = trackElement->track(); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2700 #endif | 2706 #endif |
| 2701 | 2707 |
| 2702 // We should only consider a <source> element when there is not src attribut e at all. | 2708 // We should only consider a <source> element when there is not src attribut e at all. |
| 2703 if (fastHasAttribute(srcAttr)) | 2709 if (fastHasAttribute(srcAttr)) |
| 2704 return; | 2710 return; |
| 2705 | 2711 |
| 2706 // 4.8.8 - If a source element is inserted as a child of a media element tha t has no src | 2712 // 4.8.8 - If a source element is inserted as a child of a media element tha t has no src |
| 2707 // attribute and whose networkState has the value NETWORK_EMPTY, the user ag ent must invoke | 2713 // attribute and whose networkState has the value NETWORK_EMPTY, the user ag ent must invoke |
| 2708 // the media element's resource selection algorithm. | 2714 // the media element's resource selection algorithm. |
| 2709 if (networkState() == HTMLMediaElement::NETWORK_EMPTY) { | 2715 if (networkState() == HTMLMediaElement::NETWORK_EMPTY) { |
| 2710 scheduleDelayedAction(LoadMediaResource); | 2716 invokeResourceSelectionAlgorithm(); |
| 2717 scheduleNextSourceChild(); | |
|
philipj_slow
2016/03/09 09:16:00
Ditto. It would also be *nice* if m_nextChildNodeT
Srirama
2016/03/09 12:26:22
I think if we move m_nextChildNodeToConsider above
| |
| 2711 m_nextChildNodeToConsider = source; | 2718 m_nextChildNodeToConsider = source; |
| 2712 return; | 2719 return; |
| 2713 } | 2720 } |
| 2714 | 2721 |
| 2715 if (m_currentSourceNode && source == m_currentSourceNode->nextSibling()) { | 2722 if (m_currentSourceNode && source == m_currentSourceNode->nextSibling()) { |
| 2716 WTF_LOG(Media, "HTMLMediaElement::sourceWasAdded(%p) - <source> inserted immediately after current source", this); | 2723 WTF_LOG(Media, "HTMLMediaElement::sourceWasAdded(%p) - <source> inserted immediately after current source", this); |
| 2717 m_nextChildNodeToConsider = source; | 2724 m_nextChildNodeToConsider = source; |
| 2718 return; | 2725 return; |
| 2719 } | 2726 } |
| 2720 | 2727 |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3030 } | 3037 } |
| 3031 | 3038 |
| 3032 refreshCachedTime(); | 3039 refreshCachedTime(); |
| 3033 | 3040 |
| 3034 m_playbackProgressTimer.stop(); | 3041 m_playbackProgressTimer.stop(); |
| 3035 m_playing = false; | 3042 m_playing = false; |
| 3036 double time = currentTime(); | 3043 double time = currentTime(); |
| 3037 if (time > m_lastSeekTime) | 3044 if (time > m_lastSeekTime) |
| 3038 addPlayedRange(m_lastSeekTime, time); | 3045 addPlayedRange(m_lastSeekTime, time); |
| 3039 | 3046 |
| 3040 if (couldPlayIfEnoughData()) | 3047 if (couldPlayIfEnoughData() && loadIsDeferred()) |
| 3041 prepareToPlay(); | 3048 startDeferredLoad(); |
| 3042 | 3049 |
| 3043 if (mediaControls()) | 3050 if (mediaControls()) |
| 3044 mediaControls()->playbackStopped(); | 3051 mediaControls()->playbackStopped(); |
| 3045 } | 3052 } |
| 3046 | 3053 |
| 3047 if (layoutObject()) | 3054 if (layoutObject()) |
| 3048 layoutObject()->updateFromElement(); | 3055 layoutObject()->updateFromElement(); |
| 3049 } | 3056 } |
| 3050 | 3057 |
| 3051 void HTMLMediaElement::stopPeriodicTimers() | 3058 void HTMLMediaElement::stopPeriodicTimers() |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3095 void HTMLMediaElement::stop() | 3102 void HTMLMediaElement::stop() |
| 3096 { | 3103 { |
| 3097 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); | 3104 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); |
| 3098 | 3105 |
| 3099 recordMetricsIfPausing(); | 3106 recordMetricsIfPausing(); |
| 3100 | 3107 |
| 3101 // Close the async event queue so that no events are enqueued. | 3108 // Close the async event queue so that no events are enqueued. |
| 3102 cancelPendingEventsAndCallbacks(); | 3109 cancelPendingEventsAndCallbacks(); |
| 3103 m_asyncEventQueue->close(); | 3110 m_asyncEventQueue->close(); |
| 3104 | 3111 |
| 3105 // Stop the playback without generating events | 3112 // Clear everything in the Media Element |
| 3106 clearMediaPlayer(-1); | 3113 clearMediaPlayer(-1); |
| 3107 m_readyState = HAVE_NOTHING; | 3114 m_readyState = HAVE_NOTHING; |
| 3108 m_readyStateMaximum = HAVE_NOTHING; | 3115 m_readyStateMaximum = HAVE_NOTHING; |
| 3109 setNetworkState(NETWORK_EMPTY); | 3116 setNetworkState(NETWORK_EMPTY); |
| 3110 setShouldDelayLoadEvent(false); | 3117 setShouldDelayLoadEvent(false); |
| 3111 m_currentSourceNode = nullptr; | 3118 m_currentSourceNode = nullptr; |
| 3112 invalidateCachedTime(); | 3119 invalidateCachedTime(); |
| 3113 cueTimeline().updateActiveCues(0); | 3120 cueTimeline().updateActiveCues(0); |
| 3114 m_playing = false; | 3121 m_playing = false; |
| 3115 m_paused = true; | 3122 m_paused = true; |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3467 } | 3474 } |
| 3468 | 3475 |
| 3469 void* HTMLMediaElement::preDispatchEventHandler(Event* event) | 3476 void* HTMLMediaElement::preDispatchEventHandler(Event* event) |
| 3470 { | 3477 { |
| 3471 if (event && event->type() == EventTypeNames::webkitfullscreenchange) | 3478 if (event && event->type() == EventTypeNames::webkitfullscreenchange) |
| 3472 configureMediaControls(); | 3479 configureMediaControls(); |
| 3473 | 3480 |
| 3474 return nullptr; | 3481 return nullptr; |
| 3475 } | 3482 } |
| 3476 | 3483 |
| 3477 // TODO(srirama.m): Refactor this and clearMediaPlayer to the extent possible. | 3484 // TODO(srirama.m): Merge it to resetMediaElement if possible and remove it. |
| 3478 void HTMLMediaElement::resetMediaPlayerAndMediaSource() | 3485 void HTMLMediaElement::resetMediaPlayerAndMediaSource() |
| 3479 { | 3486 { |
| 3480 closeMediaSource(); | 3487 closeMediaSource(); |
| 3481 | 3488 |
| 3482 { | 3489 { |
| 3483 AudioSourceProviderClientLockScope scope(*this); | 3490 AudioSourceProviderClientLockScope scope(*this); |
| 3484 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); | 3491 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); |
| 3485 } | 3492 } |
| 3486 | 3493 |
| 3487 // We haven't yet found out if any remote routes are available. | 3494 // We haven't yet found out if any remote routes are available. |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3771 { | 3778 { |
| 3772 visitor->trace(m_client); | 3779 visitor->trace(m_client); |
| 3773 } | 3780 } |
| 3774 | 3781 |
| 3775 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) | 3782 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) |
| 3776 { | 3783 { |
| 3777 visitor->trace(m_client); | 3784 visitor->trace(m_client); |
| 3778 } | 3785 } |
| 3779 | 3786 |
| 3780 } // namespace blink | 3787 } // namespace blink |
| OLD | NEW |