Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorganize WebRTC-SVC tests in multiple files #37084

Merged
merged 1 commit into from
Nov 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions webrtc-svc/RTCRtpParameters-scalability-av1.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!doctype html>
<meta charset=utf-8>
<meta name="timeout" content="long">
<title>AV1 scalabilityMode</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/webrtc/RTCRtpParameters-helper.js"></script>
<script src="/webrtc/RTCPeerConnection-helper.js"></script>
<script src="/webrtc-svc/svc-helper.js"></script>
<script>
'use strict';

createScalabilityTest('video/AV1', [
"L1T1",
"L1T2",
"L1T3",
"L2T1",
"L2T2",
"L2T3",
"L3T1",
"L3T2",
"L3T3",
"L2T1h",
"L2T2h",
"L2T3h",
"S2T1",
"S2T2",
"S2T3",
"S2T1h",
"S2T2h",
"S2T3h",
"S3T1",
"S3T2",
"S3T3",
"S3T1h",
"S3T2h",
"S3T3h",
"L2T2_KEY",
"L2T3_KEY",
"L3T2_KEY",
"L3T3_KEY"
]);
</script>
18 changes: 18 additions & 0 deletions webrtc-svc/RTCRtpParameters-scalability-h264.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!doctype html>
<meta charset=utf-8>
<meta name="timeout" content="long">
<title>H264 scalabilityMode</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/webrtc/RTCRtpParameters-helper.js"></script>
<script src="/webrtc/RTCPeerConnection-helper.js"></script>
<script src="/webrtc-svc/svc-helper.js"></script>
<script>
'use strict';

createScalabilityTest('video/H264', [
"L1T1",
"L1T2",
"L1T3"
]);
</script>
18 changes: 18 additions & 0 deletions webrtc-svc/RTCRtpParameters-scalability-vp8.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!doctype html>
<meta charset=utf-8>
<meta name="timeout" content="long">
<title>VP8 scalabilityMode</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/webrtc/RTCRtpParameters-helper.js"></script>
<script src="/webrtc/RTCPeerConnection-helper.js"></script>
<script src="/webrtc-svc/svc-helper.js"></script>
<script>
'use strict';

createScalabilityTest('video/VP8', [
"L1T1",
"L1T2",
"L1T3"
]);
</script>
43 changes: 43 additions & 0 deletions webrtc-svc/RTCRtpParameters-scalability-vp9.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!doctype html>
<meta charset=utf-8>
<meta name="timeout" content="long">
<title>VP9 scalabilityMode</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/webrtc/RTCRtpParameters-helper.js"></script>
<script src="/webrtc/RTCPeerConnection-helper.js"></script>
<script src="/webrtc-svc/svc-helper.js"></script>
<script>
'use strict';

createScalabilityTest('video/VP9', [
"L1T1",
"L1T2",
"L1T3",
"L2T1",
"L2T2",
"L2T3",
"L3T1",
"L3T2",
"L3T3",
"L2T1h",
"L2T2h",
"L2T3h",
"S2T1",
"S2T2",
"S2T3",
"S2T1h",
"S2T2h",
"S2T3h",
"S3T1",
"S3T2",
"S3T3",
"S3T1h",
"S3T2h",
"S3T3h",
"L2T2_KEY",
"L2T3_KEY",
"L3T2_KEY",
"L3T3_KEY"
]);
</script>
178 changes: 68 additions & 110 deletions webrtc-svc/RTCRtpParameters-scalability.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<!doctype html>
<meta charset=utf-8>
<meta name="timeout" content="long">
<title>RTCRtpParameters encodings</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
Expand All @@ -12,46 +13,6 @@
// Test is based on the following editor draft:
// https://w3c.github.io/webrtc-svc/

// Get the first encoding in param.encodings.
// Asserts that param.encodings has at least one element.
function getFirstEncoding(param) {
const { encodings } = param;
assert_equals(encodings.length, 1);
return encodings[0];
}

const capabilities = RTCRtpSender.getCapabilities('video');
let index = 0;
for (const codec of capabilities.codecs) {
if ('scalabilityModes' in codec && codec.scalabilityModes.length > 0) {
for (const scalabilityMode of codec.scalabilityModes) {
promise_test(async t => {
const v = document.createElement('video');
v.autoplay = true;
const pc1 = new RTCPeerConnection();
const pc2 = new RTCPeerConnection();
t.add_cleanup(() => pc1.close());
t.add_cleanup(() => pc2.close());
const stream1 = await getNoiseStream({ video: { signal: 100 , width: 60, height: 60} });
const [track1] = stream1.getTracks();
t.add_cleanup(() => track1.stop());
const transceiver = pc1.addTransceiver(track1, {
sendEncodings: [{ scalabilityMode: scalabilityMode }],
});
transceiver.setCodecPreferences([codec]);
const haveTrackEvent = new Promise(r => pc2.ontrack = r);
exchangeIceCandidates(pc1, pc2);
await exchangeOfferAnswer(pc1, pc2);
v.srcObject = new MediaStream([(await haveTrackEvent).track]);
await new Promise(r => v.onloadedmetadata = r);
await detectSignal(t, v, 100);
const sendParams = pc1.getSenders()[0].getParameters();
assert_equals(sendParams.encodings[0].scalabilityMode, scalabilityMode);
}, `[${index++}] ${codec.mimeType} - ${scalabilityMode} should produce valid video content`);
}
}
}

promise_test(async t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
Expand Down Expand Up @@ -84,81 +45,78 @@
assert_true(svcSupported);
}, `Sender capabilities should include at least some scalability modes`);

promise_test(async t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
const { sender } = pc.addTransceiver('video');
const param = sender.getParameters();
assert_equals(param.encodings.length, 0);
}, 'Not setting sendEncodings results in no mode info before negotiation');

promise_test(async t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
const { sender } = pc.addTransceiver('video', {
sendEncodings: [{}],
});
const param = sender.getParameters();
const encoding = getFirstEncoding(param);

assert_true(!('scalabilityMode' in encoding));
}, 'Not setting a scalability mode results in no mode set before negotiation');

promise_test(async t => {
const pc1 = new RTCPeerConnection();
const pc2 = new RTCPeerConnection();
t.add_cleanup(() => pc1.close());
t.add_cleanup(() => pc2.close());
const { sender } = pc1.addTransceiver('video', {
sendEncodings: [{}],
});
const param = sender.getParameters();
const encoding = getFirstEncoding(param);

exchangeIceCandidates(pc1, pc2);
await exchangeOfferAnswer(pc1, pc2);
const param2 = sender.getParameters();
const encoding2 = getFirstEncoding(param);
assert_true('scalabilityMode' in encoding2);
}, 'Not setting a scalability mode results in some mode set after negotiation');
promise_test(async t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
const { sender } = pc.addTransceiver('video');
const param = sender.getParameters();
assert_equals(param.encodings.length, 0);
}, 'Not setting sendEncodings results in no mode info before negotiation');

promise_test(async t => {
promise_test(async t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
assert_throws_dom('OperationError', () => {
pc.addTransceiver('video', {
sendEncodings: [{scalabilityMode: 'TotalNonsense'}],
t.add_cleanup(() => pc.close());
const { sender } = pc.addTransceiver('video', {
sendEncodings: [{}],
});
});
}, 'Setting a scalability mode to nonsense throws an exception');
const param = sender.getParameters();
const encoding = getFirstEncoding(param);

assert_true(!('scalabilityMode' in encoding));
}, 'Not setting a scalability mode results in no mode set before negotiation');

promise_test(async t => {
const pc1 = new RTCPeerConnection();
const pc2 = new RTCPeerConnection();
t.add_cleanup(() => pc1.close());
t.add_cleanup(() => pc2.close());
const { sender } = pc1.addTransceiver('video', {
sendEncodings: [{}],
});
const param = sender.getParameters();
const encoding = getFirstEncoding(param);

promise_test(async t => {
const v = document.createElement('video');
v.autoplay = true;
const pc1 = new RTCPeerConnection();
const pc2 = new RTCPeerConnection();
t.add_cleanup(() => pc1.close());
t.add_cleanup(() => pc2.close());
const transceiver = pc1.addTransceiver('video', {
sendEncodings: [{ scalabilityMode: 'L3T3' }],
});
// Before negotiation, the mode should be preserved.
const param = transceiver.sender.getParameters();
const encoding = getFirstEncoding(param);
assert_true('scalabilityMode' in encoding);
// If L3T3 is not supported at all, abort test.
assert_implements_optional(encoding.scalabilityMode === 'L3T3');
// Pick a codec known to not have L3T3 support
const capabilities = RTCRtpSender.getCapabilities('video');
const codec = capabilities.codecs.find(c => c.mimeType === 'video/VP8');
assert_true(codec !== undefined);
transceiver.setCodecPreferences([codec]);
exchangeIceCandidates(pc1, pc2);
await exchangeOfferAnswer(pc1, pc2);
const sendParams = pc1.getSenders()[0].getParameters();
assert_not_equals(sendParams.encodings[0].scalabilityMode, 'L3T3');
}, 'L3T3 on VP8 should return something other than L3T3');
exchangeIceCandidates(pc1, pc2);
await exchangeOfferAnswer(pc1, pc2);
const param2 = sender.getParameters();
const encoding2 = getFirstEncoding(param);
assert_true('scalabilityMode' in encoding2);
}, 'Not setting a scalability mode results in some mode set after negotiation');

promise_test(async t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
assert_throws_dom('OperationError', () => {
pc.addTransceiver('video', {
sendEncodings: [{scalabilityMode: 'TotalNonsense'}],
});
});
}, 'Setting a scalability mode to nonsense throws an exception');

promise_test(async t => {
const v = document.createElement('video');
v.autoplay = true;
const pc1 = new RTCPeerConnection();
const pc2 = new RTCPeerConnection();
t.add_cleanup(() => pc1.close());
t.add_cleanup(() => pc2.close());
const transceiver = pc1.addTransceiver('video', {
sendEncodings: [{ scalabilityMode: 'L3T3' }],
});
// Before negotiation, the mode should be preserved.
const param = transceiver.sender.getParameters();
const encoding = getFirstEncoding(param);
assert_true('scalabilityMode' in encoding);
// If L3T3 is not supported at all, abort test.
assert_implements_optional(encoding.scalabilityMode === 'L3T3');
// Pick a codec known to not have L3T3 support
const capabilities = RTCRtpSender.getCapabilities('video');
const codec = capabilities.codecs.find(c => c.mimeType === 'video/VP8');
assert_true(codec !== undefined);
transceiver.setCodecPreferences([codec]);
exchangeIceCandidates(pc1, pc2);
await exchangeOfferAnswer(pc1, pc2);
const sendParams = pc1.getSenders()[0].getParameters();
assert_not_equals(sendParams.encodings[0].scalabilityMode, 'L3T3');
}, 'L3T3 on VP8 should return something other than L3T3');
</script>
50 changes: 50 additions & 0 deletions webrtc-svc/svc-helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
function supportsCodec(mimeType) {
return RTCRtpSender.getCapabilities('video').codecs.filter(c => c.mimeType == mimeType).length() > 0;
}

async function supportsScalabilityMode(mimeType, scalabilityMode) {
let result = await navigator.mediaCapabilities.encodingInfo({
type: 'webrtc',
video: {
contentType: mimeType,
width: 60,
height: 60,
bitrate: 10000,
framerate: 30,
scalabilityMode: scalabilityMode
}
});
return result.supported;
}

function createScalabilityTest(mimeType, scalabilityModes) {
for (const scalabilityMode of scalabilityModes) {
promise_test(async t => {
assert_implements_optional(
supportsScalabilityMode(mimeType, scalabilityMode),
`${mimeType} supported`
);
const v = document.createElement('video');
v.autoplay = true;
const pc1 = new RTCPeerConnection();
const pc2 = new RTCPeerConnection();
t.add_cleanup(() => pc1.close());
t.add_cleanup(() => pc2.close());
const stream1 = await getNoiseStream({ video: { signal: 100, width: 60, height: 60 } });
const [track1] = stream1.getTracks();
t.add_cleanup(() => track1.stop());
const transceiver = pc1.addTransceiver(track1, {
sendEncodings: [{ scalabilityMode: scalabilityMode }],
});
transceiver.setCodecPreferences(RTCRtpSender.getCapabilities('video').codecs.filter(c => c.mimeType == mimeType));
const haveTrackEvent = new Promise(r => pc2.ontrack = r);
exchangeIceCandidates(pc1, pc2);
await exchangeOfferAnswer(pc1, pc2);
v.srcObject = new MediaStream([(await haveTrackEvent).track]);
await new Promise(r => v.onloadedmetadata = r);
await detectSignal(t, v, 100);
const sendParams = pc1.getSenders()[0].getParameters();
assert_equals(sendParams.encodings[0].scalabilityMode, scalabilityMode);
}, `${mimeType} - ${scalabilityMode} should produce valid video content`);
}
}