test_peerConnection_simulcastOddResolution_oldSetParameters.html (7196B)
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: "1432793", 15 title: "Simulcast with odd resolution", 16 visible: true 17 }); 18 19 runNetworkTest(async () => { 20 const helper = new VideoStreamHelper(); 21 const emitter = new VideoFrameEmitter(helper.green, helper.red, 705, 528); 22 23 async function checkVideoElement(senderElement, receiverElement, encoding) { 24 info(`Waiting for receiver video element ${encoding.rid} to start playing`); 25 await helper.checkVideoPlaying(receiverElement); 26 const srcWidth = senderElement.videoWidth; 27 const srcHeight = senderElement.videoHeight; 28 info(`Source resolution is ${srcWidth}x${srcHeight}`); 29 30 const scaleDownBy = encoding.scaleResolutionDownBy; 31 const expectedWidth = srcWidth / scaleDownBy; 32 const expectedHeight = srcHeight / scaleDownBy; 33 const margin = srcWidth * 0.1; 34 const width = receiverElement.videoWidth; 35 const height = receiverElement.videoHeight; 36 const rid = encoding.rid; 37 ok(width >= expectedWidth - margin && width <= expectedWidth + margin, 38 `Width ${width} should be within 10% of ${expectedWidth} for rid '${rid}'`); 39 ok(height >= expectedHeight - margin && height <= expectedHeight + margin, 40 `Height ${height} should be within 10% of ${expectedHeight} for rid '${rid}'`); 41 } 42 43 async function checkVideoElements(senderElement, receiverElements, encodings) { 44 is(receiverElements.length, encodings.length, 'Number of video elements should match number of encodings'); 45 info('Waiting for sender video element to start playing'); 46 await helper.checkVideoPlaying(senderElement); 47 for (let i = 0; i < encodings.length; i++) { 48 await checkVideoElement(senderElement, receiverElements[i], encodings[i]); 49 } 50 } 51 52 async function checkSenderStats(sender) { 53 const senderStats = await sender.getStats(); 54 checkSenderStats(senderStats, encodings.length); 55 checkExpectedFields(senderStats); 56 pedanticChecks(senderStats); 57 } 58 59 async function waitForResizeEvents(elements) { 60 return Promise.all(elements.map(elem => haveEvent(elem, 'resize'))); 61 } 62 63 const encodings = [{ rid: "0", maxBitrate: 40000, scaleResolutionDownBy: 1.9 }, 64 { rid: "1", maxBitrate: 40000, scaleResolutionDownBy: 3.5 }, 65 { rid: "2", maxBitrate: 40000, scaleResolutionDownBy: 6.8 }]; 66 67 await pushPrefs( 68 // 180Kbps was determined empirically, set well-higher than 69 // the 80Kbps+overhead needed for the two simulcast streams. 70 // 100Kbps was apparently too low. 71 ['media.peerconnection.video.min_bitrate_estimate', 180*1000]); 72 73 // [TODO] re-enable HW decoder after bug 1526207 is fixed. 74 if (navigator.userAgent.includes("Android")) { 75 await pushPrefs(["media.navigator.mediadatadecoder_vpx_enabled", false]); 76 } 77 78 79 const offerer = new RTCPeerConnection(); 80 const answerer = new RTCPeerConnection(); 81 82 const add = (pc, can, failed) => can && pc.addIceCandidate(can).catch(failed); 83 offerer.onicecandidate = e => add(answerer, e.candidate, generateErrorCallback()); 84 answerer.onicecandidate = e => add(offerer, e.candidate, generateErrorCallback()); 85 86 const metadataToBeLoaded = []; 87 answerer.ontrack = (e) => { 88 metadataToBeLoaded.push(getPlaybackWithLoadedMetadata(e.track)); 89 }; 90 91 // One send transceiver, that will be used to send both simulcast streams 92 const videoStream = emitter.stream(); 93 offerer.addTrack(videoStream.getVideoTracks()[0], videoStream); 94 const senderElement = document.createElement('video'); 95 senderElement.autoplay = true; 96 senderElement.srcObject = videoStream; 97 senderElement.id = videoStream.id 98 99 const sender = offerer.getSenders()[0]; 100 sender.setParameters({encodings}); 101 102 const offer = await offerer.createOffer(); 103 104 const mungedOffer = ridToMid(offer); 105 info(`Transformed send simulcast offer to multiple m-sections: ${offer.sdp} to ${mungedOffer}`); 106 107 await answerer.setRemoteDescription({type: "offer", sdp: mungedOffer}); 108 await offerer.setLocalDescription(offer); 109 110 const rids = answerer.getTransceivers().map(t => t.mid); 111 is(rids.length, 3, 'Should have 3 mids in offer'); 112 ok(rids[0], 'First mid should be non-empty'); 113 ok(rids[1], 'Second mid should be non-empty'); 114 ok(rids[2], 'Third mid should be non-empty'); 115 info(`rids: ${JSON.stringify(rids)}`); 116 117 const answer = await answerer.createAnswer(); 118 119 const mungedAnswer = midToRid(answer); 120 info(`Transformed recv answer to simulcast: ${answer.sdp} to ${mungedAnswer}`); 121 await offerer.setRemoteDescription({type: "answer", sdp: mungedAnswer}); 122 await answerer.setLocalDescription(answer); 123 124 is(metadataToBeLoaded.length, 3, 'Offerer should have gotten 3 ontrack events'); 125 emitter.start(); 126 info('Waiting for 3 loadedmetadata events'); 127 const videoElems = await Promise.all(metadataToBeLoaded); 128 await checkVideoElements(senderElement, videoElems, encodings); 129 emitter.stop(); 130 131 await Promise.all([waitForSyncedRtcp(offerer), waitForSyncedRtcp(answerer)]); 132 133 info(`Changing source resolution to 1280x720`); 134 emitter.size(1280, 720); 135 emitter.start(); 136 await waitForResizeEvents([senderElement, ...videoElems]); 137 await checkVideoElements(senderElement, videoElems, encodings); 138 await checkSenderStats(sender); 139 140 encodings[0].scaleResolutionDownBy = 1; 141 encodings[1].scaleResolutionDownBy = 2; 142 encodings[2].scaleResolutionDownBy = 3; 143 info(`Changing encodings to ${JSON.stringify(encodings)}`); 144 await sender.setParameters({encodings}); 145 await waitForResizeEvents(videoElems); 146 await checkVideoElements(senderElement, videoElems, encodings); 147 await checkSenderStats(sender); 148 149 encodings[0].scaleResolutionDownBy = 6; 150 encodings[1].scaleResolutionDownBy = 5; 151 encodings[2].scaleResolutionDownBy = 4; 152 info(`Changing encodings to ${JSON.stringify(encodings)}`); 153 await sender.setParameters({encodings}); 154 await waitForResizeEvents(videoElems); 155 await checkVideoElements(senderElement, videoElems, encodings); 156 await checkSenderStats(sender); 157 158 encodings[0].scaleResolutionDownBy = 4; 159 encodings[1].scaleResolutionDownBy = 1; 160 encodings[2].scaleResolutionDownBy = 2; 161 info(`Changing encodings to ${JSON.stringify(encodings)}`); 162 await sender.setParameters({encodings}); 163 await waitForResizeEvents(videoElems); 164 await checkVideoElements(senderElement, videoElems, encodings); 165 await checkSenderStats(sender); 166 167 emitter.stop(); 168 videoStream.getVideoTracks()[0].stop(); 169 offerer.close(); 170 answerer.close(); 171 }); 172 173 </script> 174 </pre> 175 </body> 176 </html>