1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
<!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: { width: 1280 } });
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: { width: 1280 } });
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: { width: 1280 } });
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>
|