136 lines
6 KiB
HTML
136 lines
6 KiB
HTML
<!doctype html>
|
|
<html>
|
|
<head>
|
|
<meta charset=utf-8>
|
|
<title>RTCRtpScriptTransformer.generateKeyFrame simulcast tests</title>
|
|
<meta name='timeout' content='long'>
|
|
<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='../mediacapture-streams/permission-helper.js'></script>
|
|
</head>
|
|
<body>
|
|
<video id='video1' autoplay></video>
|
|
<video id='video2' autoplay></video>
|
|
<script src ='routines.js'></script>
|
|
<script src ='../webrtc/simulcast/simulcast.js'></script>
|
|
<script src ='../webrtc/RTCPeerConnection-helper.js'></script>
|
|
<script src='../webrtc/third_party/sdp/sdp.js'></script>
|
|
<script>
|
|
|
|
const generateKeyFrame = (port, opts) => postMethod(port, 'generateKeyFrame', opts);
|
|
const waitForFrame = port => postMethod(port, 'waitForFrame');
|
|
|
|
promise_test(async (test) => {
|
|
const worker = await createWorker('script-transform-generateKeyFrame.js');
|
|
const transform = await createTransform(worker);
|
|
const senderPc = new RTCPeerConnection();
|
|
const receiverPc = new RTCPeerConnection();
|
|
// This will only work if first rid is 0
|
|
exchangeIceCandidates(senderPc, receiverPc);
|
|
const stream = await navigator.mediaDevices.getUserMedia({video: true});
|
|
const {sender} = senderPc.addTransceiver(stream.getTracks()[0], {sendEncodings: [{rid: '0'}, {rid: '1'}, {rid: '2'}]});
|
|
sender.transform = transform;
|
|
await doOfferToSendSimulcastAndAnswer(senderPc, receiverPc, ['0', '1', '2']);
|
|
|
|
let message = await waitForFrame(sender.transform.port);
|
|
assert_equals(message, 'got frame');
|
|
|
|
// Spec says ridless generateKeyFrame selects the first stream, so should work
|
|
message = await generateKeyFrame(sender.transform.port);
|
|
assert_equals(message.result, 'success');
|
|
|
|
message = await generateKeyFrame(sender.transform.port, {rid: '0'});
|
|
assert_equals(message.result, 'success');
|
|
|
|
message = await generateKeyFrame(sender.transform.port, {rid: '1'});
|
|
assert_equals(message.result, 'success');
|
|
|
|
message = await generateKeyFrame(sender.transform.port, {rid: '2'});
|
|
assert_equals(message.result, 'success');
|
|
}, 'generateKeyFrame works with simulcast rids');
|
|
|
|
promise_test(async (test) => {
|
|
const worker = await createWorker('script-transform-generateKeyFrame.js');
|
|
const transform = await createTransform(worker);
|
|
const senderPc = new RTCPeerConnection();
|
|
const receiverPc = new RTCPeerConnection();
|
|
// This will only work if first rid is 0
|
|
exchangeIceCandidates(senderPc, receiverPc);
|
|
const stream = await navigator.mediaDevices.getUserMedia({video: true});
|
|
const {sender} = senderPc.addTransceiver(stream.getTracks()[0], {sendEncodings: [{rid: '0'}, {rid: '1'}, {rid: '2'}]});
|
|
sender.transform = transform;
|
|
await doOfferToSendSimulcastAndAnswer(senderPc, receiverPc, ['0', '1', '2']);
|
|
|
|
let message = await waitForFrame(sender.transform.port);
|
|
assert_equals(message, 'got frame');
|
|
|
|
// Remove the '1' encoding
|
|
await doOfferToSendSimulcastAndAnswer(senderPc, receiverPc, ['0', '2']);
|
|
|
|
// Spec says ridless generateKeyFrame selects the first stream, so should work
|
|
message = await generateKeyFrame(sender.transform.port);
|
|
assert_equals(message.result, 'success');
|
|
|
|
message = await generateKeyFrame(sender.transform.port, {rid: '0'});
|
|
assert_equals(message.result, 'success');
|
|
|
|
message = await generateKeyFrame(sender.transform.port, {rid: '1'});
|
|
assert_equals(message.result, 'failure');
|
|
assert_equals(message.value, 'NotFoundError', `Message: ${message.message}`);
|
|
|
|
message = await generateKeyFrame(sender.transform.port, {rid: '2'});
|
|
assert_equals(message.result, 'success');
|
|
}, 'generateKeyFrame for rid that was negotiated away fails');
|
|
|
|
promise_test(async (test) => {
|
|
const worker = await createWorker('script-transform-generateKeyFrame.js');
|
|
const transform = await createTransform(worker);
|
|
const senderPc = new RTCPeerConnection();
|
|
const receiverPc = new RTCPeerConnection();
|
|
// This will only work if first rid is 0
|
|
exchangeIceCandidates(senderPc, receiverPc);
|
|
const stream = await navigator.mediaDevices.getUserMedia({video: true});
|
|
const {sender} = senderPc.addTransceiver(stream.getTracks()[0], {sendEncodings: [{rid: '0'}, {rid: '1'}, {rid: '2'}]});
|
|
sender.transform = transform;
|
|
await doOfferToSendSimulcastAndAnswer(senderPc, receiverPc, ['0', '1', '2']);
|
|
|
|
let message = await waitForFrame(sender.transform.port);
|
|
assert_equals(message, 'got frame');
|
|
|
|
// Drop to unicast
|
|
await doOfferToSendSimulcastAndAnswer(senderPc, receiverPc, []);
|
|
|
|
message = await generateKeyFrame(sender.transform.port);
|
|
assert_equals(message.result, 'success');
|
|
|
|
// This is really lame, but there could be frames with rids in flight, and
|
|
// there's not really any good way to know when they've been flushed out.
|
|
// If RTCEncodedVideoFrame had a rid field, we might be able to watch for a
|
|
// frame without a rid. We can't just use generateKeyFrame(null) either,
|
|
// because a keyframe in flight with the first rid can resolve it. However,
|
|
// it's reasonable to expect that if we wait for a _second_
|
|
// generateKeyFrame(null), that should not be resolved with a keyframe for
|
|
// '0'
|
|
message = await generateKeyFrame(sender.transform.port);
|
|
assert_equals(message.result, 'success');
|
|
|
|
message = await generateKeyFrame(sender.transform.port, {rid: '0'});
|
|
assert_equals(message.result, 'failure');
|
|
assert_equals(message.value, 'NotFoundError', `Message: ${message.message}`);
|
|
|
|
message = await generateKeyFrame(sender.transform.port, {rid: '1'});
|
|
assert_equals(message.result, 'failure');
|
|
assert_equals(message.value, 'NotFoundError', `Message: ${message.message}`);
|
|
|
|
message = await generateKeyFrame(sender.transform.port, {rid: '2'});
|
|
assert_equals(message.result, 'failure');
|
|
assert_equals(message.value, 'NotFoundError', `Message: ${message.message}`);
|
|
}, 'generateKeyFrame with rid after simulcast->unicast negotiation fails');
|
|
|
|
</script>
|
|
</body>
|
|
</html>
|
|
|
|
|