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

Side by Side Diff: third_party/WebKit/Source/core/html/HTMLMediaElement.cpp

Issue 1522463003: Refactor resource load and resource selection algorithms as per spec (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added tests using internals.idl Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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 m_ignorePreloadNone = false;
475 scheduleDelayedAction(LoadMediaResource); 475 invokeLoadAlgorithm();
476 476
477 // Decrement the load event delay count on oldDocument now that m_webMediaPl ayer has been destroyed 477 // Decrement the load event delay count on oldDocument now that m_webMediaPl ayer has been destroyed
478 // and there is no risk of dispatching a load event from within the destruct or. 478 // and there is no risk of dispatching a load event from within the destruct or.
479 oldDocument.decrementLoadEventDelayCount(); 479 oldDocument.decrementLoadEventDelayCount();
480 480
481 ActiveDOMObject::didMoveToNewExecutionContext(&document()); 481 ActiveDOMObject::didMoveToNewExecutionContext(&document());
482 HTMLElement::didMoveToNewDocument(oldDocument); 482 HTMLElement::didMoveToNewDocument(oldDocument);
483 } 483 }
484 484
485 bool HTMLMediaElement::supportsFocus() const 485 bool HTMLMediaElement::supportsFocus() const
486 { 486 {
487 if (ownerDocument()->isMediaDocument()) 487 if (ownerDocument()->isMediaDocument())
488 return false; 488 return false;
489 489
490 // If no controls specified, we should still be able to focus the element if it has tabIndex. 490 // If no controls specified, we should still be able to focus the element if it has tabIndex.
491 return shouldShowControls() || HTMLElement::supportsFocus(); 491 return shouldShowControls() || HTMLElement::supportsFocus();
492 } 492 }
493 493
494 bool HTMLMediaElement::isMouseFocusable() const 494 bool HTMLMediaElement::isMouseFocusable() const
495 { 495 {
496 return false; 496 return false;
497 } 497 }
498 498
499 void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& oldValue, const AtomicString& value) 499 void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& oldValue, const AtomicString& value)
500 { 500 {
501 if (name == srcAttr) { 501 if (name == srcAttr) {
502 // Trigger a reload, as long as the 'src' attribute is present. 502 // Trigger a reload, as long as the 'src' attribute is present.
503 if (!value.isNull()) { 503 if (!value.isNull()) {
504 clearMediaPlayer(LoadMediaResource); 504 m_ignorePreloadNone = false;
505 scheduleDelayedAction(LoadMediaResource); 505 invokeLoadAlgorithm();
506 } 506 }
507 } else if (name == controlsAttr) { 507 } else if (name == controlsAttr) {
508 UseCounter::count(document(), UseCounter::HTMLMediaElementControlsAttrib ute); 508 UseCounter::count(document(), UseCounter::HTMLMediaElementControlsAttrib ute);
509 configureMediaControls(); 509 configureMediaControls();
510 } else if (name == preloadAttr) { 510 } else if (name == preloadAttr) {
511 setPlayerPreload(); 511 setPlayerPreload();
512 } else if (name == disableremoteplaybackAttr) { 512 } else if (name == disableremoteplaybackAttr) {
513 UseCounter::count(document(), UseCounter::DisableRemotePlaybackAttribute ); 513 UseCounter::count(document(), UseCounter::DisableRemotePlaybackAttribute );
514 } else { 514 } else {
515 HTMLElement::parseAttribute(name, oldValue, value); 515 HTMLElement::parseAttribute(name, oldValue, value);
516 } 516 }
517 } 517 }
518 518
519 void HTMLMediaElement::finishParsingChildren() 519 void HTMLMediaElement::finishParsingChildren()
520 { 520 {
521 HTMLElement::finishParsingChildren(); 521 HTMLElement::finishParsingChildren();
522 522
523 if (Traversal<HTMLTrackElement>::firstChild(*this)) 523 if (Traversal<HTMLTrackElement>::firstChild(*this))
524 scheduleDelayedAction(LoadTextTrackResource); 524 scheduleTextTrackResourceLoad();
525 } 525 }
526 526
527 bool HTMLMediaElement::layoutObjectIsNeeded(const ComputedStyle& style) 527 bool HTMLMediaElement::layoutObjectIsNeeded(const ComputedStyle& style)
528 { 528 {
529 return shouldShowControls() && HTMLElement::layoutObjectIsNeeded(style); 529 return shouldShowControls() && HTMLElement::layoutObjectIsNeeded(style);
530 } 530 }
531 531
532 LayoutObject* HTMLMediaElement::createLayoutObject(const ComputedStyle&) 532 LayoutObject* HTMLMediaElement::createLayoutObject(const ComputedStyle&)
533 { 533 {
534 return new LayoutMedia(this); 534 return new LayoutMedia(this);
535 } 535 }
536 536
537 Node::InsertionNotificationRequest HTMLMediaElement::insertedInto(ContainerNode* insertionPoint) 537 Node::InsertionNotificationRequest HTMLMediaElement::insertedInto(ContainerNode* insertionPoint)
538 { 538 {
539 WTF_LOG(Media, "HTMLMediaElement::insertedInto(%p, %p)", this, insertionPoin t); 539 WTF_LOG(Media, "HTMLMediaElement::insertedInto(%p, %p)", this, insertionPoin t);
540 540
541 HTMLElement::insertedInto(insertionPoint); 541 HTMLElement::insertedInto(insertionPoint);
542 if (insertionPoint->inDocument()) { 542 if (insertionPoint->inDocument()) {
543 UseCounter::count(document(), UseCounter::HTMLMediaElementInDocument); 543 UseCounter::count(document(), UseCounter::HTMLMediaElementInDocument);
544 if (!getAttribute(srcAttr).isEmpty() && m_networkState == NETWORK_EMPTY) 544 if (!getAttribute(srcAttr).isEmpty() && m_networkState == NETWORK_EMPTY) {
philipj_slow 2016/03/14 13:03:15 Just want to say that this was pretty strange to b
Srirama 2016/03/14 15:12:54 Acknowledged.
545 scheduleDelayedAction(LoadMediaResource); 545 m_ignorePreloadNone = false;
546 invokeLoadAlgorithm();
547 }
546 } 548 }
547 549
548 return InsertionShouldCallDidNotifySubtreeInsertions; 550 return InsertionShouldCallDidNotifySubtreeInsertions;
549 } 551 }
550 552
551 void HTMLMediaElement::didNotifySubtreeInsertionsToDocument() 553 void HTMLMediaElement::didNotifySubtreeInsertionsToDocument()
552 { 554 {
553 configureMediaControls(); 555 configureMediaControls();
554 } 556 }
555 557
(...skipping 16 matching lines...) Expand all
572 if (layoutObject()) 574 if (layoutObject())
573 layoutObject()->updateFromElement(); 575 layoutObject()->updateFromElement();
574 } 576 }
575 577
576 void HTMLMediaElement::didRecalcStyle(StyleRecalcChange) 578 void HTMLMediaElement::didRecalcStyle(StyleRecalcChange)
577 { 579 {
578 if (layoutObject()) 580 if (layoutObject())
579 layoutObject()->updateFromElement(); 581 layoutObject()->updateFromElement();
580 } 582 }
581 583
582 void HTMLMediaElement::scheduleDelayedAction(DelayedActionType actionType) 584 void HTMLMediaElement::scheduleTextTrackResourceLoad()
583 { 585 {
584 WTF_LOG(Media, "HTMLMediaElement::scheduleDelayedAction(%p)", this); 586 WTF_LOG(Media, "HTMLMediaElement::scheduleTextTrackResourceLoad(%p)", this);
585 587
586 if ((actionType & LoadMediaResource) && !(m_pendingActionFlags & LoadMediaRe source)) { 588 m_pendingActionFlags |= LoadTextTrackResource;
587 prepareForLoad();
588 m_pendingActionFlags |= LoadMediaResource;
589 }
590
591 if (actionType & LoadTextTrackResource)
592 m_pendingActionFlags |= LoadTextTrackResource;
593 589
594 if (!m_loadTimer.isActive()) 590 if (!m_loadTimer.isActive())
595 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); 591 m_loadTimer.startOneShot(0, BLINK_FROM_HERE);
596 } 592 }
597 593
598 void HTMLMediaElement::scheduleNextSourceChild() 594 void HTMLMediaElement::scheduleNextSourceChild()
599 { 595 {
600 // Schedule the timer to try the next <source> element WITHOUT resetting sta te ala prepareForLoad. 596 // Schedule the timer to try the next <source> element WITHOUT resetting sta te ala invokeLoadAlgorithm.
601 m_pendingActionFlags |= LoadMediaResource; 597 m_pendingActionFlags |= LoadMediaResource;
602 m_loadTimer.startOneShot(0, BLINK_FROM_HERE); 598 m_loadTimer.startOneShot(0, BLINK_FROM_HERE);
603 } 599 }
604 600
605 void HTMLMediaElement::scheduleEvent(const AtomicString& eventName) 601 void HTMLMediaElement::scheduleEvent(const AtomicString& eventName)
606 { 602 {
607 scheduleEvent(Event::createCancelable(eventName)); 603 scheduleEvent(Event::createCancelable(eventName));
608 } 604 }
609 605
610 void HTMLMediaElement::scheduleEvent(PassRefPtrWillBeRawPtr<Event> event) 606 void HTMLMediaElement::scheduleEvent(PassRefPtrWillBeRawPtr<Event> event)
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 699
704 if (UserGestureIndicator::processingUserGesture() && m_userGestureRequiredFo rPlay) { 700 if (UserGestureIndicator::processingUserGesture() && m_userGestureRequiredFo rPlay) {
705 recordAutoplayMetric(AutoplayEnabledThroughLoad); 701 recordAutoplayMetric(AutoplayEnabledThroughLoad);
706 m_userGestureRequiredForPlay = false; 702 m_userGestureRequiredForPlay = false;
707 // While usergesture-initiated load()s technically count as autoplayed, 703 // 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 704 // they don't feel like such to the users and hence we don't want to
709 // count them for the purposes of metrics. 705 // count them for the purposes of metrics.
710 m_autoplayMediaCounted = true; 706 m_autoplayMediaCounted = true;
711 } 707 }
712 708
713 prepareForLoad(); 709 m_ignorePreloadNone = true;
714 loadInternal(); 710 invokeLoadAlgorithm();
715 prepareToPlay();
716 } 711 }
717 712
718 void HTMLMediaElement::prepareForLoad() 713 // TODO(srirama.m): Currently m_ignorePreloadNone is reset before calling
714 // invokeLoadAlgorithm() in all places except load(). Move it inside here
715 // once microtask is implemented for "Await a stable state" step
716 // in resource selection algorithm.
717 void HTMLMediaElement::invokeLoadAlgorithm()
719 { 718 {
720 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this); 719 WTF_LOG(Media, "HTMLMediaElement::invokeLoadAlgorithm(%p)", this);
721 720
722 // Perform the cleanup required for the resource load algorithm to run. 721 // Perform the cleanup required for the resource load algorithm to run.
723 stopPeriodicTimers(); 722 stopPeriodicTimers();
724 m_loadTimer.stop(); 723 m_loadTimer.stop();
725 cancelDeferredLoad(); 724 cancelDeferredLoad();
726 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec essary and set m_pendingActionFlags to 0 here. 725 // FIXME: Figure out appropriate place to reset LoadTextTrackResource if nec essary and set m_pendingActionFlags to 0 here.
727 m_pendingActionFlags &= ~LoadMediaResource; 726 m_pendingActionFlags &= ~LoadMediaResource;
728 m_sentEndEvent = false; 727 m_sentEndEvent = false;
729 m_sentStalledEvent = false; 728 m_sentStalledEvent = false;
730 m_haveFiredLoadedData = false; 729 m_haveFiredLoadedData = false;
731 m_havePreparedToPlay = false;
732 m_displayMode = Unknown; 730 m_displayMode = Unknown;
733 731
734 // 1 - Abort any already-running instance of the resource selection algorith m for this element. 732 // 1 - Abort any already-running instance of the resource selection algorith m for this element.
735 m_loadState = WaitingForSource; 733 m_loadState = WaitingForSource;
736 m_currentSourceNode = nullptr; 734 m_currentSourceNode = nullptr;
737 735
738 // 2 - If there are any tasks from the media element's media element event t ask source in 736 // 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. 737 // one of the task queues, then remove those tasks.
740 cancelPendingEventsAndCallbacks(); 738 cancelPendingEventsAndCallbacks();
741 739
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 } 783 }
786 784
787 // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRat e attribute. 785 // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRat e attribute.
788 setPlaybackRate(defaultPlaybackRate()); 786 setPlaybackRate(defaultPlaybackRate());
789 787
790 // 6 - Set the error attribute to null and the autoplaying flag to true. 788 // 6 - Set the error attribute to null and the autoplaying flag to true.
791 m_error = nullptr; 789 m_error = nullptr;
792 m_autoplaying = true; 790 m_autoplaying = true;
793 791
794 // 7 - Invoke the media element's resource selection algorithm. 792 // 7 - Invoke the media element's resource selection algorithm.
793 invokeResourceSelectionAlgorithm();
795 794
796 // 8 - Note: Playback of any previously playing media resource for this elem ent stops. 795 // 8 - Note: Playback of any previously playing media resource for this elem ent stops.
796 scheduleNextSourceChild();
philipj_slow 2016/03/14 13:03:15 Oh but wait, every call to invokeResourceSelection
Srirama 2016/03/14 15:12:54 Done.
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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 m_mediaSource = nullptr; 975 m_mediaSource = nullptr;
970 attemptLoad = false; 976 attemptLoad = false;
971 } 977 }
972 } 978 }
973 } 979 }
974 } 980 }
975 981
976 if (attemptLoad && canLoadURL(url, contentType)) { 982 if (attemptLoad && canLoadURL(url, contentType)) {
977 ASSERT(!webMediaPlayer()); 983 ASSERT(!webMediaPlayer());
978 984
979 if (!m_havePreparedToPlay && effectivePreloadType() == WebMediaPlayer::P reloadNone) { 985 if (effectivePreloadType() == WebMediaPlayer::PreloadNone) {
980 WTF_LOG(Media, "HTMLMediaElement::loadResource(%p) : Delaying load b ecause preload == 'none'", this); 986 WTF_LOG(Media, "HTMLMediaElement::loadResource(%p) : Delaying load b ecause preload == 'none'", this);
981 deferLoad(); 987 deferLoad();
982 } else { 988 } else {
983 startPlayerLoad(); 989 startPlayerLoad();
984 } 990 }
985 } else { 991 } else {
986 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); 992 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError);
987 } 993 }
988 994
989 // If there is no poster to display, allow the media engine to render video frames as soon as 995 // 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
1047 // This handles any transition to or from fullscreen overlay mode. 1053 // This handles any transition to or from fullscreen overlay mode.
1048 frame->chromeClient().enterFullScreenForElement(this); 1054 frame->chromeClient().enterFullScreenForElement(this);
1049 } 1055 }
1050 } 1056 }
1051 1057
1052 void HTMLMediaElement::setPlayerPreload() 1058 void HTMLMediaElement::setPlayerPreload()
1053 { 1059 {
1054 if (m_webMediaPlayer) 1060 if (m_webMediaPlayer)
1055 m_webMediaPlayer->setPreload(effectivePreloadType()); 1061 m_webMediaPlayer->setPreload(effectivePreloadType());
1056 1062
1057 if (loadIsDeferred() && preloadType() != WebMediaPlayer::PreloadNone) 1063 if (loadIsDeferred() && effectivePreloadType() != WebMediaPlayer::PreloadNon e)
1058 startDeferredLoad(); 1064 startDeferredLoad();
1059 } 1065 }
1060 1066
1061 bool HTMLMediaElement::loadIsDeferred() const 1067 bool HTMLMediaElement::loadIsDeferred() const
1062 { 1068 {
1063 return m_deferredLoadState != NotDeferred; 1069 return m_deferredLoadState != NotDeferred;
1064 } 1070 }
1065 1071
1066 void HTMLMediaElement::deferLoad() 1072 void HTMLMediaElement::deferLoad()
1067 { 1073 {
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
1600 if (!m_playedTimeRanges) 1606 if (!m_playedTimeRanges)
1601 m_playedTimeRanges = TimeRanges::create(); 1607 m_playedTimeRanges = TimeRanges::create();
1602 m_playedTimeRanges->add(start, end); 1608 m_playedTimeRanges->add(start, end);
1603 } 1609 }
1604 1610
1605 bool HTMLMediaElement::supportsSave() const 1611 bool HTMLMediaElement::supportsSave() const
1606 { 1612 {
1607 return webMediaPlayer() && webMediaPlayer()->supportsSave(); 1613 return webMediaPlayer() && webMediaPlayer()->supportsSave();
1608 } 1614 }
1609 1615
1610 void HTMLMediaElement::prepareToPlay() 1616 void HTMLMediaElement::setIgnorePreloadNone()
1611 { 1617 {
1612 WTF_LOG(Media, "HTMLMediaElement::prepareToPlay(%p)", this); 1618 WTF_LOG(Media, "HTMLMediaElement::setIgnorePreloadNone(%p)", this);
1613 if (m_havePreparedToPlay) 1619 m_ignorePreloadNone = true;
1614 return; 1620 setPlayerPreload();
1615 m_havePreparedToPlay = true;
1616
1617 if (loadIsDeferred())
1618 startDeferredLoad();
1619 } 1621 }
1620 1622
1621 void HTMLMediaElement::seek(double time) 1623 void HTMLMediaElement::seek(double time)
1622 { 1624 {
1623 WTF_LOG(Media, "HTMLMediaElement::seek(%p, %f)", this, time); 1625 WTF_LOG(Media, "HTMLMediaElement::seek(%p, %f)", this, time);
1624 1626
1625 // 2 - If the media element's readyState is HAVE_NOTHING, abort these steps. 1627 // 2 - If the media element's readyState is HAVE_NOTHING, abort these steps.
1626 if (m_readyState == HAVE_NOTHING) 1628 if (m_readyState == HAVE_NOTHING)
1627 return; 1629 return;
1628 1630
1629 // If the media engine has been told to postpone loading data, let it go ahe ad now. 1631 // If the media engine has been told to postpone loading data, let it go ahe ad now.
1630 if (preloadType() < WebMediaPlayer::PreloadAuto && m_readyState < HAVE_FUTUR E_DATA) 1632 if (preloadType() < WebMediaPlayer::PreloadAuto && m_readyState < HAVE_FUTUR E_DATA)
1631 prepareToPlay(); 1633 setIgnorePreloadNone();
philipj_slow 2016/03/14 13:03:15 This actually looks like it could unconditionally
Srirama 2016/03/14 15:12:54 Done. I thought existing comment is ok. Anyway i h
philipj_slow 2016/03/14 15:59:56 Looks great!
1632 1634
1633 // Get the current time before setting m_seeking, m_lastSeekTime is returned once it is set. 1635 // Get the current time before setting m_seeking, m_lastSeekTime is returned once it is set.
1634 refreshCachedTime(); 1636 refreshCachedTime();
1635 // This is needed to avoid getting default playback start position from curr entTime(). 1637 // This is needed to avoid getting default playback start position from curr entTime().
1636 double now = m_cachedTime; 1638 double now = m_cachedTime;
1637 1639
1638 // 3 - If the element's seeking IDL attribute is true, then another instance of this algorithm is 1640 // 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 1641 // already running. Abort that other instance of the algorithm without waiti ng for the step that
1640 // it is running to complete. 1642 // it is running to complete.
1641 // Nothing specific to be done here. 1643 // Nothing specific to be done here.
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
1937 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=28950 1939 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=28950
1938 1940
1939 // TODO(philipj): Try to make "metadata" the default preload state: 1941 // TODO(philipj): Try to make "metadata" the default preload state:
1940 // https://crbug.com/310450 1942 // https://crbug.com/310450
1941 UseCounter::count(document(), UseCounter::HTMLMediaElementPreloadDefault); 1943 UseCounter::count(document(), UseCounter::HTMLMediaElementPreloadDefault);
1942 return WebMediaPlayer::PreloadAuto; 1944 return WebMediaPlayer::PreloadAuto;
1943 } 1945 }
1944 1946
1945 WebMediaPlayer::Preload HTMLMediaElement::effectivePreloadType() const 1947 WebMediaPlayer::Preload HTMLMediaElement::effectivePreloadType() const
1946 { 1948 {
1947 return autoplay() ? WebMediaPlayer::PreloadAuto : preloadType(); 1949 if (autoplay())
1950 return WebMediaPlayer::PreloadAuto;
1951
1952 WebMediaPlayer::Preload preload = preloadType();
1953 if (m_ignorePreloadNone && preload == WebMediaPlayer::PreloadNone)
1954 return WebMediaPlayer::PreloadMetaData;
1955
1956 return preload;
1948 } 1957 }
1949 1958
1950 ScriptPromise HTMLMediaElement::playForBindings(ScriptState* scriptState) 1959 ScriptPromise HTMLMediaElement::playForBindings(ScriptState* scriptState)
1951 { 1960 {
1952 Nullable<ExceptionCode> code = play(); 1961 Nullable<ExceptionCode> code = play();
1953 if (!code.isNull()) { 1962 if (!code.isNull()) {
1954 String message; 1963 String message;
1955 switch (code.get()) { 1964 switch (code.get()) {
1956 case NotAllowedError: 1965 case NotAllowedError:
1957 message = "play() can only be initiated by a user gesture."; 1966 message = "play() can only be initiated by a user gesture.";
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2008 { 2017 {
2009 WTF_LOG(Media, "HTMLMediaElement::playInternal(%p)", this); 2018 WTF_LOG(Media, "HTMLMediaElement::playInternal(%p)", this);
2010 2019
2011 // Always return the buffering strategy to normal when not paused, 2020 // Always return the buffering strategy to normal when not paused,
2012 // regardless of the cause. (In contrast with aggressive buffering which is 2021 // regardless of the cause. (In contrast with aggressive buffering which is
2013 // only enabled by pause(), not pauseInternal().) 2022 // only enabled by pause(), not pauseInternal().)
2014 if (webMediaPlayer()) 2023 if (webMediaPlayer())
2015 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Normal); 2024 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Normal);
2016 2025
2017 // 4.8.10.9. Playing the media resource 2026 // 4.8.10.9. Playing the media resource
2018 if (m_networkState == NETWORK_EMPTY) 2027 if (m_networkState == NETWORK_EMPTY) {
2019 scheduleDelayedAction(LoadMediaResource); 2028 // TODO(srirama.m): Remove scheduleNextSourceChild() here and
2029 // post a micro task inside invokeResourceSelectionAlgorithm().
2030 // See http://crbug.com/593289 for more details.
2031 invokeResourceSelectionAlgorithm();
2032 scheduleNextSourceChild();
2033 }
2020 2034
2021 // Generally "ended" and "looping" are exclusive. Here, the loop attribute 2035 // 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 2036 // is ignored to seek back to start in case loop was set after playback
2023 // ended. See http://crbug.com/364442 2037 // ended. See http://crbug.com/364442
2024 if (endedPlayback(LoopCondition::Ignored)) 2038 if (endedPlayback(LoopCondition::Ignored))
2025 seek(0); 2039 seek(0);
2026 2040
2027 if (m_paused) { 2041 if (m_paused) {
2028 m_paused = false; 2042 m_paused = false;
2029 invalidateCachedTime(); 2043 invalidateCachedTime();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2071 if (webMediaPlayer() && UserGestureIndicator::processingUserGesture()) 2085 if (webMediaPlayer() && UserGestureIndicator::processingUserGesture())
2072 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Aggressive); 2086 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Aggressive);
2073 2087
2074 pauseInternal(); 2088 pauseInternal();
2075 } 2089 }
2076 2090
2077 void HTMLMediaElement::pauseInternal() 2091 void HTMLMediaElement::pauseInternal()
2078 { 2092 {
2079 WTF_LOG(Media, "HTMLMediaElement::pauseInternal(%p)", this); 2093 WTF_LOG(Media, "HTMLMediaElement::pauseInternal(%p)", this);
2080 2094
2081 if (m_networkState == NETWORK_EMPTY) 2095 if (m_networkState == NETWORK_EMPTY) {
2082 scheduleDelayedAction(LoadMediaResource); 2096 // TODO(srirama.m): Remove scheduleNextSourceChild() here and
2097 // post a micro task inside invokeResourceSelectionAlgorithm().
2098 // See http://crbug.com/593289 for more details.
2099 invokeResourceSelectionAlgorithm();
2100 scheduleNextSourceChild();
2101 }
2083 2102
2084 m_autoplayHelper.pauseMethodCalled(); 2103 m_autoplayHelper.pauseMethodCalled();
2085 2104
2086 m_autoplaying = false; 2105 m_autoplaying = false;
2087 2106
2088 if (!m_paused) { 2107 if (!m_paused) {
2089 recordMetricsIfPausing(); 2108 recordMetricsIfPausing();
2090 2109
2091 m_paused = true; 2110 m_paused = true;
2092 scheduleTimeupdateEvent(false); 2111 scheduleTimeupdateEvent(false);
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
2408 // 5. Populate the new text track's list of cues with the cues parsed so far , folllowing the guidelines for exposing 2427 // 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. 2428 // cues, and begin updating it dynamically as necessary.
2410 // - Thess are all done by the media engine. 2429 // - Thess are all done by the media engine.
2411 2430
2412 // 6. Set the new text track's readiness state to loaded. 2431 // 6. Set the new text track's readiness state to loaded.
2413 textTrack->setReadinessState(TextTrack::Loaded); 2432 textTrack->setReadinessState(TextTrack::Loaded);
2414 2433
2415 // 7. Set the new text track's mode to the mode consistent with the user's p references and the requirements of 2434 // 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. 2435 // the relevant specification for the data.
2417 // - This will happen in honorUserPreferencesForAutomaticTextTrackSelection () 2436 // - This will happen in honorUserPreferencesForAutomaticTextTrackSelection ()
2418 scheduleDelayedAction(LoadTextTrackResource); 2437 scheduleTextTrackResourceLoad();
2419 2438
2420 // 8. Add the new text track to the media element's list of text tracks. 2439 // 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 2440 // 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 2441 // 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. 2442 // textTracks attribute's TextTrackList object.
2424 addTextTrack(textTrack); 2443 addTextTrack(textTrack);
2425 } 2444 }
2426 2445
2427 void HTMLMediaElement::removeTextTrack(WebInbandTextTrack* webTrack) 2446 void HTMLMediaElement::removeTextTrack(WebInbandTextTrack* webTrack)
2428 { 2447 {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2528 // media element's list of text tracks ... [continues in TextTrackList::appe nd] 2547 // media element's list of text tracks ... [continues in TextTrackList::appe nd]
2529 TextTrack* textTrack = trackElement->track(); 2548 TextTrack* textTrack = trackElement->track();
2530 if (!textTrack) 2549 if (!textTrack)
2531 return; 2550 return;
2532 2551
2533 addTextTrack(textTrack); 2552 addTextTrack(textTrack);
2534 2553
2535 // Do not schedule the track loading until parsing finishes so we don't star t before all tracks 2554 // 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. 2555 // in the markup have been added.
2537 if (isFinishedParsingChildren()) 2556 if (isFinishedParsingChildren())
2538 scheduleDelayedAction(LoadTextTrackResource); 2557 scheduleTextTrackResourceLoad();
2539 } 2558 }
2540 2559
2541 void HTMLMediaElement::didRemoveTrackElement(HTMLTrackElement* trackElement) 2560 void HTMLMediaElement::didRemoveTrackElement(HTMLTrackElement* trackElement)
2542 { 2561 {
2543 #if !LOG_DISABLED 2562 #if !LOG_DISABLED
2544 KURL url = trackElement->getNonEmptyURLAttribute(srcAttr); 2563 KURL url = trackElement->getNonEmptyURLAttribute(srcAttr);
2545 WTF_LOG(Media, "HTMLMediaElement::didRemoveTrackElement(%p) - 'src' is %s", this, urlForLoggingMedia(url).utf8().data()); 2564 WTF_LOG(Media, "HTMLMediaElement::didRemoveTrackElement(%p) - 'src' is %s", this, urlForLoggingMedia(url).utf8().data());
2546 #endif 2565 #endif
2547 2566
2548 TextTrack* textTrack = trackElement->track(); 2567 TextTrack* textTrack = trackElement->track();
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
2713 #endif 2732 #endif
2714 2733
2715 // We should only consider a <source> element when there is not src attribut e at all. 2734 // We should only consider a <source> element when there is not src attribut e at all.
2716 if (fastHasAttribute(srcAttr)) 2735 if (fastHasAttribute(srcAttr))
2717 return; 2736 return;
2718 2737
2719 // 4.8.8 - If a source element is inserted as a child of a media element tha t has no src 2738 // 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 2739 // attribute and whose networkState has the value NETWORK_EMPTY, the user ag ent must invoke
2721 // the media element's resource selection algorithm. 2740 // the media element's resource selection algorithm.
2722 if (getNetworkState() == HTMLMediaElement::NETWORK_EMPTY) { 2741 if (getNetworkState() == HTMLMediaElement::NETWORK_EMPTY) {
2723 scheduleDelayedAction(LoadMediaResource); 2742 // TODO(srirama.m): Remove scheduleNextSourceChild() here and
2743 // post a micro task inside invokeResourceSelectionAlgorithm().
2744 // See http://crbug.com/593289 for more details.
2745 invokeResourceSelectionAlgorithm();
2746 scheduleNextSourceChild();
2747 // Ignore current |m_nextChildNodeToConsider| and consider |source|.
2724 m_nextChildNodeToConsider = source; 2748 m_nextChildNodeToConsider = source;
2725 return; 2749 return;
2726 } 2750 }
2727 2751
2728 if (m_currentSourceNode && source == m_currentSourceNode->nextSibling()) { 2752 if (m_currentSourceNode && source == m_currentSourceNode->nextSibling()) {
2729 WTF_LOG(Media, "HTMLMediaElement::sourceWasAdded(%p) - <source> inserted immediately after current source", this); 2753 WTF_LOG(Media, "HTMLMediaElement::sourceWasAdded(%p) - <source> inserted immediately after current source", this);
2754 // Ignore current |m_nextChildNodeToConsider| and consider |source|.
2730 m_nextChildNodeToConsider = source; 2755 m_nextChildNodeToConsider = source;
2731 return; 2756 return;
2732 } 2757 }
2733 2758
2759 // Consider current |m_nextChildNodeToConsider| as it is already in the midd le of processing.
2734 if (m_nextChildNodeToConsider) 2760 if (m_nextChildNodeToConsider)
2735 return; 2761 return;
2736 2762
2737 if (m_loadState != WaitingForSource) 2763 if (m_loadState != WaitingForSource)
2738 return; 2764 return;
2739 2765
2740 // 4.8.9.5, resource selection algorithm, source elements section: 2766 // 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.) 2767 // 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... 2768 // 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 2769 // 23. Set the element's delaying-the-load-event flag back to true (this del ays the load event again, in case
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
3044 3070
3045 refreshCachedTime(); 3071 refreshCachedTime();
3046 3072
3047 m_playbackProgressTimer.stop(); 3073 m_playbackProgressTimer.stop();
3048 m_playing = false; 3074 m_playing = false;
3049 double time = currentTime(); 3075 double time = currentTime();
3050 if (time > m_lastSeekTime) 3076 if (time > m_lastSeekTime)
3051 addPlayedRange(m_lastSeekTime, time); 3077 addPlayedRange(m_lastSeekTime, time);
3052 3078
3053 if (couldPlayIfEnoughData()) 3079 if (couldPlayIfEnoughData())
3054 prepareToPlay(); 3080 setIgnorePreloadNone();
philipj_slow 2016/03/14 13:03:15 I looked at more context and realize I don't under
Srirama 2016/03/14 15:12:54 Infact i had the same doubt initially when you sai
philipj_slow 2016/03/14 15:59:56 OK, that's weird, makes more sense when moved, tha
3055 3081
3056 if (mediaControls()) 3082 if (mediaControls())
3057 mediaControls()->playbackStopped(); 3083 mediaControls()->playbackStopped();
3058 } 3084 }
3059 3085
3060 if (layoutObject()) 3086 if (layoutObject())
3061 layoutObject()->updateFromElement(); 3087 layoutObject()->updateFromElement();
3062 } 3088 }
3063 3089
3064 void HTMLMediaElement::stopPeriodicTimers() 3090 void HTMLMediaElement::stopPeriodicTimers()
3065 { 3091 {
3066 m_progressEventTimer.stop(); 3092 m_progressEventTimer.stop();
3067 m_playbackProgressTimer.stop(); 3093 m_playbackProgressTimer.stop();
3068 } 3094 }
3069 3095
3070 void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClientWithoutLockin g() 3096 void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClientWithoutLockin g()
3071 { 3097 {
3072 audioSourceProvider().setClient(nullptr); 3098 audioSourceProvider().setClient(nullptr);
3073 if (m_webMediaPlayer) { 3099 if (m_webMediaPlayer) {
3074 m_audioSourceProvider.wrap(nullptr); 3100 m_audioSourceProvider.wrap(nullptr);
3075 m_webMediaPlayer.clear(); 3101 m_webMediaPlayer.clear();
3076 } 3102 }
3077 } 3103 }
3078 3104
3079 void HTMLMediaElement::clearMediaPlayer(int flags) 3105 void HTMLMediaElement::clearMediaPlayer()
3080 { 3106 {
3081 forgetResourceSpecificTracks(); 3107 forgetResourceSpecificTracks();
3082 3108
3083 closeMediaSource(); 3109 closeMediaSource();
3084 3110
3085 cancelDeferredLoad(); 3111 cancelDeferredLoad();
3086 3112
3087 { 3113 {
3088 AudioSourceProviderClientLockScope scope(*this); 3114 AudioSourceProviderClientLockScope scope(*this);
3089 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); 3115 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
3090 } 3116 }
3091 3117
3092 stopPeriodicTimers(); 3118 stopPeriodicTimers();
3093 m_loadTimer.stop(); 3119 m_loadTimer.stop();
3094 3120
3095 m_pendingActionFlags &= ~flags; 3121 m_pendingActionFlags = 0;
3096 m_loadState = WaitingForSource; 3122 m_loadState = WaitingForSource;
3097 3123
3098 // We can't cast if we don't have a media player. 3124 // We can't cast if we don't have a media player.
3099 m_remoteRoutesAvailable = false; 3125 m_remoteRoutesAvailable = false;
3100 m_playingRemotely = false; 3126 m_playingRemotely = false;
3101 if (mediaControls()) 3127 if (mediaControls())
3102 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); 3128 mediaControls()->refreshCastButtonVisibilityWithoutUpdate();
3103 3129
3104 if (layoutObject()) 3130 if (layoutObject())
3105 layoutObject()->setShouldDoFullPaintInvalidation(); 3131 layoutObject()->setShouldDoFullPaintInvalidation();
3106 } 3132 }
3107 3133
3108 void HTMLMediaElement::stop() 3134 void HTMLMediaElement::stop()
3109 { 3135 {
3110 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); 3136 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this);
3111 3137
3112 recordMetricsIfPausing(); 3138 recordMetricsIfPausing();
3113 3139
3114 // Close the async event queue so that no events are enqueued. 3140 // Close the async event queue so that no events are enqueued.
3115 cancelPendingEventsAndCallbacks(); 3141 cancelPendingEventsAndCallbacks();
3116 m_asyncEventQueue->close(); 3142 m_asyncEventQueue->close();
3117 3143
3118 // Stop the playback without generating events 3144 // Clear everything in the Media Element
3119 clearMediaPlayer(-1); 3145 clearMediaPlayer();
3120 m_readyState = HAVE_NOTHING; 3146 m_readyState = HAVE_NOTHING;
3121 m_readyStateMaximum = HAVE_NOTHING; 3147 m_readyStateMaximum = HAVE_NOTHING;
3122 setNetworkState(NETWORK_EMPTY); 3148 setNetworkState(NETWORK_EMPTY);
3123 setShouldDelayLoadEvent(false); 3149 setShouldDelayLoadEvent(false);
3124 m_currentSourceNode = nullptr; 3150 m_currentSourceNode = nullptr;
3125 invalidateCachedTime(); 3151 invalidateCachedTime();
3126 cueTimeline().updateActiveCues(0); 3152 cueTimeline().updateActiveCues(0);
3127 m_playing = false; 3153 m_playing = false;
3128 m_paused = true; 3154 m_paused = true;
3129 m_seeking = false; 3155 m_seeking = false;
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
3480 } 3506 }
3481 3507
3482 void* HTMLMediaElement::preDispatchEventHandler(Event* event) 3508 void* HTMLMediaElement::preDispatchEventHandler(Event* event)
3483 { 3509 {
3484 if (event && event->type() == EventTypeNames::webkitfullscreenchange) 3510 if (event && event->type() == EventTypeNames::webkitfullscreenchange)
3485 configureMediaControls(); 3511 configureMediaControls();
3486 3512
3487 return nullptr; 3513 return nullptr;
3488 } 3514 }
3489 3515
3490 // TODO(srirama.m): Refactor this and clearMediaPlayer to the extent possible. 3516 // TODO(srirama.m): Merge it to resetMediaElement if possible and remove it.
3491 void HTMLMediaElement::resetMediaPlayerAndMediaSource() 3517 void HTMLMediaElement::resetMediaPlayerAndMediaSource()
3492 { 3518 {
3493 closeMediaSource(); 3519 closeMediaSource();
3494 3520
3495 { 3521 {
3496 AudioSourceProviderClientLockScope scope(*this); 3522 AudioSourceProviderClientLockScope scope(*this);
3497 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking(); 3523 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
3498 } 3524 }
3499 3525
3500 // We haven't yet found out if any remote routes are available. 3526 // We haven't yet found out if any remote routes are available.
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
3784 { 3810 {
3785 visitor->trace(m_client); 3811 visitor->trace(m_client);
3786 } 3812 }
3787 3813
3788 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) 3814 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl)
3789 { 3815 {
3790 visitor->trace(m_client); 3816 visitor->trace(m_client);
3791 } 3817 }
3792 3818
3793 } // namespace blink 3819 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698