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