RTCEncodedFrame-timestamps-helper.js (4170B)
1 'use strict'; 2 3 // This file depends on `webrtc/RTCPeerConnection-helper.js` 4 // which should be loaded from the main HTML file. 5 6 // TODO: Replace with IETF link. 7 var kAbsCaptureTime = 8 'http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time'; 9 10 function addHeaderExtensionToSdp(sdp, uri) { 11 // Find the highest used header extension id by sorting the extension ids 12 // used, eliminating duplicates and adding one. This is not quite correct but 13 // this code will go away with the header extension API. 14 const usedIds = 15 sdp.split('\n') 16 .filter(line => line.startsWith('a=extmap:')) 17 .map(line => parseInt(line.split(' ')[0].substring(9), 10)) 18 .sort((a, b) => a - b) 19 .filter((item, index, array) => array.indexOf(item) === index); 20 const nextId = usedIds[usedIds.length - 1] + 1; 21 const extmapLine = 'a=extmap:' + nextId + ' ' + uri + '\r\n'; 22 23 const sections = sdp.split('\nm=').map((part, index) => { 24 return (index > 0 ? 'm=' + part : part).trim() + '\r\n'; 25 }); 26 const sessionPart = sections.shift(); 27 return sessionPart + 28 sections.map(mediaSection => mediaSection + extmapLine).join(''); 29 } 30 31 async function addAbsCaptureTimeAndExchangeOffer(caller, callee) { 32 let offer = await caller.createOffer(); 33 34 // Absolute capture time header extension may not be offered by default, 35 // in such case, munge the SDP. 36 offer.sdp = addHeaderExtensionToSdp(offer.sdp, kAbsCaptureTime); 37 38 await caller.setLocalDescription(offer); 39 return callee.setRemoteDescription(offer); 40 } 41 42 async function checkAbsCaptureTimeAndExchangeAnswer( 43 caller, callee, absCaptureTimeAnswered) { 44 let answer = await callee.createAnswer(); 45 46 const extmap = new RegExp('a=extmap:\\d+ ' + kAbsCaptureTime + '\r\n', 'g'); 47 if (answer.sdp.match(extmap) == null) { 48 // We expect that absolute capture time RTP header extension is answered. 49 // But if not, there is no need to proceed with the test. 50 assert_false( 51 absCaptureTimeAnswered, 52 'Absolute capture time RTP ' + 53 'header extension is not answered'); 54 } else { 55 if (!absCaptureTimeAnswered) { 56 // We expect that absolute capture time RTP header extension is not 57 // answered, but it is, then we munge the answer to remove it. 58 answer.sdp = answer.sdp.replace(extmap, ''); 59 } 60 } 61 62 await callee.setLocalDescription(answer); 63 return caller.setRemoteDescription(answer); 64 } 65 66 async function exchangeOfferAndListenToOntrack( 67 t, caller, callee, absCaptureTimeOffered) { 68 const ontrackPromise = addEventListenerPromise(t, callee, 'track'); 69 // Absolute capture time header extension is expected not offered by default, 70 // and thus munging is needed to enable it. 71 await absCaptureTimeOffered ? 72 addAbsCaptureTimeAndExchangeOffer(caller, callee) : 73 exchangeOffer(caller, callee); 74 return ontrackPromise; 75 } 76 77 async function initiateCall( 78 t, streamOptions, enableAbsCaptureTime, worker, enableSenderTransform, 79 enableReceiverTransform) { 80 const caller = new RTCPeerConnection(); 81 t.add_cleanup(() => caller.close()); 82 const callee = new RTCPeerConnection(); 83 t.add_cleanup(() => callee.close()); 84 const senderTransform = enableSenderTransform ? 85 new RTCRtpScriptTransform(worker, {name: 'sender'}) : 86 null; 87 const receiverTransform = enableReceiverTransform ? 88 new RTCRtpScriptTransform(worker, {name: 'receiver'}) : 89 null; 90 91 92 const stream = await getNoiseStream(streamOptions); 93 stream.getTracks().forEach(track => { 94 const sender = caller.addTrack(track, stream); 95 if (enableSenderTransform) { 96 sender.transform = senderTransform; 97 } 98 t.add_cleanup(() => track.stop()); 99 }); 100 101 callee.ontrack = 102 e => { 103 if (enableReceiverTransform) { 104 e.receiver.transform = receiverTransform; 105 } 106 } 107 108 exchangeIceCandidates(caller, callee); 109 110 await exchangeOfferAndListenToOntrack( 111 t, caller, callee, enableAbsCaptureTime); 112 113 // Exchange answer and check whether the absolute capture time RTP header 114 // extension is answered. 115 await checkAbsCaptureTimeAndExchangeAnswer( 116 caller, callee, enableAbsCaptureTime); 117 }