haikuwebkit/LayoutTests/fast/mediastream/mediaPlayer-visibility.html

60 lines
2.1 KiB
HTML
Raw Permalink Normal View History

MediaPlayerPrivateMediaStreamAVFObjC should skip enqueuing frames when not visible https://bugs.webkit.org/show_bug.cgi?id=228816 <rdar://81077972> Reviewed by Eric Carlson. Source/WebCore: Do not create layers when not needed. This prevents enqueuing frames in a AVSampleBufferDisplayLayer that will only buffer them, thus breaking camera capture/video decoding. We do this by not calling ensureLayers when getting a new track. Instead we react upon player renderingCanBeAccelerated value. It is also unnecessary and takes CPU cycles to enqueue frames when the video element is not visible. HTMLMediaElement and RenderVideo thus pass to MediaPlayer a new flag telling whether the video element is visible in the view port. MediaPlayerPrivateMediaStreamAVFObjC will then skip enqueueing frames if not needed. Add getter and internals API to cover these changes. Test: fast/mediastream/mediaPlayer-visibility.html * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::isVisibleInViewportChanged): * platform/graphics/MediaPlayer.cpp: (WebCore::MediaPlayer::loadWithNextMediaEngine): (WebCore::MediaPlayer::setVisibleInViewport): * platform/graphics/MediaPlayer.h: * platform/graphics/MediaPlayerPrivate.h: (WebCore::MediaPlayerPrivateInterface::setVisibleInViewport): * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h: * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm: (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::enqueueVideoSample): (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::setVisible): (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::setVisibleInViewport): (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::checkSelectedVideoTrack): (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::paintCurrentFrameInContext): * rendering/RenderVideo.cpp: (WebCore::RenderVideo::updatePlayer): * testing/Internals.cpp: (WebCore::Internals::isPlayerVisibleInViewport const): * testing/Internals.h: * testing/Internals.idl: LayoutTests: * fast/mediastream/mediaPlayer-visibility-expected.txt: Added. * fast/mediastream/mediaPlayer-visibility.html: Added. Canonical link: https://commits.webkit.org/240311@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@280720 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-08-06 09:15:49 +00:00
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<body>
<video id="video1" autoplay playsInline></video>
<video id="video2" autoplay playsInline style="visibility:hidden"></video>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script>
promise_test(async() => {
if (!window.internals)
return Promise.reject("Test requires internals API");
const stream = await navigator.mediaDevices.getUserMedia({video : true});
video1.srcObject = stream;
await video1.play();
assert_true(internals.isPlayerVisibleInViewport(video1), "video1");
}, "Check default media stream player visibility");
promise_test(async() => {
if (!window.internals)
return Promise.reject("Test requires internals API");
const stream = await navigator.mediaDevices.getUserMedia({video : true});
video2.srcObject = stream;
await video2.play();
assert_false(internals.isPlayerVisibleInViewport(video2), "video2");
video2.style.visibility = "visible";
await new Promise(resolve => setTimeout(resolve, 0));
assert_true(internals.isPlayerVisibleInViewport(video2), "video2 2");
video2.style.visibility = "hidden";
await new Promise(resolve => setTimeout(resolve, 0));
assert_false(internals.isPlayerVisibleInViewport(video2), "video2 3");
}, "Check media stream player visibility with CSS");
promise_test(async() => {
if (!window.internals)
return Promise.reject("Test requires internals API");
const video3 = document.createElement("video");
const stream = await navigator.mediaDevices.getUserMedia({video : true});
video3.srcObject = stream;
video3.playsInline = true;
await video3.play();
assert_false(internals.isPlayerVisibleInViewport(video3), "video3");
document.body.appendChild(video3);
await video3.play();
await new Promise(resolve => setTimeout(resolve, 0));
assert_false(internals.isPlayerVisibleInViewport(video3), "video3 2");
}, "Check media stream player visibility of unattached media element");
</script>
</body>
</html>