test_peerConnection_simulcastAnswer_oldSetParameters.html (4521B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <script type="application/javascript" src="pc.js"></script> 5 <script type="application/javascript" src="/tests/dom/canvas/test/captureStream_common.js"></script> 6 <script type="application/javascript" src="helpers_from_wpt/sdp.js"></script> 7 <script type="application/javascript" src="simulcast.js"></script> 8 <script type="application/javascript" src="stats.js"></script> 9 </head> 10 <body> 11 <pre id="test"> 12 <script type="application/javascript"> 13 createHTML({ 14 bug: "1231507", 15 title: "Basic video-only peer connection with Simulcast answer", 16 visible: true 17 }); 18 19 runNetworkTest(async () => { 20 await pushPrefs( 21 // 180Kbps was determined empirically, set well-higher than 22 // the 80Kbps+overhead needed for the two simulcast streams. 23 // 100Kbps was apparently too low. 24 ['media.peerconnection.video.min_bitrate_estimate', 180*1000]); 25 26 // [TODO] re-enable HW decoder after bug 1526207 is fixed. 27 if (navigator.userAgent.includes("Android")) { 28 await pushPrefs(["media.navigator.mediadatadecoder_vpx_enabled", false]); 29 } 30 31 32 const offerer = new RTCPeerConnection(); 33 const answerer = new RTCPeerConnection(); 34 35 const add = (pc, can, failed) => can && pc.addIceCandidate(can).catch(failed); 36 offerer.onicecandidate = e => add(answerer, e.candidate, generateErrorCallback()); 37 answerer.onicecandidate = e => add(offerer, e.candidate, generateErrorCallback()); 38 39 const metadataToBeLoaded = []; 40 offerer.ontrack = (e) => { 41 metadataToBeLoaded.push(getPlaybackWithLoadedMetadata(e.track)); 42 }; 43 44 // Two recv transceivers, one for each simulcast stream 45 offerer.addTransceiver('video', { direction: 'recvonly' }); 46 offerer.addTransceiver('video', { direction: 'recvonly' }); 47 48 // One send transceiver, that will be used to send both simulcast streams 49 const emitter = new VideoFrameEmitter(); 50 const videoStream = emitter.stream(); 51 answerer.addTrack(videoStream.getVideoTracks()[0], videoStream); 52 emitter.start(); 53 54 const offer = await offerer.createOffer(); 55 56 const mungedOffer = midToRid(offer); 57 info(`Transformed recv offer to simulcast: ${offer.sdp} to ${mungedOffer}`); 58 59 await answerer.setRemoteDescription({type: "offer", sdp: mungedOffer}); 60 await offerer.setLocalDescription(offer); 61 62 const rids = offerer.getTransceivers().map(t => t.mid); 63 is(rids.length, 2, 'Should have 2 mids in offer'); 64 ok(rids[0] != '', 'First mid should be non-empty'); 65 ok(rids[1] != '', 'Second mid should be non-empty'); 66 info(`rids: ${JSON.stringify(rids)}`); 67 68 const sender = answerer.getSenders()[0]; 69 await sender.setParameters({ 70 encodings: [ 71 { rid: rids[0], maxBitrate: 40000 }, 72 { rid: rids[1], maxBitrate: 40000, scaleResolutionDownBy: 2 } 73 ] 74 }); 75 76 const answer = await answerer.createAnswer(); 77 78 const mungedAnswer = ridToMid(answer); 79 info(`Transformed send simulcast answer to multiple m-sections: ${answer.sdp} to ${mungedAnswer}`); 80 await offerer.setRemoteDescription({type: "answer", sdp: mungedAnswer}); 81 await answerer.setLocalDescription(answer); 82 83 is(metadataToBeLoaded.length, 2, 'Offerer should have gotten 2 ontrack events'); 84 info('Waiting for 2 loadedmetadata events'); 85 const videoElems = await Promise.all(metadataToBeLoaded); 86 87 const statsReady = 88 Promise.all([waitForSyncedRtcp(offerer), waitForSyncedRtcp(answerer)]); 89 90 const helper = new VideoStreamHelper(); 91 info('Waiting for first video element to start playing'); 92 await helper.checkVideoPlaying(videoElems[0]); 93 info('Waiting for second video element to start playing'); 94 await helper.checkVideoPlaying(videoElems[1]); 95 96 is(videoElems[0].videoWidth, 64, 97 "sink is same width as source, modulo our cropping algorithm"); 98 is(videoElems[0].videoHeight, 64, 99 "sink is same height as source, modulo our cropping algorithm"); 100 is(videoElems[1].videoWidth, 32, 101 "sink is 1/2 width of source, modulo our cropping algorithm"); 102 is(videoElems[1].videoHeight, 32, 103 "sink is 1/2 height of source, modulo our cropping algorithm"); 104 105 await statsReady; 106 const senderStats = await sender.getStats(); 107 checkSenderStats(senderStats, 2); 108 checkExpectedFields(senderStats); 109 pedanticChecks(senderStats); 110 111 emitter.stop(); 112 videoStream.getVideoTracks()[0].stop(); 113 offerer.close(); 114 answerer.close(); 115 }); 116 </script> 117 </pre> 118 </body> 119 </html>