blob: 16f2f84a03236480bcbd6dd8b7afcda607641fc4 [file] [log] [blame]
<!doctype html>
<html>
<head>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
</head>
<body>
<div>
<video id="low" playsinline autoplay width="320"></video>
<video id="mid" playsinline autoplay width="320"></video>
<video id="high" playsinline autoplay width="320"></video>
</div>
<script>
if (window.testRunner)
testRunner.setWebRTCUnifiedPlanEnabled(false);
var state;
var finished = false;
// This test is largely inspired from Chrome/Firefox/Simulcast playground tests.
promise_test(async (test) => {
if (window.testRunner && testRunner.timeout) {
setTimeout(() => {
if (!finished)
throw "test stucked in state: " + state;
}, testRunner.timeout * 0.9);
}
state = "start";
const pc1 = new RTCPeerConnection();
const pc2 = new RTCPeerConnection();
pc1.onicecandidate = (e) => pc2.addIceCandidate(e.candidate);
pc2.onicecandidate = (e) => pc1.addIceCandidate(e.candidate);
let counter = 0;
pc2.ontrack = (e) => {
if (counter == 0)
low.srcObject = new MediaStream([e.track]);
else if (counter == 1)
mid.srcObject = new MediaStream([e.track]);
else
high.srcObject = new MediaStream([e.track]);
++counter;
}
const localStream = await navigator.mediaDevices.getUserMedia({ video: { width: 640, height: 480 } });
pc1.addTrack(localStream.getVideoTracks()[0], localStream);
const offer = await pc1.createOffer();
state = "got offer";
match = offer.sdp.match(/a=ssrc:(\d+) cname:(.*)\r\n/);
msid = offer.sdp.match(/a=ssrc:(\d+) msid:(.*)\r\n/);
var lines = offer.sdp.trim().split('\r\n');
var removed = lines.splice(lines.length - 4, 4);
var videoSSRC1 = parseInt(match[1]);
rtxSSRC1 = offer.sdp.split('\r\n').filter((line) => { return line.startsWith('a=ssrc-group:FID ')})[0].split(' ')[2];
var videoSSRC2 = videoSSRC1 + 1;
var rtxSSRC2 = videoSSRC1 + 2;
var videoSSRC3 = videoSSRC1 + 3;
var rtxSSRC3 = videoSSRC1 + 4;
lines.push(removed[0]);
lines.push(removed[1]);
lines.push('a=ssrc:' + videoSSRC2 + ' cname:' + match[2]);
lines.push('a=ssrc:' + videoSSRC2 + ' msid:' + msid[2]);
lines.push('a=ssrc:' + rtxSSRC2 + ' cname:' + match[2]);
lines.push('a=ssrc:' + rtxSSRC2 + ' msid:' + msid[2]);
lines.push('a=ssrc:' + videoSSRC3 + ' cname:' + match[2]);
lines.push('a=ssrc:' + videoSSRC3 + ' msid:' + msid[2]);
lines.push('a=ssrc:' + rtxSSRC3 + ' cname:' + match[2]);
lines.push('a=ssrc:' + rtxSSRC3 + ' msid:' + msid[2]);
lines.push('a=ssrc-group:FID ' + videoSSRC2 + ' ' + rtxSSRC2);
lines.push('a=ssrc-group:FID ' + videoSSRC3 + ' ' + rtxSSRC3);
lines.push('a=ssrc-group:SIM ' + videoSSRC1 + ' ' + videoSSRC2 + ' ' + videoSSRC3);
offer.sdp = lines.join('\r\n') + '\r\n';
var offer2 = {
type: 'offer',
sdp: offer.sdp,
};
offer2.sdp = offer2.sdp.replace('a=ssrc-group:SIM ' + videoSSRC1 + ' ' + videoSSRC2 + ' ' + videoSSRC3 + '\r\n', '');
offer2.sdp = offer2.sdp.replace('a=ssrc:' + videoSSRC1 + ' msid:' + msid[2], 'a=ssrc:' + videoSSRC1 + ' msid:low low');
offer2.sdp = offer2.sdp.replace('a=ssrc:' + rtxSSRC1 + ' msid:' + msid[2], 'a=ssrc:' + rtxSSRC1 + ' msid:low low');
offer2.sdp = offer2.sdp.replace('a=ssrc:' + videoSSRC2 + ' msid:' + msid[2], 'a=ssrc:' + videoSSRC2 + ' msid:mid mid');
offer2.sdp = offer2.sdp.replace('a=ssrc:' + rtxSSRC2 + ' msid:' + msid[2], 'a=ssrc:' + rtxSSRC2 + ' msid:mid mid');
offer2.sdp = offer2.sdp.replace('a=ssrc:' + videoSSRC3 + ' msid:' + msid[2], 'a=ssrc:' + videoSSRC3 + ' msid:hi hi');
offer2.sdp = offer2.sdp.replace('a=ssrc:' + rtxSSRC3 + ' msid:' + msid[2], 'a=ssrc:' + rtxSSRC3 + ' msid:hi hi');
await Promise.all([
pc1.setLocalDescription(offer),
pc2.setRemoteDescription(offer2),
]);
state = "set description";
const answer = await pc2.createAnswer();
state = "got answer";
await Promise.all([
pc2.setLocalDescription(answer),
pc1.setRemoteDescription(answer),
]);
state = "set description 2";
await low.play();
state = "video low plays";
assert_equals(low.srcObject.getVideoTracks()[0].getSettings().height, 240);
assert_equals(low.srcObject.getVideoTracks()[0].getSettings().width, 320);
await mid.play();
state = "video mid plays";
assert_equals(mid.srcObject.getVideoTracks()[0].getSettings().height, 480);
assert_equals(mid.srcObject.getVideoTracks()[0].getSettings().width, 640);
finished = true;
}, "Testing simulcast");
</script>
</body>
</html>