Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

<!doctype html>
<title>getDisplayMedia MediaStreamTrack video resizeMode.</title>
<meta name="timeout" content="long">
<meta name="variant" content="?resizeMode=enabled">
<meta name="variant" content="?resizeMode=disabled">
<p class="instructions">When prompted, accept to share your video stream.</p>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/resources/testdriver.js></script>
<script src=/resources/testdriver-vendor.js></script>
<script src=settings-helper.js></script>
<script src=../mediacapture-streams/video-test-helper.js></script>
<script>
"use strict"
function doTest() {
const resizeModeEnabled =
new URLSearchParams(window.location.search).get("resizeMode") == "enabled";
// Note these gDM tests will fail if our own window is on a screen different
// than the system's first screen. They're functions in case the browser
// window needs to be moved to the first screen during the test in order to
// pass.
function screenPixelRatio() { return SpecialPowers.wrap(window).desktopToDeviceScale; }
function screenWidth() { return window.screen.width * window.devicePixelRatio; }
function screenHeight() { return window.screen.height * window.devicePixelRatio; }
function desktopWidth() {
// TODO: Bug 1965499 - scale down by screenPixelRatio by default in resizeMode: crop-and-scale.
// return screenWidth() / screenPixelRatio();
return screenWidth();
}
function desktopHeight() {
// TODO: Bug 1965499 - scale down by screenPixelRatio by default in resizeMode: crop-and-scale.
// return screenHeight() / screenPixelRatio();
return screenHeight();
}
promise_test(async t => {
await test_driver.bless('getDisplayMedia()');
const stream = await navigator.mediaDevices.getDisplayMedia(
{video: {resizeMode: "none", width: 100}}
);
const [track] = stream.getTracks();
t.add_cleanup(() => track.stop());
if (resizeModeEnabled) {
assert_equals(track.getSettings().width, screenWidth(), "width");
assert_equals(track.getSettings().height, screenHeight(), "height");
assert_equals(track.getSettings().frameRate, 60, "framerate");
assert_equals(track.getSettings().resizeMode, "none", "resizeMode");
} else {
assert_equals(track.getSettings().width, 100, "width");
assert_equals(track.getSettings().height, Math.round(screenHeight() / screenWidth() * 100), "height");
assert_equals(track.getSettings().frameRate, 30, "framerate");
assert_equals(track.getSettings().resizeMode, undefined, "resizeMode");
}
}, "gDM gets full screen resolution by width");
// TODO: By default we shouldn't be multiplying with window.devicePixelRatio (bug 1703991).
function defaultScreen() {
return {
resizeMode: "crop-and-scale",
width: screenWidth(),
height: screenHeight(),
frameRate: 30,
};
}
// TODO: Should get the source's real refresh rate for frameRate (bug 1984363).
function nativeScreen() {
return {
resizeMode: "none",
width: screenWidth(),
height: screenHeight(),
frameRate: 60
};
}
[
[{resizeMode: "none", width: 100}, resizeModeEnabled ? nativeScreen : () => ({
width: 100,
height: Math.round(screenHeight() / screenWidth() * 100),
frameRate: 30
})],
[{resizeMode: "none", frameRate: 50}, resizeModeEnabled ? nativeScreen : () => ({
width: screenWidth(),
height: screenHeight(),
frameRate: 50
})],
[{resizeMode: "crop-and-scale"}, defaultScreen],
[{resizeMode: "crop-and-scale", height: 100}, () => ({
resizeMode: "crop-and-scale",
width: Math.round(screenWidth() / screenHeight() * 100),
height: 100,
frameRate: 30
})],
[{resizeMode: "crop-and-scale", frameRate: 5}, () => {
const { width, height } = defaultScreen();
return { width, height, frameRate: 5};
}, [2, 7]],
[{resizeMode: "crop-and-scale", frameRate: 50}, () => {
const { width, height } = defaultScreen();
return { width, height, frameRate: 50};
}],
[{resizeMode: "crop-and-scale", frameRate: 5000}, () => {
const { width, height } = defaultScreen();
return { width, height, frameRate: 120};
}],
].forEach(([video, expectedFunc, testFramerate]) => {
let expected;
promise_test(async t => {
expected = expectedFunc();
await test_driver.bless('getDisplayMedia()');
const stream = await navigator.mediaDevices.getDisplayMedia({video});
const [track] = stream.getTracks();
t.add_cleanup(() => track.stop());
const settings = track.getSettings();
if (!resizeModeEnabled) {
expected.resizeMode = undefined;
}
for (const key of Object.keys(expected)) {
assert_equals(settings[key], expected[key], key);
}
if (testFramerate) {
const [low, high] = testFramerate;
await test_framerate_between_exclusive(t, track, low, high);
}
}, `gDM gets expected mode by ${JSON.stringify(video)}`);
});
promise_test(async t => {
await test_driver.bless('getDisplayMedia()');
const stream = await navigator.mediaDevices.getDisplayMedia(
{video: {
resizeMode: "crop-and-scale",
width: 400,
height: 400
}}
);
const [track] = stream.getTracks();
t.add_cleanup(() => track.stop());
const expected = findFittestResolutionSetting(
screenWidth(),
screenHeight(),
track.getConstraints()
);
assert_equals(track.getSettings().width, expected.width, "width");
assert_equals(track.getSettings().height, expected.height, "height");
assert_approx_equals(
track.getSettings().width / track.getSettings().height,
desktopWidth() / desktopHeight(),
0.01,
"aspect ratio"
);
assert_equals(track.getSettings().resizeMode, resizeModeEnabled ? "crop-and-scale" : undefined, "resizeMode");
}, "gDM doesn't crop with only ideal dimensions");
promise_test(async t => {
await test_driver.bless('getDisplayMedia()');
const stream = await navigator.mediaDevices.getDisplayMedia(
{video: {
resizeMode: "crop-and-scale",
width: {max: 400},
height: {ideal: 400}
}}
);
const [track] = stream.getTracks();
t.add_cleanup(() => track.stop());
assert_equals(track.getSettings().width, 400, "width");
assert_equals(
track.getSettings().height,
Math.round(screenHeight() / screenWidth() * 400),
"height"
);
assert_equals(track.getSettings().resizeMode, resizeModeEnabled ? "crop-and-scale" : undefined, "resizeMode");
}, "gDM doesn't crop with ideal and max dimensions");
}
window.addEventListener("load", doTest, {once: true});
</script>