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

Unified Diff: third_party/WebKit/Source/core/html/HTMLMediaElement.cpp

Issue 2475643004: Monitor the intersection of video and viewport. (Closed)
Patch Set: Moved the calculation of intersection ratio to RemotingController. Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
index 56ad755a6e9c9743151d0a62dc99d5335758bdd9..aaf03db5be9e5ea3562ed00fb8260bb4e1f17110 100644
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -464,8 +464,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName,
m_autoplayHelper(
AutoplayExperimentHelper::create(m_autoplayHelperClient.get())),
m_autoplayUmaHelper(AutoplayUmaHelper::create(this)),
- m_remotePlaybackClient(nullptr),
- m_autoplayVisibilityObserver(nullptr) {
+ m_remotePlaybackClient(nullptr) {
ThreadState::current()->registerPreFinalizer(this);
BLINK_MEDIA_LOG << "HTMLMediaElement(" << (void*)this << ")";
@@ -482,6 +481,11 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName,
addElementToDocumentMap(this, &document);
UseCounter::count(document, UseCounter::HTMLMediaElement);
+
+ m_viewportIntersectionObserver = new ViewportIntersectionObserver(
+ this, WTF::bind(&HTMLMediaElement::onVideoViewportIntersectionChanged,
+ wrapWeakPersistent(this)));
+ m_viewportIntersectionObserver->start();
}
HTMLMediaElement::~HTMLMediaElement() {
@@ -497,6 +501,8 @@ HTMLMediaElement::~HTMLMediaElement() {
void HTMLMediaElement::dispose() {
closeMediaSource();
+ m_viewportIntersectionObserver->stop();
+
// Destroying the player may cause a resource load to be canceled,
// which could result in LocalDOMWindow::dispatchWindowLoadEvent() being
// called via ResourceFetch::didLoadResource(), then
@@ -1723,16 +1729,7 @@ void HTMLMediaElement::setReadyState(ReadyState state) {
if (!isGestureNeededForPlayback()) {
if (isHTMLVideoElement() && muted() &&
RuntimeEnabledFeatures::autoplayMutedVideosEnabled()) {
- // We might end up in a situation where the previous
- // observer didn't had time to fire yet. We can avoid
- // creating a new one in this case.
- if (!m_autoplayVisibilityObserver) {
- m_autoplayVisibilityObserver = new ElementVisibilityObserver(
- this,
- WTF::bind(&HTMLMediaElement::onVisibilityChangedForAutoplay,
- wrapWeakPersistent(this)));
- m_autoplayVisibilityObserver->start();
- }
+ m_shouldAutoplayWhenVisible = true;
} else {
m_paused = false;
invalidateCachedTime();
@@ -2355,7 +2352,7 @@ void HTMLMediaElement::setMuted(bool muted) {
bool wasAutoplayingMuted =
!paused() && m_muted && isLockedPendingUserGesture();
- bool wasPendingAutoplayMuted = m_autoplayVisibilityObserver && paused() &&
+ bool wasPendingAutoplayMuted = m_shouldAutoplayWhenVisible && paused() &&
m_muted && isLockedPendingUserGesture();
if (UserGestureIndicator::processingUserGesture())
@@ -2382,11 +2379,9 @@ void HTMLMediaElement::setMuted(bool muted) {
}
// If an element was a candidate for autoplay muted but not visible, it will
- // have a visibility observer ready to start its playback.
- if (wasPendingAutoplayMuted) {
- m_autoplayVisibilityObserver->stop();
- m_autoplayVisibilityObserver = nullptr;
- }
+ // start its playback once becomes visible.
+ if (wasPendingAutoplayMuted)
+ m_shouldAutoplayWhenVisible = false;
}
void HTMLMediaElement::updateVolume() {
@@ -3742,7 +3737,7 @@ DEFINE_TRACE(HTMLMediaElement) {
visitor->trace(m_autoplayHelper);
visitor->trace(m_autoplayUmaHelper);
visitor->trace(m_srcObject);
- visitor->trace(m_autoplayVisibilityObserver);
+ visitor->trace(m_viewportIntersectionObserver);
visitor->template registerWeakMembers<HTMLMediaElement,
&HTMLMediaElement::clearWeakMembers>(
this);
@@ -3968,8 +3963,20 @@ EnumerationHistogram& HTMLMediaElement::showControlsHistogram() const {
return histogram;
}
-void HTMLMediaElement::onVisibilityChangedForAutoplay(bool isVisible) {
- if (!isVisible)
+void HTMLMediaElement::onVideoViewportIntersectionChanged(
+ const WebRect& rootRect,
+ const WebRect& intersectRect) {
+ WebMediaPlayer::ViewportIntersectionInfo info;
+ info.rootRect = rootRect;
+ info.intersectRect = intersectRect;
+ if (m_webMediaPlayer)
+ m_webMediaPlayer->videoViewportIntersectionChanged(info);
+ m_viewportIntersectInfo = info;
+
+ bool isVisible = !intersectRect.isEmpty();
+ m_autoplayUmaHelper->visibilityMaybeChangedforMutedVideo(isVisible);
+
+ if (!isVisible || !m_shouldAutoplayWhenVisible)
return;
if (shouldAutoplay()) {
@@ -3981,13 +3988,7 @@ void HTMLMediaElement::onVisibilityChangedForAutoplay(bool isVisible) {
updatePlayState();
}
-
- // TODO(zqzhang): There's still flaky leak if onVisibilityChangedForAutoplay()
- // is never called. The leak comes from either ElementVisibilityObserver or
- // IntersectionObserver. Should keep an eye on it. See
- // https://crbug.com/627539
- m_autoplayVisibilityObserver->stop();
- m_autoplayVisibilityObserver = nullptr;
+ m_shouldAutoplayWhenVisible = false;
}
void HTMLMediaElement::clearWeakMembers(Visitor* visitor) {

Powered by Google App Engine
This is Rietveld 408576698