| 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 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 // when used with parameters, e.g. "application/octet-stream;codecs=theora",
is a type that the user agent knows | 244 // when used with parameters, e.g. "application/octet-stream;codecs=theora",
is a type that the user agent knows |
| 245 // it cannot render. | 245 // it cannot render. |
| 246 if (contentMIMEType != "application/octet-stream" || contentTypeCodecs.isEmp
ty()) { | 246 if (contentMIMEType != "application/octet-stream" || contentTypeCodecs.isEmp
ty()) { |
| 247 WebMimeRegistry::SupportsType supported = Platform::current()->mimeRegis
try()->supportsMediaMIMEType(contentMIMEType, contentTypeCodecs); | 247 WebMimeRegistry::SupportsType supported = Platform::current()->mimeRegis
try()->supportsMediaMIMEType(contentMIMEType, contentTypeCodecs); |
| 248 return supported > WebMimeRegistry::IsNotSupported; | 248 return supported > WebMimeRegistry::IsNotSupported; |
| 249 } | 249 } |
| 250 | 250 |
| 251 return false; | 251 return false; |
| 252 } | 252 } |
| 253 | 253 |
| 254 String preloadTypeToString(WebMediaPlayer::Preload preloadType) |
| 255 { |
| 256 switch (preloadType) { |
| 257 case WebMediaPlayer::PreloadNone: |
| 258 return "none"; |
| 259 case WebMediaPlayer::PreloadMetaData: |
| 260 return "metadata"; |
| 261 case WebMediaPlayer::PreloadAuto: |
| 262 return "auto"; |
| 263 } |
| 264 |
| 265 ASSERT_NOT_REACHED(); |
| 266 return String(); |
| 267 } |
| 268 |
| 254 } // anonymous namespace | 269 } // anonymous namespace |
| 255 | 270 |
| 256 void HTMLMediaElement::recordAutoplayMetric(AutoplayMetrics metric) | 271 void HTMLMediaElement::recordAutoplayMetric(AutoplayMetrics metric) |
| 257 { | 272 { |
| 258 DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplayHistogram, ("Blink.MediaEl
ement.Autoplay", NumberOfAutoplayMetrics)); | 273 DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplayHistogram, ("Blink.MediaEl
ement.Autoplay", NumberOfAutoplayMetrics)); |
| 259 autoplayHistogram.count(metric); | 274 autoplayHistogram.count(metric); |
| 260 } | 275 } |
| 261 | 276 |
| 262 WebMimeRegistry::SupportsType HTMLMediaElement::supportsType(const ContentType&
contentType) | 277 WebMimeRegistry::SupportsType HTMLMediaElement::supportsType(const ContentType&
contentType) |
| 263 { | 278 { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 , m_playing(false) | 340 , m_playing(false) |
| 326 , m_shouldDelayLoadEvent(false) | 341 , m_shouldDelayLoadEvent(false) |
| 327 , m_haveFiredLoadedData(false) | 342 , m_haveFiredLoadedData(false) |
| 328 , m_autoplaying(true) | 343 , m_autoplaying(true) |
| 329 , m_muted(false) | 344 , m_muted(false) |
| 330 , m_paused(true) | 345 , m_paused(true) |
| 331 , m_seeking(false) | 346 , m_seeking(false) |
| 332 , m_sentStalledEvent(false) | 347 , m_sentStalledEvent(false) |
| 333 , m_sentEndEvent(false) | 348 , m_sentEndEvent(false) |
| 334 , m_closedCaptionsVisible(false) | 349 , m_closedCaptionsVisible(false) |
| 335 , m_havePreparedToPlay(false) | 350 , m_ignorePreloadNone(false) |
| 336 , m_tracksAreReady(true) | 351 , m_tracksAreReady(true) |
| 337 , m_processingPreferenceChange(false) | 352 , m_processingPreferenceChange(false) |
| 338 , m_remoteRoutesAvailable(false) | 353 , m_remoteRoutesAvailable(false) |
| 339 , m_playingRemotely(false) | 354 , m_playingRemotely(false) |
| 340 , m_isFinalizing(false) | 355 , m_isFinalizing(false) |
| 341 , m_initialPlayWithoutUserGesture(false) | 356 , m_initialPlayWithoutUserGesture(false) |
| 342 , m_autoplayMediaCounted(false) | 357 , m_autoplayMediaCounted(false) |
| 343 , m_inOverlayFullscreenVideo(false) | 358 , m_inOverlayFullscreenVideo(false) |
| 344 , m_audioTracks(AudioTrackList::create(*this)) | 359 , m_audioTracks(AudioTrackList::create(*this)) |
| 345 , m_videoTracks(VideoTrackList::create(*this)) | 360 , m_videoTracks(VideoTrackList::create(*this)) |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 | 479 |
| 465 removeElementFromDocumentMap(this, &oldDocument); | 480 removeElementFromDocumentMap(this, &oldDocument); |
| 466 addElementToDocumentMap(this, &document()); | 481 addElementToDocumentMap(this, &document()); |
| 467 | 482 |
| 468 // FIXME: This is a temporary fix to prevent this object from causing the | 483 // FIXME: This is a temporary fix to prevent this object from causing the |
| 469 // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the | 484 // 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. | 485 // 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 | 486 // A proper fix would provide a mechanism to allow this object to refresh |
| 472 // the MediaPlayer's LocalFrame and FrameLoader references on | 487 // the MediaPlayer's LocalFrame and FrameLoader references on |
| 473 // document changes so that playback can be resumed properly. | 488 // document changes so that playback can be resumed properly. |
| 474 clearMediaPlayer(LoadMediaResource); | 489 m_ignorePreloadNone = false; |
| 475 scheduleDelayedAction(LoadMediaResource); | 490 invokeLoadAlgorithm(); |
| 476 | 491 |
| 477 // Decrement the load event delay count on oldDocument now that m_webMediaPl
ayer has been destroyed | 492 // 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. | 493 // and there is no risk of dispatching a load event from within the destruct
or. |
| 479 oldDocument.decrementLoadEventDelayCount(); | 494 oldDocument.decrementLoadEventDelayCount(); |
| 480 | 495 |
| 481 ActiveDOMObject::didMoveToNewExecutionContext(&document()); | 496 ActiveDOMObject::didMoveToNewExecutionContext(&document()); |
| 482 HTMLElement::didMoveToNewDocument(oldDocument); | 497 HTMLElement::didMoveToNewDocument(oldDocument); |
| 483 } | 498 } |
| 484 | 499 |
| 485 bool HTMLMediaElement::supportsFocus() const | 500 bool HTMLMediaElement::supportsFocus() const |
| 486 { | 501 { |
| 487 if (ownerDocument()->isMediaDocument()) | 502 if (ownerDocument()->isMediaDocument()) |
| 488 return false; | 503 return false; |
| 489 | 504 |
| 490 // If no controls specified, we should still be able to focus the element if
it has tabIndex. | 505 // If no controls specified, we should still be able to focus the element if
it has tabIndex. |
| 491 return shouldShowControls() || HTMLElement::supportsFocus(); | 506 return shouldShowControls() || HTMLElement::supportsFocus(); |
| 492 } | 507 } |
| 493 | 508 |
| 494 bool HTMLMediaElement::isMouseFocusable() const | 509 bool HTMLMediaElement::isMouseFocusable() const |
| 495 { | 510 { |
| 496 return false; | 511 return false; |
| 497 } | 512 } |
| 498 | 513 |
| 499 void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr
ing& oldValue, const AtomicString& value) | 514 void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr
ing& oldValue, const AtomicString& value) |
| 500 { | 515 { |
| 501 if (name == srcAttr) { | 516 if (name == srcAttr) { |
| 502 // Trigger a reload, as long as the 'src' attribute is present. | 517 // Trigger a reload, as long as the 'src' attribute is present. |
| 503 if (!value.isNull()) { | 518 if (!value.isNull()) { |
| 504 clearMediaPlayer(LoadMediaResource); | 519 m_ignorePreloadNone = false; |
| 505 scheduleDelayedAction(LoadMediaResource); | 520 invokeLoadAlgorithm(); |
| 506 } | 521 } |
| 507 } else if (name == controlsAttr) { | 522 } else if (name == controlsAttr) { |
| 508 UseCounter::count(document(), UseCounter::HTMLMediaElementControlsAttrib
ute); | 523 UseCounter::count(document(), UseCounter::HTMLMediaElementControlsAttrib
ute); |
| 509 configureMediaControls(); | 524 configureMediaControls(); |
| 510 } else if (name == preloadAttr) { | 525 } else if (name == preloadAttr) { |
| 511 setPlayerPreload(); | 526 setPlayerPreload(); |
| 512 } else if (name == disableremoteplaybackAttr) { | 527 } else if (name == disableremoteplaybackAttr) { |
| 513 UseCounter::count(document(), UseCounter::DisableRemotePlaybackAttribute
); | 528 UseCounter::count(document(), UseCounter::DisableRemotePlaybackAttribute
); |
| 514 } else { | 529 } else { |
| 515 HTMLElement::parseAttribute(name, oldValue, value); | 530 HTMLElement::parseAttribute(name, oldValue, value); |
| 516 } | 531 } |
| 517 } | 532 } |
| 518 | 533 |
| 519 void HTMLMediaElement::finishParsingChildren() | 534 void HTMLMediaElement::finishParsingChildren() |
| 520 { | 535 { |
| 521 HTMLElement::finishParsingChildren(); | 536 HTMLElement::finishParsingChildren(); |
| 522 | 537 |
| 523 if (Traversal<HTMLTrackElement>::firstChild(*this)) | 538 if (Traversal<HTMLTrackElement>::firstChild(*this)) |
| 524 scheduleDelayedAction(LoadTextTrackResource); | 539 scheduleTextTrackResourceLoad(); |
| 525 } | 540 } |
| 526 | 541 |
| 527 bool HTMLMediaElement::layoutObjectIsNeeded(const ComputedStyle& style) | 542 bool HTMLMediaElement::layoutObjectIsNeeded(const ComputedStyle& style) |
| 528 { | 543 { |
| 529 return shouldShowControls() && HTMLElement::layoutObjectIsNeeded(style); | 544 return shouldShowControls() && HTMLElement::layoutObjectIsNeeded(style); |
| 530 } | 545 } |
| 531 | 546 |
| 532 LayoutObject* HTMLMediaElement::createLayoutObject(const ComputedStyle&) | 547 LayoutObject* HTMLMediaElement::createLayoutObject(const ComputedStyle&) |
| 533 { | 548 { |
| 534 return new LayoutMedia(this); | 549 return new LayoutMedia(this); |
| 535 } | 550 } |
| 536 | 551 |
| 537 Node::InsertionNotificationRequest HTMLMediaElement::insertedInto(ContainerNode*
insertionPoint) | 552 Node::InsertionNotificationRequest HTMLMediaElement::insertedInto(ContainerNode*
insertionPoint) |
| 538 { | 553 { |
| 539 WTF_LOG(Media, "HTMLMediaElement::insertedInto(%p, %p)", this, insertionPoin
t); | 554 WTF_LOG(Media, "HTMLMediaElement::insertedInto(%p, %p)", this, insertionPoin
t); |
| 540 | 555 |
| 541 HTMLElement::insertedInto(insertionPoint); | 556 HTMLElement::insertedInto(insertionPoint); |
| 542 if (insertionPoint->inDocument()) { | 557 if (insertionPoint->inDocument()) { |
| 543 UseCounter::count(document(), UseCounter::HTMLMediaElementInDocument); | 558 UseCounter::count(document(), UseCounter::HTMLMediaElementInDocument); |
| 544 if (!getAttribute(srcAttr).isEmpty() && m_networkState == NETWORK_EMPTY) | 559 if (!getAttribute(srcAttr).isEmpty() && m_networkState == NETWORK_EMPTY)
{ |
| 545 scheduleDelayedAction(LoadMediaResource); | 560 m_ignorePreloadNone = false; |
| 561 invokeLoadAlgorithm(); |
| 562 } |
| 546 } | 563 } |
| 547 | 564 |
| 548 return InsertionShouldCallDidNotifySubtreeInsertions; | 565 return InsertionShouldCallDidNotifySubtreeInsertions; |
| 549 } | 566 } |
| 550 | 567 |
| 551 void HTMLMediaElement::didNotifySubtreeInsertionsToDocument() | 568 void HTMLMediaElement::didNotifySubtreeInsertionsToDocument() |
| 552 { | 569 { |
| 553 configureMediaControls(); | 570 configureMediaControls(); |
| 554 } | 571 } |
| 555 | 572 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 572 if (layoutObject()) | 589 if (layoutObject()) |
| 573 layoutObject()->updateFromElement(); | 590 layoutObject()->updateFromElement(); |
| 574 } | 591 } |
| 575 | 592 |
| 576 void HTMLMediaElement::didRecalcStyle(StyleRecalcChange) | 593 void HTMLMediaElement::didRecalcStyle(StyleRecalcChange) |
| 577 { | 594 { |
| 578 if (layoutObject()) | 595 if (layoutObject()) |
| 579 layoutObject()->updateFromElement(); | 596 layoutObject()->updateFromElement(); |
| 580 } | 597 } |
| 581 | 598 |
| 582 void HTMLMediaElement::scheduleDelayedAction(DelayedActionType actionType) | 599 void HTMLMediaElement::scheduleTextTrackResourceLoad() |
| 583 { | 600 { |
| 584 WTF_LOG(Media, "HTMLMediaElement::scheduleDelayedAction(%p)", this); | 601 WTF_LOG(Media, "HTMLMediaElement::scheduleTextTrackResourceLoad(%p)", this); |
| 585 | 602 |
| 586 if ((actionType & LoadMediaResource) && !(m_pendingActionFlags & LoadMediaRe
source)) { | 603 m_pendingActionFlags |= LoadTextTrackResource; |
| 587 prepareForLoad(); | |
| 588 m_pendingActionFlags |= LoadMediaResource; | |
| 589 } | |
| 590 | |
| 591 if (actionType & LoadTextTrackResource) | |
| 592 m_pendingActionFlags |= LoadTextTrackResource; | |
| 593 | 604 |
| 594 if (!m_loadTimer.isActive()) | 605 if (!m_loadTimer.isActive()) |
| 595 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); | 606 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); |
| 596 } | 607 } |
| 597 | 608 |
| 598 void HTMLMediaElement::scheduleNextSourceChild() | 609 void HTMLMediaElement::scheduleNextSourceChild() |
| 599 { | 610 { |
| 600 // Schedule the timer to try the next <source> element WITHOUT resetting sta
te ala prepareForLoad. | 611 // Schedule the timer to try the next <source> element WITHOUT resetting sta
te ala invokeLoadAlgorithm. |
| 601 m_pendingActionFlags |= LoadMediaResource; | 612 m_pendingActionFlags |= LoadMediaResource; |
| 602 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); | 613 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); |
| 603 } | 614 } |
| 604 | 615 |
| 605 void HTMLMediaElement::scheduleEvent(const AtomicString& eventName) | 616 void HTMLMediaElement::scheduleEvent(const AtomicString& eventName) |
| 606 { | 617 { |
| 607 scheduleEvent(Event::createCancelable(eventName)); | 618 scheduleEvent(Event::createCancelable(eventName)); |
| 608 } | 619 } |
| 609 | 620 |
| 610 void HTMLMediaElement::scheduleEvent(PassRefPtrWillBeRawPtr<Event> event) | 621 void HTMLMediaElement::scheduleEvent(PassRefPtrWillBeRawPtr<Event> event) |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 | 714 |
| 704 if (UserGestureIndicator::processingUserGesture() && m_userGestureRequiredFo
rPlay) { | 715 if (UserGestureIndicator::processingUserGesture() && m_userGestureRequiredFo
rPlay) { |
| 705 recordAutoplayMetric(AutoplayEnabledThroughLoad); | 716 recordAutoplayMetric(AutoplayEnabledThroughLoad); |
| 706 m_userGestureRequiredForPlay = false; | 717 m_userGestureRequiredForPlay = false; |
| 707 // While usergesture-initiated load()s technically count as autoplayed, | 718 // 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 | 719 // they don't feel like such to the users and hence we don't want to |
| 709 // count them for the purposes of metrics. | 720 // count them for the purposes of metrics. |
| 710 m_autoplayMediaCounted = true; | 721 m_autoplayMediaCounted = true; |
| 711 } | 722 } |
| 712 | 723 |
| 713 prepareForLoad(); | 724 m_ignorePreloadNone = true; |
| 714 loadInternal(); | 725 invokeLoadAlgorithm(); |
| 715 prepareToPlay(); | |
| 716 } | 726 } |
| 717 | 727 |
| 718 void HTMLMediaElement::prepareForLoad() | 728 // TODO(srirama.m): Currently m_ignorePreloadNone is reset before calling |
| 729 // invokeLoadAlgorithm() in all places except load(). Move it inside here |
| 730 // once microtask is implemented for "Await a stable state" step |
| 731 // in resource selection algorithm. |
| 732 void HTMLMediaElement::invokeLoadAlgorithm() |
| 719 { | 733 { |
| 720 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this); | 734 WTF_LOG(Media, "HTMLMediaElement::invokeLoadAlgorithm(%p)", this); |
| 721 | 735 |
| 722 // Perform the cleanup required for the resource load algorithm to run. | 736 // Perform the cleanup required for the resource load algorithm to run. |
| 723 stopPeriodicTimers(); | 737 stopPeriodicTimers(); |
| 724 m_loadTimer.stop(); | 738 m_loadTimer.stop(); |
| 725 cancelDeferredLoad(); | 739 cancelDeferredLoad(); |
| 726 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec
essary and set m_pendingActionFlags to 0 here. | 740 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec
essary and set m_pendingActionFlags to 0 here. |
| 727 m_pendingActionFlags &= ~LoadMediaResource; | 741 m_pendingActionFlags &= ~LoadMediaResource; |
| 728 m_sentEndEvent = false; | 742 m_sentEndEvent = false; |
| 729 m_sentStalledEvent = false; | 743 m_sentStalledEvent = false; |
| 730 m_haveFiredLoadedData = false; | 744 m_haveFiredLoadedData = false; |
| 731 m_havePreparedToPlay = false; | |
| 732 m_displayMode = Unknown; | 745 m_displayMode = Unknown; |
| 733 | 746 |
| 734 // 1 - Abort any already-running instance of the resource selection algorith
m for this element. | 747 // 1 - Abort any already-running instance of the resource selection algorith
m for this element. |
| 735 m_loadState = WaitingForSource; | 748 m_loadState = WaitingForSource; |
| 736 m_currentSourceNode = nullptr; | 749 m_currentSourceNode = nullptr; |
| 737 | 750 |
| 738 // 2 - If there are any tasks from the media element's media element event t
ask source in | 751 // 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. | 752 // one of the task queues, then remove those tasks. |
| 740 cancelPendingEventsAndCallbacks(); | 753 cancelPendingEventsAndCallbacks(); |
| 741 | 754 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 785 } | 798 } |
| 786 | 799 |
| 787 // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRat
e attribute. | 800 // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRat
e attribute. |
| 788 setPlaybackRate(defaultPlaybackRate()); | 801 setPlaybackRate(defaultPlaybackRate()); |
| 789 | 802 |
| 790 // 6 - Set the error attribute to null and the autoplaying flag to true. | 803 // 6 - Set the error attribute to null and the autoplaying flag to true. |
| 791 m_error = nullptr; | 804 m_error = nullptr; |
| 792 m_autoplaying = true; | 805 m_autoplaying = true; |
| 793 | 806 |
| 794 // 7 - Invoke the media element's resource selection algorithm. | 807 // 7 - Invoke the media element's resource selection algorithm. |
| 808 invokeResourceSelectionAlgorithm(); |
| 795 | 809 |
| 796 // 8 - Note: Playback of any previously playing media resource for this elem
ent stops. | 810 // 8 - Note: Playback of any previously playing media resource for this elem
ent stops. |
| 811 } |
| 797 | 812 |
| 813 void HTMLMediaElement::invokeResourceSelectionAlgorithm() |
| 814 { |
| 815 WTF_LOG(Media, "HTMLMediaElement::invokeResourceSelectionAlgorithm(%p)", thi
s); |
| 798 // The resource selection algorithm | 816 // The resource selection algorithm |
| 799 // 1 - Set the networkState to NETWORK_NO_SOURCE | 817 // 1 - Set the networkState to NETWORK_NO_SOURCE |
| 800 setNetworkState(NETWORK_NO_SOURCE); | 818 setNetworkState(NETWORK_NO_SOURCE); |
| 801 | 819 |
| 802 // 2 - Asynchronously await a stable state. | 820 // 2 - Set the element's show poster flag to true |
| 821 // TODO(srirama.m): Introduce show poster flag and update it as per spec |
| 803 | 822 |
| 804 m_playedTimeRanges = TimeRanges::create(); | 823 m_playedTimeRanges = TimeRanges::create(); |
| 805 | 824 |
| 806 // FIXME: Investigate whether these can be moved into m_networkState != NETW
ORK_EMPTY block above | 825 // 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. | 826 // so they are closer to the relevant spec steps. |
| 808 m_lastSeekTime = 0; | 827 m_lastSeekTime = 0; |
| 809 m_duration = std::numeric_limits<double>::quiet_NaN(); | 828 m_duration = std::numeric_limits<double>::quiet_NaN(); |
| 810 | 829 |
| 811 // The spec doesn't say to block the load event until we actually run the as
ynchronous section | 830 // 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); | 831 setShouldDelayLoadEvent(true); |
| 815 if (mediaControls()) | 832 if (mediaControls()) |
| 816 mediaControls()->reset(); | 833 mediaControls()->reset(); |
| 834 |
| 835 // 4 - Await a stable state, allowing the task that invoked this algorithm t
o continue |
| 836 // TODO(srirama.m): Remove scheduleNextSourceChild() and post a microtask in
stead. |
| 837 // See http://crbug.com/593289 for more details. |
| 838 scheduleNextSourceChild(); |
| 817 } | 839 } |
| 818 | 840 |
| 819 void HTMLMediaElement::loadInternal() | 841 void HTMLMediaElement::loadInternal() |
| 820 { | 842 { |
| 821 // HTMLMediaElement::textTracksAreReady will need "... the text tracks whose
mode was not in the | 843 // 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". | 844 // disabled state when the element's resource selection algorithm last start
ed". |
| 823 m_textTracksWhenResourceSelectionBegan.clear(); | 845 m_textTracksWhenResourceSelectionBegan.clear(); |
| 824 if (m_textTracks) { | 846 if (m_textTracks) { |
| 825 for (unsigned i = 0; i < m_textTracks->length(); ++i) { | 847 for (unsigned i = 0; i < m_textTracks->length(); ++i) { |
| 826 TextTrack* track = m_textTracks->anonymousIndexedGetter(i); | 848 TextTrack* track = m_textTracks->anonymousIndexedGetter(i); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 969 m_mediaSource = nullptr; | 991 m_mediaSource = nullptr; |
| 970 attemptLoad = false; | 992 attemptLoad = false; |
| 971 } | 993 } |
| 972 } | 994 } |
| 973 } | 995 } |
| 974 } | 996 } |
| 975 | 997 |
| 976 if (attemptLoad && canLoadURL(url, contentType)) { | 998 if (attemptLoad && canLoadURL(url, contentType)) { |
| 977 ASSERT(!webMediaPlayer()); | 999 ASSERT(!webMediaPlayer()); |
| 978 | 1000 |
| 979 if (!m_havePreparedToPlay && effectivePreloadType() == WebMediaPlayer::P
reloadNone) { | 1001 if (effectivePreloadType() == WebMediaPlayer::PreloadNone) { |
| 980 WTF_LOG(Media, "HTMLMediaElement::loadResource(%p) : Delaying load b
ecause preload == 'none'", this); | 1002 WTF_LOG(Media, "HTMLMediaElement::loadResource(%p) : Delaying load b
ecause preload == 'none'", this); |
| 981 deferLoad(); | 1003 deferLoad(); |
| 982 } else { | 1004 } else { |
| 983 startPlayerLoad(); | 1005 startPlayerLoad(); |
| 984 } | 1006 } |
| 985 } else { | 1007 } else { |
| 986 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); | 1008 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); |
| 987 } | 1009 } |
| 988 | 1010 |
| 989 // If there is no poster to display, allow the media engine to render video
frames as soon as | 1011 // If there is no poster to display, allow the media engine to render video
frames as soon as |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1047 // This handles any transition to or from fullscreen overlay mode. | 1069 // This handles any transition to or from fullscreen overlay mode. |
| 1048 frame->chromeClient().enterFullScreenForElement(this); | 1070 frame->chromeClient().enterFullScreenForElement(this); |
| 1049 } | 1071 } |
| 1050 } | 1072 } |
| 1051 | 1073 |
| 1052 void HTMLMediaElement::setPlayerPreload() | 1074 void HTMLMediaElement::setPlayerPreload() |
| 1053 { | 1075 { |
| 1054 if (m_webMediaPlayer) | 1076 if (m_webMediaPlayer) |
| 1055 m_webMediaPlayer->setPreload(effectivePreloadType()); | 1077 m_webMediaPlayer->setPreload(effectivePreloadType()); |
| 1056 | 1078 |
| 1057 if (loadIsDeferred() && preloadType() != WebMediaPlayer::PreloadNone) | 1079 if (loadIsDeferred() && effectivePreloadType() != WebMediaPlayer::PreloadNon
e) |
| 1058 startDeferredLoad(); | 1080 startDeferredLoad(); |
| 1059 } | 1081 } |
| 1060 | 1082 |
| 1061 bool HTMLMediaElement::loadIsDeferred() const | 1083 bool HTMLMediaElement::loadIsDeferred() const |
| 1062 { | 1084 { |
| 1063 return m_deferredLoadState != NotDeferred; | 1085 return m_deferredLoadState != NotDeferred; |
| 1064 } | 1086 } |
| 1065 | 1087 |
| 1066 void HTMLMediaElement::deferLoad() | 1088 void HTMLMediaElement::deferLoad() |
| 1067 { | 1089 { |
| (...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1600 if (!m_playedTimeRanges) | 1622 if (!m_playedTimeRanges) |
| 1601 m_playedTimeRanges = TimeRanges::create(); | 1623 m_playedTimeRanges = TimeRanges::create(); |
| 1602 m_playedTimeRanges->add(start, end); | 1624 m_playedTimeRanges->add(start, end); |
| 1603 } | 1625 } |
| 1604 | 1626 |
| 1605 bool HTMLMediaElement::supportsSave() const | 1627 bool HTMLMediaElement::supportsSave() const |
| 1606 { | 1628 { |
| 1607 return webMediaPlayer() && webMediaPlayer()->supportsSave(); | 1629 return webMediaPlayer() && webMediaPlayer()->supportsSave(); |
| 1608 } | 1630 } |
| 1609 | 1631 |
| 1610 void HTMLMediaElement::prepareToPlay() | 1632 void HTMLMediaElement::setIgnorePreloadNone() |
| 1611 { | 1633 { |
| 1612 WTF_LOG(Media, "HTMLMediaElement::prepareToPlay(%p)", this); | 1634 WTF_LOG(Media, "HTMLMediaElement::setIgnorePreloadNone(%p)", this); |
| 1613 if (m_havePreparedToPlay) | 1635 m_ignorePreloadNone = true; |
| 1614 return; | 1636 setPlayerPreload(); |
| 1615 m_havePreparedToPlay = true; | |
| 1616 | |
| 1617 if (loadIsDeferred()) | |
| 1618 startDeferredLoad(); | |
| 1619 } | 1637 } |
| 1620 | 1638 |
| 1621 void HTMLMediaElement::seek(double time) | 1639 void HTMLMediaElement::seek(double time) |
| 1622 { | 1640 { |
| 1623 WTF_LOG(Media, "HTMLMediaElement::seek(%p, %f)", this, time); | 1641 WTF_LOG(Media, "HTMLMediaElement::seek(%p, %f)", this, time); |
| 1624 | 1642 |
| 1625 // 2 - If the media element's readyState is HAVE_NOTHING, abort these steps. | 1643 // 2 - If the media element's readyState is HAVE_NOTHING, abort these steps. |
| 1626 if (m_readyState == HAVE_NOTHING) | 1644 if (m_readyState == HAVE_NOTHING) |
| 1627 return; | 1645 return; |
| 1628 | 1646 |
| 1629 // If the media engine has been told to postpone loading data, let it go ahe
ad now. | 1647 // Ignore preload none and start load if necessary. |
| 1630 if (preloadType() < WebMediaPlayer::PreloadAuto && m_readyState < HAVE_FUTUR
E_DATA) | 1648 setIgnorePreloadNone(); |
| 1631 prepareToPlay(); | |
| 1632 | 1649 |
| 1633 // Get the current time before setting m_seeking, m_lastSeekTime is returned
once it is set. | 1650 // Get the current time before setting m_seeking, m_lastSeekTime is returned
once it is set. |
| 1634 refreshCachedTime(); | 1651 refreshCachedTime(); |
| 1635 // This is needed to avoid getting default playback start position from curr
entTime(). | 1652 // This is needed to avoid getting default playback start position from curr
entTime(). |
| 1636 double now = m_cachedTime; | 1653 double now = m_cachedTime; |
| 1637 | 1654 |
| 1638 // 3 - If the element's seeking IDL attribute is true, then another instance
of this algorithm is | 1655 // 3 - If the element's seeking IDL attribute is true, then another instance
of this algorithm is |
| 1639 // already running. Abort that other instance of the algorithm without waiti
ng for the step that | 1656 // already running. Abort that other instance of the algorithm without waiti
ng for the step that |
| 1640 // it is running to complete. | 1657 // it is running to complete. |
| 1641 // Nothing specific to be done here. | 1658 // Nothing specific to be done here. |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1881 } | 1898 } |
| 1882 | 1899 |
| 1883 return true; | 1900 return true; |
| 1884 } | 1901 } |
| 1885 | 1902 |
| 1886 return false; | 1903 return false; |
| 1887 } | 1904 } |
| 1888 | 1905 |
| 1889 String HTMLMediaElement::preload() const | 1906 String HTMLMediaElement::preload() const |
| 1890 { | 1907 { |
| 1891 switch (preloadType()) { | 1908 return preloadTypeToString(preloadType()); |
| 1892 case WebMediaPlayer::PreloadNone: | |
| 1893 return "none"; | |
| 1894 case WebMediaPlayer::PreloadMetaData: | |
| 1895 return "metadata"; | |
| 1896 case WebMediaPlayer::PreloadAuto: | |
| 1897 return "auto"; | |
| 1898 } | |
| 1899 | |
| 1900 ASSERT_NOT_REACHED(); | |
| 1901 return String(); | |
| 1902 } | 1909 } |
| 1903 | 1910 |
| 1904 void HTMLMediaElement::setPreload(const AtomicString& preload) | 1911 void HTMLMediaElement::setPreload(const AtomicString& preload) |
| 1905 { | 1912 { |
| 1906 WTF_LOG(Media, "HTMLMediaElement::setPreload(%p, %s)", this, preload.utf8().
data()); | 1913 WTF_LOG(Media, "HTMLMediaElement::setPreload(%p, %s)", this, preload.utf8().
data()); |
| 1907 setAttribute(preloadAttr, preload); | 1914 setAttribute(preloadAttr, preload); |
| 1908 } | 1915 } |
| 1909 | 1916 |
| 1910 WebMediaPlayer::Preload HTMLMediaElement::preloadType() const | 1917 WebMediaPlayer::Preload HTMLMediaElement::preloadType() const |
| 1911 { | 1918 { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1935 | 1942 |
| 1936 // The spec does not define an invalid value default: | 1943 // The spec does not define an invalid value default: |
| 1937 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=28950 | 1944 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=28950 |
| 1938 | 1945 |
| 1939 // TODO(philipj): Try to make "metadata" the default preload state: | 1946 // TODO(philipj): Try to make "metadata" the default preload state: |
| 1940 // https://crbug.com/310450 | 1947 // https://crbug.com/310450 |
| 1941 UseCounter::count(document(), UseCounter::HTMLMediaElementPreloadDefault); | 1948 UseCounter::count(document(), UseCounter::HTMLMediaElementPreloadDefault); |
| 1942 return WebMediaPlayer::PreloadAuto; | 1949 return WebMediaPlayer::PreloadAuto; |
| 1943 } | 1950 } |
| 1944 | 1951 |
| 1952 String HTMLMediaElement::effectivePreload() const |
| 1953 { |
| 1954 return preloadTypeToString(effectivePreloadType()); |
| 1955 } |
| 1956 |
| 1945 WebMediaPlayer::Preload HTMLMediaElement::effectivePreloadType() const | 1957 WebMediaPlayer::Preload HTMLMediaElement::effectivePreloadType() const |
| 1946 { | 1958 { |
| 1947 return autoplay() ? WebMediaPlayer::PreloadAuto : preloadType(); | 1959 if (autoplay()) |
| 1960 return WebMediaPlayer::PreloadAuto; |
| 1961 |
| 1962 WebMediaPlayer::Preload preload = preloadType(); |
| 1963 if (m_ignorePreloadNone && preload == WebMediaPlayer::PreloadNone) |
| 1964 return WebMediaPlayer::PreloadMetaData; |
| 1965 |
| 1966 return preload; |
| 1948 } | 1967 } |
| 1949 | 1968 |
| 1950 ScriptPromise HTMLMediaElement::playForBindings(ScriptState* scriptState) | 1969 ScriptPromise HTMLMediaElement::playForBindings(ScriptState* scriptState) |
| 1951 { | 1970 { |
| 1952 Nullable<ExceptionCode> code = play(); | 1971 Nullable<ExceptionCode> code = play(); |
| 1953 if (!code.isNull()) { | 1972 if (!code.isNull()) { |
| 1954 String message; | 1973 String message; |
| 1955 switch (code.get()) { | 1974 switch (code.get()) { |
| 1956 case NotAllowedError: | 1975 case NotAllowedError: |
| 1957 message = "play() can only be initiated by a user gesture."; | 1976 message = "play() can only be initiated by a user gesture."; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2009 WTF_LOG(Media, "HTMLMediaElement::playInternal(%p)", this); | 2028 WTF_LOG(Media, "HTMLMediaElement::playInternal(%p)", this); |
| 2010 | 2029 |
| 2011 // Always return the buffering strategy to normal when not paused, | 2030 // Always return the buffering strategy to normal when not paused, |
| 2012 // regardless of the cause. (In contrast with aggressive buffering which is | 2031 // regardless of the cause. (In contrast with aggressive buffering which is |
| 2013 // only enabled by pause(), not pauseInternal().) | 2032 // only enabled by pause(), not pauseInternal().) |
| 2014 if (webMediaPlayer()) | 2033 if (webMediaPlayer()) |
| 2015 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy
::Normal); | 2034 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy
::Normal); |
| 2016 | 2035 |
| 2017 // 4.8.10.9. Playing the media resource | 2036 // 4.8.10.9. Playing the media resource |
| 2018 if (m_networkState == NETWORK_EMPTY) | 2037 if (m_networkState == NETWORK_EMPTY) |
| 2019 scheduleDelayedAction(LoadMediaResource); | 2038 invokeResourceSelectionAlgorithm(); |
| 2020 | 2039 |
| 2021 // Generally "ended" and "looping" are exclusive. Here, the loop attribute | 2040 // Generally "ended" and "looping" are exclusive. Here, the loop attribute |
| 2022 // is ignored to seek back to start in case loop was set after playback | 2041 // is ignored to seek back to start in case loop was set after playback |
| 2023 // ended. See http://crbug.com/364442 | 2042 // ended. See http://crbug.com/364442 |
| 2024 if (endedPlayback(LoopCondition::Ignored)) | 2043 if (endedPlayback(LoopCondition::Ignored)) |
| 2025 seek(0); | 2044 seek(0); |
| 2026 | 2045 |
| 2027 if (m_paused) { | 2046 if (m_paused) { |
| 2028 m_paused = false; | 2047 m_paused = false; |
| 2029 invalidateCachedTime(); | 2048 invalidateCachedTime(); |
| 2030 scheduleEvent(EventTypeNames::play); | 2049 scheduleEvent(EventTypeNames::play); |
| 2031 | 2050 |
| 2032 if (m_readyState <= HAVE_CURRENT_DATA) | 2051 if (m_readyState <= HAVE_CURRENT_DATA) |
| 2033 scheduleEvent(EventTypeNames::waiting); | 2052 scheduleEvent(EventTypeNames::waiting); |
| 2034 else if (m_readyState >= HAVE_FUTURE_DATA) | 2053 else if (m_readyState >= HAVE_FUTURE_DATA) |
| 2035 scheduleNotifyPlaying(); | 2054 scheduleNotifyPlaying(); |
| 2036 } else if (m_readyState >= HAVE_FUTURE_DATA) { | 2055 } else if (m_readyState >= HAVE_FUTURE_DATA) { |
| 2037 scheduleResolvePlayPromises(); | 2056 scheduleResolvePlayPromises(); |
| 2038 } | 2057 } |
| 2039 | 2058 |
| 2040 m_autoplaying = false; | 2059 m_autoplaying = false; |
| 2041 | 2060 |
| 2061 setIgnorePreloadNone(); |
| 2042 updatePlayState(); | 2062 updatePlayState(); |
| 2043 } | 2063 } |
| 2044 | 2064 |
| 2045 void HTMLMediaElement::autoplayMediaEncountered() | 2065 void HTMLMediaElement::autoplayMediaEncountered() |
| 2046 { | 2066 { |
| 2047 if (!m_autoplayMediaCounted) { | 2067 if (!m_autoplayMediaCounted) { |
| 2048 m_autoplayMediaCounted = true; | 2068 m_autoplayMediaCounted = true; |
| 2049 recordAutoplayMetric(AutoplayMediaFound); | 2069 recordAutoplayMetric(AutoplayMediaFound); |
| 2050 | 2070 |
| 2051 if (!m_userGestureRequiredForPlay) | 2071 if (!m_userGestureRequiredForPlay) |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2072 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy
::Aggressive); | 2092 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy
::Aggressive); |
| 2073 | 2093 |
| 2074 pauseInternal(); | 2094 pauseInternal(); |
| 2075 } | 2095 } |
| 2076 | 2096 |
| 2077 void HTMLMediaElement::pauseInternal() | 2097 void HTMLMediaElement::pauseInternal() |
| 2078 { | 2098 { |
| 2079 WTF_LOG(Media, "HTMLMediaElement::pauseInternal(%p)", this); | 2099 WTF_LOG(Media, "HTMLMediaElement::pauseInternal(%p)", this); |
| 2080 | 2100 |
| 2081 if (m_networkState == NETWORK_EMPTY) | 2101 if (m_networkState == NETWORK_EMPTY) |
| 2082 scheduleDelayedAction(LoadMediaResource); | 2102 invokeResourceSelectionAlgorithm(); |
| 2083 | 2103 |
| 2084 m_autoplayHelper.pauseMethodCalled(); | 2104 m_autoplayHelper.pauseMethodCalled(); |
| 2085 | 2105 |
| 2086 m_autoplaying = false; | 2106 m_autoplaying = false; |
| 2087 | 2107 |
| 2088 if (!m_paused) { | 2108 if (!m_paused) { |
| 2089 recordMetricsIfPausing(); | 2109 recordMetricsIfPausing(); |
| 2090 | 2110 |
| 2091 m_paused = true; | 2111 m_paused = true; |
| 2092 scheduleTimeupdateEvent(false); | 2112 scheduleTimeupdateEvent(false); |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2408 // 5. Populate the new text track's list of cues with the cues parsed so far
, folllowing the guidelines for exposing | 2428 // 5. Populate the new text track's list of cues with the cues parsed so far
, folllowing the guidelines for exposing |
| 2409 // cues, and begin updating it dynamically as necessary. | 2429 // cues, and begin updating it dynamically as necessary. |
| 2410 // - Thess are all done by the media engine. | 2430 // - Thess are all done by the media engine. |
| 2411 | 2431 |
| 2412 // 6. Set the new text track's readiness state to loaded. | 2432 // 6. Set the new text track's readiness state to loaded. |
| 2413 textTrack->setReadinessState(TextTrack::Loaded); | 2433 textTrack->setReadinessState(TextTrack::Loaded); |
| 2414 | 2434 |
| 2415 // 7. Set the new text track's mode to the mode consistent with the user's p
references and the requirements of | 2435 // 7. Set the new text track's mode to the mode consistent with the user's p
references and the requirements of |
| 2416 // the relevant specification for the data. | 2436 // the relevant specification for the data. |
| 2417 // - This will happen in honorUserPreferencesForAutomaticTextTrackSelection
() | 2437 // - This will happen in honorUserPreferencesForAutomaticTextTrackSelection
() |
| 2418 scheduleDelayedAction(LoadTextTrackResource); | 2438 scheduleTextTrackResourceLoad(); |
| 2419 | 2439 |
| 2420 // 8. Add the new text track to the media element's list of text tracks. | 2440 // 8. Add the new text track to the media element's list of text tracks. |
| 2421 // 9. Fire an event with the name addtrack, that does not bubble and is not
cancelable, and that uses the TrackEvent | 2441 // 9. Fire an event with the name addtrack, that does not bubble and is not
cancelable, and that uses the TrackEvent |
| 2422 // interface, with the track attribute initialized to the text track's TextT
rack object, at the media element's | 2442 // interface, with the track attribute initialized to the text track's TextT
rack object, at the media element's |
| 2423 // textTracks attribute's TextTrackList object. | 2443 // textTracks attribute's TextTrackList object. |
| 2424 addTextTrack(textTrack); | 2444 addTextTrack(textTrack); |
| 2425 } | 2445 } |
| 2426 | 2446 |
| 2427 void HTMLMediaElement::removeTextTrack(WebInbandTextTrack* webTrack) | 2447 void HTMLMediaElement::removeTextTrack(WebInbandTextTrack* webTrack) |
| 2428 { | 2448 { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2528 // media element's list of text tracks ... [continues in TextTrackList::appe
nd] | 2548 // media element's list of text tracks ... [continues in TextTrackList::appe
nd] |
| 2529 TextTrack* textTrack = trackElement->track(); | 2549 TextTrack* textTrack = trackElement->track(); |
| 2530 if (!textTrack) | 2550 if (!textTrack) |
| 2531 return; | 2551 return; |
| 2532 | 2552 |
| 2533 addTextTrack(textTrack); | 2553 addTextTrack(textTrack); |
| 2534 | 2554 |
| 2535 // Do not schedule the track loading until parsing finishes so we don't star
t before all tracks | 2555 // Do not schedule the track loading until parsing finishes so we don't star
t before all tracks |
| 2536 // in the markup have been added. | 2556 // in the markup have been added. |
| 2537 if (isFinishedParsingChildren()) | 2557 if (isFinishedParsingChildren()) |
| 2538 scheduleDelayedAction(LoadTextTrackResource); | 2558 scheduleTextTrackResourceLoad(); |
| 2539 } | 2559 } |
| 2540 | 2560 |
| 2541 void HTMLMediaElement::didRemoveTrackElement(HTMLTrackElement* trackElement) | 2561 void HTMLMediaElement::didRemoveTrackElement(HTMLTrackElement* trackElement) |
| 2542 { | 2562 { |
| 2543 #if !LOG_DISABLED | 2563 #if !LOG_DISABLED |
| 2544 KURL url = trackElement->getNonEmptyURLAttribute(srcAttr); | 2564 KURL url = trackElement->getNonEmptyURLAttribute(srcAttr); |
| 2545 WTF_LOG(Media, "HTMLMediaElement::didRemoveTrackElement(%p) - 'src' is %s",
this, urlForLoggingMedia(url).utf8().data()); | 2565 WTF_LOG(Media, "HTMLMediaElement::didRemoveTrackElement(%p) - 'src' is %s",
this, urlForLoggingMedia(url).utf8().data()); |
| 2546 #endif | 2566 #endif |
| 2547 | 2567 |
| 2548 TextTrack* textTrack = trackElement->track(); | 2568 TextTrack* textTrack = trackElement->track(); |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2713 #endif | 2733 #endif |
| 2714 | 2734 |
| 2715 // We should only consider a <source> element when there is not src attribut
e at all. | 2735 // We should only consider a <source> element when there is not src attribut
e at all. |
| 2716 if (fastHasAttribute(srcAttr)) | 2736 if (fastHasAttribute(srcAttr)) |
| 2717 return; | 2737 return; |
| 2718 | 2738 |
| 2719 // 4.8.8 - If a source element is inserted as a child of a media element tha
t has no src | 2739 // 4.8.8 - If a source element is inserted as a child of a media element tha
t has no src |
| 2720 // attribute and whose networkState has the value NETWORK_EMPTY, the user ag
ent must invoke | 2740 // attribute and whose networkState has the value NETWORK_EMPTY, the user ag
ent must invoke |
| 2721 // the media element's resource selection algorithm. | 2741 // the media element's resource selection algorithm. |
| 2722 if (getNetworkState() == HTMLMediaElement::NETWORK_EMPTY) { | 2742 if (getNetworkState() == HTMLMediaElement::NETWORK_EMPTY) { |
| 2723 scheduleDelayedAction(LoadMediaResource); | 2743 invokeResourceSelectionAlgorithm(); |
| 2744 // Ignore current |m_nextChildNodeToConsider| and consider |source|. |
| 2724 m_nextChildNodeToConsider = source; | 2745 m_nextChildNodeToConsider = source; |
| 2725 return; | 2746 return; |
| 2726 } | 2747 } |
| 2727 | 2748 |
| 2728 if (m_currentSourceNode && source == m_currentSourceNode->nextSibling()) { | 2749 if (m_currentSourceNode && source == m_currentSourceNode->nextSibling()) { |
| 2729 WTF_LOG(Media, "HTMLMediaElement::sourceWasAdded(%p) - <source> inserted
immediately after current source", this); | 2750 WTF_LOG(Media, "HTMLMediaElement::sourceWasAdded(%p) - <source> inserted
immediately after current source", this); |
| 2751 // Ignore current |m_nextChildNodeToConsider| and consider |source|. |
| 2730 m_nextChildNodeToConsider = source; | 2752 m_nextChildNodeToConsider = source; |
| 2731 return; | 2753 return; |
| 2732 } | 2754 } |
| 2733 | 2755 |
| 2756 // Consider current |m_nextChildNodeToConsider| as it is already in the midd
le of processing. |
| 2734 if (m_nextChildNodeToConsider) | 2757 if (m_nextChildNodeToConsider) |
| 2735 return; | 2758 return; |
| 2736 | 2759 |
| 2737 if (m_loadState != WaitingForSource) | 2760 if (m_loadState != WaitingForSource) |
| 2738 return; | 2761 return; |
| 2739 | 2762 |
| 2740 // 4.8.9.5, resource selection algorithm, source elements section: | 2763 // 4.8.9.5, resource selection algorithm, source elements section: |
| 2741 // 21. Wait until the node after pointer is a node other than the end of the
list. (This step might wait forever.) | 2764 // 21. Wait until the node after pointer is a node other than the end of the
list. (This step might wait forever.) |
| 2742 // 22. Asynchronously await a stable state... | 2765 // 22. Asynchronously await a stable state... |
| 2743 // 23. Set the element's delaying-the-load-event flag back to true (this del
ays the load event again, in case | 2766 // 23. Set the element's delaying-the-load-event flag back to true (this del
ays the load event again, in case |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3043 } | 3066 } |
| 3044 | 3067 |
| 3045 refreshCachedTime(); | 3068 refreshCachedTime(); |
| 3046 | 3069 |
| 3047 m_playbackProgressTimer.stop(); | 3070 m_playbackProgressTimer.stop(); |
| 3048 m_playing = false; | 3071 m_playing = false; |
| 3049 double time = currentTime(); | 3072 double time = currentTime(); |
| 3050 if (time > m_lastSeekTime) | 3073 if (time > m_lastSeekTime) |
| 3051 addPlayedRange(m_lastSeekTime, time); | 3074 addPlayedRange(m_lastSeekTime, time); |
| 3052 | 3075 |
| 3053 if (couldPlayIfEnoughData()) | |
| 3054 prepareToPlay(); | |
| 3055 | |
| 3056 if (mediaControls()) | 3076 if (mediaControls()) |
| 3057 mediaControls()->playbackStopped(); | 3077 mediaControls()->playbackStopped(); |
| 3058 } | 3078 } |
| 3059 | 3079 |
| 3060 if (layoutObject()) | 3080 if (layoutObject()) |
| 3061 layoutObject()->updateFromElement(); | 3081 layoutObject()->updateFromElement(); |
| 3062 } | 3082 } |
| 3063 | 3083 |
| 3064 void HTMLMediaElement::stopPeriodicTimers() | 3084 void HTMLMediaElement::stopPeriodicTimers() |
| 3065 { | 3085 { |
| 3066 m_progressEventTimer.stop(); | 3086 m_progressEventTimer.stop(); |
| 3067 m_playbackProgressTimer.stop(); | 3087 m_playbackProgressTimer.stop(); |
| 3068 } | 3088 } |
| 3069 | 3089 |
| 3070 void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClientWithoutLockin
g() | 3090 void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClientWithoutLockin
g() |
| 3071 { | 3091 { |
| 3072 audioSourceProvider().setClient(nullptr); | 3092 audioSourceProvider().setClient(nullptr); |
| 3073 if (m_webMediaPlayer) { | 3093 if (m_webMediaPlayer) { |
| 3074 m_audioSourceProvider.wrap(nullptr); | 3094 m_audioSourceProvider.wrap(nullptr); |
| 3075 m_webMediaPlayer.clear(); | 3095 m_webMediaPlayer.clear(); |
| 3076 } | 3096 } |
| 3077 } | 3097 } |
| 3078 | 3098 |
| 3079 void HTMLMediaElement::clearMediaPlayer(int flags) | 3099 void HTMLMediaElement::clearMediaPlayer() |
| 3080 { | 3100 { |
| 3081 forgetResourceSpecificTracks(); | 3101 forgetResourceSpecificTracks(); |
| 3082 | 3102 |
| 3083 closeMediaSource(); | 3103 closeMediaSource(); |
| 3084 | 3104 |
| 3085 cancelDeferredLoad(); | 3105 cancelDeferredLoad(); |
| 3086 | 3106 |
| 3087 { | 3107 { |
| 3088 AudioSourceProviderClientLockScope scope(*this); | 3108 AudioSourceProviderClientLockScope scope(*this); |
| 3089 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); | 3109 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); |
| 3090 } | 3110 } |
| 3091 | 3111 |
| 3092 stopPeriodicTimers(); | 3112 stopPeriodicTimers(); |
| 3093 m_loadTimer.stop(); | 3113 m_loadTimer.stop(); |
| 3094 | 3114 |
| 3095 m_pendingActionFlags &= ~flags; | 3115 m_pendingActionFlags = 0; |
| 3096 m_loadState = WaitingForSource; | 3116 m_loadState = WaitingForSource; |
| 3097 | 3117 |
| 3098 // We can't cast if we don't have a media player. | 3118 // We can't cast if we don't have a media player. |
| 3099 m_remoteRoutesAvailable = false; | 3119 m_remoteRoutesAvailable = false; |
| 3100 m_playingRemotely = false; | 3120 m_playingRemotely = false; |
| 3101 if (mediaControls()) | 3121 if (mediaControls()) |
| 3102 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); | 3122 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); |
| 3103 | 3123 |
| 3104 if (layoutObject()) | 3124 if (layoutObject()) |
| 3105 layoutObject()->setShouldDoFullPaintInvalidation(); | 3125 layoutObject()->setShouldDoFullPaintInvalidation(); |
| 3106 } | 3126 } |
| 3107 | 3127 |
| 3108 void HTMLMediaElement::stop() | 3128 void HTMLMediaElement::stop() |
| 3109 { | 3129 { |
| 3110 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); | 3130 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); |
| 3111 | 3131 |
| 3112 recordMetricsIfPausing(); | 3132 recordMetricsIfPausing(); |
| 3113 | 3133 |
| 3114 // Close the async event queue so that no events are enqueued. | 3134 // Close the async event queue so that no events are enqueued. |
| 3115 cancelPendingEventsAndCallbacks(); | 3135 cancelPendingEventsAndCallbacks(); |
| 3116 m_asyncEventQueue->close(); | 3136 m_asyncEventQueue->close(); |
| 3117 | 3137 |
| 3118 // Stop the playback without generating events | 3138 // Clear everything in the Media Element |
| 3119 clearMediaPlayer(-1); | 3139 clearMediaPlayer(); |
| 3120 m_readyState = HAVE_NOTHING; | 3140 m_readyState = HAVE_NOTHING; |
| 3121 m_readyStateMaximum = HAVE_NOTHING; | 3141 m_readyStateMaximum = HAVE_NOTHING; |
| 3122 setNetworkState(NETWORK_EMPTY); | 3142 setNetworkState(NETWORK_EMPTY); |
| 3123 setShouldDelayLoadEvent(false); | 3143 setShouldDelayLoadEvent(false); |
| 3124 m_currentSourceNode = nullptr; | 3144 m_currentSourceNode = nullptr; |
| 3125 invalidateCachedTime(); | 3145 invalidateCachedTime(); |
| 3126 cueTimeline().updateActiveCues(0); | 3146 cueTimeline().updateActiveCues(0); |
| 3127 m_playing = false; | 3147 m_playing = false; |
| 3128 m_paused = true; | 3148 m_paused = true; |
| 3129 m_seeking = false; | 3149 m_seeking = false; |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3480 } | 3500 } |
| 3481 | 3501 |
| 3482 void* HTMLMediaElement::preDispatchEventHandler(Event* event) | 3502 void* HTMLMediaElement::preDispatchEventHandler(Event* event) |
| 3483 { | 3503 { |
| 3484 if (event && event->type() == EventTypeNames::webkitfullscreenchange) | 3504 if (event && event->type() == EventTypeNames::webkitfullscreenchange) |
| 3485 configureMediaControls(); | 3505 configureMediaControls(); |
| 3486 | 3506 |
| 3487 return nullptr; | 3507 return nullptr; |
| 3488 } | 3508 } |
| 3489 | 3509 |
| 3490 // TODO(srirama.m): Refactor this and clearMediaPlayer to the extent possible. | 3510 // TODO(srirama.m): Merge it to resetMediaElement if possible and remove it. |
| 3491 void HTMLMediaElement::resetMediaPlayerAndMediaSource() | 3511 void HTMLMediaElement::resetMediaPlayerAndMediaSource() |
| 3492 { | 3512 { |
| 3493 closeMediaSource(); | 3513 closeMediaSource(); |
| 3494 | 3514 |
| 3495 { | 3515 { |
| 3496 AudioSourceProviderClientLockScope scope(*this); | 3516 AudioSourceProviderClientLockScope scope(*this); |
| 3497 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); | 3517 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); |
| 3498 } | 3518 } |
| 3499 | 3519 |
| 3500 // We haven't yet found out if any remote routes are available. | 3520 // 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... |
| 3784 { | 3804 { |
| 3785 visitor->trace(m_client); | 3805 visitor->trace(m_client); |
| 3786 } | 3806 } |
| 3787 | 3807 |
| 3788 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) | 3808 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) |
| 3789 { | 3809 { |
| 3790 visitor->trace(m_client); | 3810 visitor->trace(m_client); |
| 3791 } | 3811 } |
| 3792 | 3812 |
| 3793 } // namespace blink | 3813 } // namespace blink |
| OLD | NEW |