RTCRtpSender-setParameters-keyFrame.html (3999B)
1 <!doctype html> 2 <meta charset=utf-8> 3 <meta name="timeout" content="long"> 4 <title>RTCRtpSender.prototype.setParameters for generating keyFrames</title> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 <script src="RTCPeerConnection-helper.js"></script> 8 <script src="third_party/sdp/sdp.js"></script> 9 <script src="simulcast/simulcast.js"></script> 10 <script> 11 'use strict'; 12 13 // https://w3c.github.io/webrtc-extensions/#rtcrtpsender-setparameters-keyframe 14 15 async function waitForKeyFrameCount(t, pc, spatialLayer, minimumKeyFrames) { 16 // return after 5 seconds. 17 const startTime = performance.now(); 18 while (true) { 19 const report = await pc.getStats(); 20 const stats = [...report.values()].find(({type, rid}) => type === 'outbound-rtp' && rid === spatialLayer); 21 if (stats && stats.keyFramesEncoded >= minimumKeyFrames) { 22 return stats; 23 } 24 await new Promise(r => t.step_timeout(r, 100)); 25 if (performance.now() > startTime + 5000) { 26 break; 27 } 28 } 29 } 30 31 promise_test(async t => { 32 const pc1 = new RTCPeerConnection(); 33 t.add_cleanup(() => pc1.close()); 34 const pc2 = new RTCPeerConnection(); 35 t.add_cleanup(() => pc2.close()); 36 // Video must be small enough to reach a key frame of the right size immediately. 37 const stream = await getNoiseStream({video: {width: 320, height: 160}}); 38 t.add_cleanup(() => stream.getTracks().forEach(t => t.stop())); 39 40 const sender = pc1.addTrack(stream.getTracks()[0], stream); 41 exchangeIceCandidates(pc1, pc2); 42 await exchangeOfferAnswer(pc1, pc2); 43 44 const rid = undefined; 45 const first_stats = await waitForKeyFrameCount(t, pc1, rid, 1); 46 assert_true(!!first_stats); 47 sender.setParameters(sender.getParameters(), { 48 encodingOptions: [{keyFrame: true}], 49 }); 50 const second_stats = await waitForKeyFrameCount(t, pc1, rid, first_stats.keyFramesEncoded + 1); 51 assert_true(!!second_stats); 52 assert_greater_than(second_stats.keyFramesEncoded, first_stats.keyFramesEncoded); 53 }, `setParameters() second argument can be used to trigger keyFrame generation`); 54 55 promise_test(async t => { 56 const pc1 = new RTCPeerConnection(); 57 t.add_cleanup(() => pc1.close()); 58 const pc2 = new RTCPeerConnection(); 59 t.add_cleanup(() => pc2.close()); 60 // Video must be small enough to reach a key frame of the right size immediately. 61 const stream = await getNoiseStream({video: {width: 640, height: 360}}); 62 t.add_cleanup(() => stream.getTracks().forEach(t => t.stop())); 63 64 const rids = ['0', '1']; 65 const {sender} = pc1.addTransceiver(stream.getTracks()[0], { 66 streams: [stream], 67 sendEncodings: [{rid: 0}, {rid: 1}], 68 }); 69 exchangeIceCandidates(pc1, pc2); 70 await pc1.setLocalDescription(); 71 await pc2.setRemoteDescription({type: 'offer', sdp: ridToMid(pc1.localDescription, rids)}); 72 await pc2.setLocalDescription(); 73 await pc1.setRemoteDescription({type: 'answer', sdp: midToRid( 74 pc2.localDescription, 75 pc1.localDescription, 76 rids 77 )}); 78 79 const first_stats_l0 = await waitForKeyFrameCount(t, pc1, '0', 1); 80 assert_true(!!first_stats_l0); 81 const first_stats_l1 = await waitForKeyFrameCount(t, pc1, '1', 1); 82 assert_true(!!first_stats_l1); 83 84 // Generate a keyframe on the second layer. This may, depending on the encoder, force 85 // a key frame on the first layer as well. 86 sender.setParameters(sender.getParameters(), { 87 encodingOptions: [{keyFrame: false}, {keyFrame: true}], 88 }); 89 const second_stats_l1 = await waitForKeyFrameCount(t, pc1, '1', first_stats_l1.keyFramesEncoded + 1); 90 assert_true(!!second_stats_l1); 91 assert_greater_than(second_stats_l1.keyFramesEncoded, first_stats_l1.keyFramesEncoded); 92 93 const second_stats_l0 = await waitForKeyFrameCount(t, pc1, '0', first_stats_l0.keyFramesEncoded); 94 assert_true(!!second_stats_l0); 95 assert_greater_than_equal(second_stats_l0.keyFramesEncoded, first_stats_l0.keyFramesEncoded); 96 }, `setParameters() second argument can be used to trigger keyFrame generation (simulcast)`); 97 </script>