script-transform-generateKeyFrame-simulcast.https.html (6136B)
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset=utf-8> 5 <title>RTCRtpScriptTransformer.generateKeyFrame simulcast tests</title> 6 <meta name='timeout' content='long'> 7 <script src='/resources/testharness.js'></script> 8 <script src='/resources/testharnessreport.js'></script> 9 <script src=/resources/testdriver.js></script> 10 <script src=/resources/testdriver-vendor.js></script> 11 <script src='../mediacapture-streams/permission-helper.js'></script> 12 </head> 13 <body> 14 <video id='video1' autoplay></video> 15 <video id='video2' autoplay></video> 16 <script src ='routines.js'></script> 17 <script src ='../webrtc/simulcast/simulcast.js'></script> 18 <script src ='../webrtc/RTCPeerConnection-helper.js'></script> 19 <script src='../webrtc/third_party/sdp/sdp.js'></script> 20 <script> 21 22 const generateKeyFrame = (port, opts) => postMethod(port, 'generateKeyFrame', opts); 23 const waitForFrame = port => postMethod(port, 'waitForFrame'); 24 25 promise_test(async (test) => { 26 const worker = await createWorker('script-transform-generateKeyFrame.js'); 27 const transform = await createTransform(worker); 28 const senderPc = new RTCPeerConnection(); 29 const receiverPc = new RTCPeerConnection(); 30 // This will only work if first rid is 0 31 exchangeIceCandidates(senderPc, receiverPc); 32 const stream = await navigator.mediaDevices.getUserMedia({video: { width: 1280 } }); 33 const {sender} = senderPc.addTransceiver(stream.getTracks()[0], {sendEncodings: [{rid: '0'}, {rid: '1'}, {rid: '2'}]}); 34 sender.transform = transform; 35 await doOfferToSendSimulcastAndAnswer(senderPc, receiverPc, ['0', '1', '2']); 36 37 let message = await waitForFrame(sender.transform.port); 38 assert_equals(message, 'got frame'); 39 40 // Spec says ridless generateKeyFrame selects the first stream, so should work 41 message = await generateKeyFrame(sender.transform.port); 42 assert_equals(message.result, 'success'); 43 44 message = await generateKeyFrame(sender.transform.port, {rid: '0'}); 45 assert_equals(message.result, 'success'); 46 47 message = await generateKeyFrame(sender.transform.port, {rid: '1'}); 48 assert_equals(message.result, 'success'); 49 50 message = await generateKeyFrame(sender.transform.port, {rid: '2'}); 51 assert_equals(message.result, 'success'); 52 }, 'generateKeyFrame works with simulcast rids'); 53 54 promise_test(async (test) => { 55 const worker = await createWorker('script-transform-generateKeyFrame.js'); 56 const transform = await createTransform(worker); 57 const senderPc = new RTCPeerConnection(); 58 const receiverPc = new RTCPeerConnection(); 59 // This will only work if first rid is 0 60 exchangeIceCandidates(senderPc, receiverPc); 61 const stream = await navigator.mediaDevices.getUserMedia({video: { width: 1280 } }); 62 const {sender} = senderPc.addTransceiver(stream.getTracks()[0], {sendEncodings: [{rid: '0'}, {rid: '1'}, {rid: '2'}]}); 63 sender.transform = transform; 64 await doOfferToSendSimulcastAndAnswer(senderPc, receiverPc, ['0', '1', '2']); 65 66 let message = await waitForFrame(sender.transform.port); 67 assert_equals(message, 'got frame'); 68 69 // Remove the '1' encoding 70 await doOfferToSendSimulcastAndAnswer(senderPc, receiverPc, ['0', '2']); 71 72 // Spec says ridless generateKeyFrame selects the first stream, so should work 73 message = await generateKeyFrame(sender.transform.port); 74 assert_equals(message.result, 'success'); 75 76 message = await generateKeyFrame(sender.transform.port, {rid: '0'}); 77 assert_equals(message.result, 'success'); 78 79 message = await generateKeyFrame(sender.transform.port, {rid: '1'}); 80 assert_equals(message.result, 'failure'); 81 assert_equals(message.value, 'NotFoundError', `Message: ${message.message}`); 82 83 message = await generateKeyFrame(sender.transform.port, {rid: '2'}); 84 assert_equals(message.result, 'success'); 85 }, 'generateKeyFrame for rid that was negotiated away fails'); 86 87 promise_test(async (test) => { 88 const worker = await createWorker('script-transform-generateKeyFrame.js'); 89 const transform = await createTransform(worker); 90 const senderPc = new RTCPeerConnection(); 91 const receiverPc = new RTCPeerConnection(); 92 // This will only work if first rid is 0 93 exchangeIceCandidates(senderPc, receiverPc); 94 const stream = await navigator.mediaDevices.getUserMedia({video: { width: 1280 } }); 95 const {sender} = senderPc.addTransceiver(stream.getTracks()[0], {sendEncodings: [{rid: '0'}, {rid: '1'}, {rid: '2'}]}); 96 sender.transform = transform; 97 await doOfferToSendSimulcastAndAnswer(senderPc, receiverPc, ['0', '1', '2']); 98 99 let message = await waitForFrame(sender.transform.port); 100 assert_equals(message, 'got frame'); 101 102 // Drop to unicast 103 await doOfferToSendSimulcastAndAnswer(senderPc, receiverPc, []); 104 105 message = await generateKeyFrame(sender.transform.port); 106 assert_equals(message.result, 'success'); 107 108 // This is really lame, but there could be frames with rids in flight, and 109 // there's not really any good way to know when they've been flushed out. 110 // If RTCEncodedVideoFrame had a rid field, we might be able to watch for a 111 // frame without a rid. We can't just use generateKeyFrame(null) either, 112 // because a keyframe in flight with the first rid can resolve it. However, 113 // it's reasonable to expect that if we wait for a _second_ 114 // generateKeyFrame(null), that should not be resolved with a keyframe for 115 // '0' 116 message = await generateKeyFrame(sender.transform.port); 117 assert_equals(message.result, 'success'); 118 119 message = await generateKeyFrame(sender.transform.port, {rid: '0'}); 120 assert_equals(message.result, 'failure'); 121 assert_equals(message.value, 'NotFoundError', `Message: ${message.message}`); 122 123 message = await generateKeyFrame(sender.transform.port, {rid: '1'}); 124 assert_equals(message.result, 'failure'); 125 assert_equals(message.value, 'NotFoundError', `Message: ${message.message}`); 126 127 message = await generateKeyFrame(sender.transform.port, {rid: '2'}); 128 assert_equals(message.result, 'failure'); 129 assert_equals(message.value, 'NotFoundError', `Message: ${message.message}`); 130 }, 'generateKeyFrame with rid after simulcast->unicast negotiation fails'); 131 132 </script> 133 </body> 134 </html>