toolkit/content/aboutWebrtc.xhtml

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 <?xml version="1.0" encoding="UTF-8"?>
michael@0 2 <!-- This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 - License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
michael@0 5
michael@0 6
michael@0 7 <!DOCTYPE html [
michael@0 8 <!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> %htmlDTD;
michael@0 9 ]>
michael@0 10
michael@0 11 <html xmlns="http://www.w3.org/1999/xhtml">
michael@0 12 <head>
michael@0 13 <title>Webrtc Internals</title>
michael@0 14 </head>
michael@0 15 <script>
michael@0 16
michael@0 17
michael@0 18 function displayLogs(logs) {
michael@0 19 var logsDiv = document.getElementById('logs');
michael@0 20 while (logsDiv.lastChild) {
michael@0 21 logsDiv.removeChild(logsDiv.lastChild);
michael@0 22 }
michael@0 23 logsDiv.appendChild(document.createElement('h3'))
michael@0 24 .appendChild(document.createTextNode('Logging:'));
michael@0 25 logs.forEach(function(logLine){
michael@0 26 logsDiv.appendChild(document.createElement('div'))
michael@0 27 .appendChild(document.createTextNode(logLine));
michael@0 28 });
michael@0 29 }
michael@0 30
michael@0 31 function candidateTypeString(cand) {
michael@0 32 if (cand.type == "localcandidate") {
michael@0 33 if (cand.candidateType == "relayed") {
michael@0 34 return cand.candidateType + '-' + cand.mozLocalTransport;
michael@0 35 }
michael@0 36 }
michael@0 37 return cand.candidateType;
michael@0 38 }
michael@0 39
michael@0 40 function candidateAddrString(cand) {
michael@0 41 return cand.ipAddress + ':' +
michael@0 42 cand.portNumber + '/' +
michael@0 43 cand.transport + '(' +
michael@0 44 candidateTypeString(cand) + ')';
michael@0 45 }
michael@0 46
michael@0 47 function buildCandPairTableRow(candPair, localCand, remoteCand) {
michael@0 48 var row = document.createElement('tr');
michael@0 49 row.onclick = function() {
michael@0 50 WebrtcGlobalInformation.getLogging("CAND-PAIR(" + row.id, displayLogs);
michael@0 51 }
michael@0 52
michael@0 53 if (localCand) {
michael@0 54 row.appendChild(document.createElement('td'))
michael@0 55 .appendChild(document.createTextNode(candidateAddrString(localCand)));
michael@0 56 } else {
michael@0 57 row.appendChild(document.createElement('td'))
michael@0 58 .appendChild(document.createTextNode(candPair.localCandidateId));
michael@0 59 }
michael@0 60
michael@0 61 if (remoteCand) {
michael@0 62 row.appendChild(document.createElement('td'))
michael@0 63 .appendChild(document.createTextNode(candidateAddrString(remoteCand)));
michael@0 64 } else {
michael@0 65 row.appendChild(document.createElement('td'))
michael@0 66 .appendChild(document.createTextNode(candPair.remoteCandidateId));
michael@0 67 }
michael@0 68
michael@0 69 row.appendChild(document.createElement('td'))
michael@0 70 .appendChild(document.createTextNode(candPair.state));
michael@0 71 row.appendChild(document.createElement('td'))
michael@0 72 .appendChild(document.createTextNode(candPair.mozPriority));
michael@0 73
michael@0 74 row.appendChild(document.createElement('td'))
michael@0 75 .appendChild(document.createTextNode(candPair.nominated ? '*' : ''));
michael@0 76 row.appendChild(document.createElement('td'))
michael@0 77 .appendChild(document.createTextNode(candPair.selected ? '*' : ''));
michael@0 78 return row;
michael@0 79 }
michael@0 80
michael@0 81 function buildCandTableRow(cand) {
michael@0 82 var row = document.createElement('tr');
michael@0 83
michael@0 84 row.appendChild(document.createElement('td'))
michael@0 85 .appendChild(document.createTextNode(cand.ipAddress + ':' +
michael@0 86 cand.portNumber + '/' +
michael@0 87 cand.transport));
michael@0 88
michael@0 89 row.appendChild(document.createElement('td'))
michael@0 90 .appendChild(document.createTextNode(candidateTypeString(cand)));
michael@0 91 return row;
michael@0 92 }
michael@0 93
michael@0 94 function buildCandPairTableHeader() {
michael@0 95 var headerRow = document.createElement('tr');
michael@0 96 headerRow.appendChild(document.createElement('th'))
michael@0 97 .appendChild(document.createTextNode('Local candidate'));
michael@0 98 headerRow.appendChild(document.createElement('th'))
michael@0 99 .appendChild(document.createTextNode('Remote candidate'));
michael@0 100 headerRow.appendChild(document.createElement('th'))
michael@0 101 .appendChild(document.createTextNode('ICE State'));
michael@0 102 headerRow.appendChild(document.createElement('th'))
michael@0 103 .appendChild(document.createTextNode('Priority'));
michael@0 104 headerRow.appendChild(document.createElement('th'))
michael@0 105 .appendChild(document.createTextNode('Nominated'));
michael@0 106 headerRow.appendChild(document.createElement('th'))
michael@0 107 .appendChild(document.createTextNode('Selected'));
michael@0 108 return headerRow;
michael@0 109 }
michael@0 110
michael@0 111 function buildCandTableHeader(isLocal) {
michael@0 112 var headerRow = document.createElement('tr');
michael@0 113 headerRow.appendChild(document.createElement('th'))
michael@0 114 .appendChild(document.createTextNode(isLocal ?
michael@0 115 'Local candidate addr' :
michael@0 116 'Remote candidate addr'));
michael@0 117 headerRow.appendChild(document.createElement('th'))
michael@0 118 .appendChild(document.createTextNode('Type'));
michael@0 119 return headerRow;
michael@0 120 }
michael@0 121
michael@0 122 function buildEmptyCandPairTable() {
michael@0 123 var candPairTable = document.createElement('table');
michael@0 124 candPairTable.appendChild(buildCandPairTableHeader());
michael@0 125 return candPairTable;
michael@0 126 }
michael@0 127
michael@0 128 function buildEmptyCandTable(local) {
michael@0 129 var candTable = document.createElement('table');
michael@0 130 candTable.appendChild(buildCandTableHeader(local));
michael@0 131 return candTable;
michael@0 132 }
michael@0 133
michael@0 134 function round00(num) {
michael@0 135 return Math.round(num * 100) / 100;
michael@0 136 }
michael@0 137
michael@0 138 function dumpAvStat(stat) {
michael@0 139 var div = document.createElement('div');
michael@0 140 var statsString = "";
michael@0 141 if (stat.mozAvSyncDelay !== undefined) {
michael@0 142 statsString += "A/V sync: " + stat.mozAvSyncDelay + " ms ";
michael@0 143 }
michael@0 144 if (stat.mozJitterBufferDelay !== undefined) {
michael@0 145 statsString += "Jitter-buffer delay: " + stat.mozJitterBufferDelay + " ms";
michael@0 146 }
michael@0 147 div.appendChild(document.createTextNode(statsString));
michael@0 148 return div;
michael@0 149 }
michael@0 150
michael@0 151 function dumpRtpStat(stat, label) {
michael@0 152 var div = document.createElement('div');
michael@0 153 var statsString = " " + label + new Date(stat.timestamp).toTimeString() +
michael@0 154 " " + stat.type + " SSRC: " + stat.ssrc;
michael@0 155 if (stat.packetsReceived !== undefined) {
michael@0 156 statsString += " Received: " + stat.packetsReceived + " packets";
michael@0 157 if (stat.bytesReceived !== undefined) {
michael@0 158 statsString += " (" + round00(stat.bytesReceived/1024) + " Kb)";
michael@0 159 }
michael@0 160 statsString += " Lost: " + stat.packetsLost + " Jitter: " + stat.jitter;
michael@0 161 if (stat.mozRtt !== undefined) {
michael@0 162 statsString += " RTT: " + stat.mozRtt + " ms";
michael@0 163 }
michael@0 164 } else if (stat.packetsSent !== undefined) {
michael@0 165 statsString += " Sent: " + stat.packetsSent + " packets";
michael@0 166 if (stat.bytesSent !== undefined) {
michael@0 167 statsString += " (" + round00(stat.bytesSent/1024) + " Kb)";
michael@0 168 }
michael@0 169 }
michael@0 170 div.appendChild(document.createTextNode(statsString));
michael@0 171 return div;
michael@0 172 }
michael@0 173
michael@0 174 function buildPcDiv(stats, pcDivHeading) {
michael@0 175 var newPcDiv = document.createElement('div');
michael@0 176
michael@0 177 var heading = document.createElement('h3');
michael@0 178 heading.appendChild(document.createTextNode(pcDivHeading));
michael@0 179 newPcDiv.appendChild(heading);
michael@0 180
michael@0 181 // First, ICE stats
michael@0 182 var iceHeading = document.createElement('h4');
michael@0 183 iceHeading.appendChild(document.createTextNode("ICE statistics"));
michael@0 184 newPcDiv.appendChild(iceHeading);
michael@0 185
michael@0 186 var iceTablesByComponent = {};
michael@0 187
michael@0 188 function getIceTables(componentId) {
michael@0 189 if (!iceTablesByComponent[componentId]) {
michael@0 190 iceTablesByComponent[componentId] = {
michael@0 191 candidatePairTable: buildEmptyCandPairTable(),
michael@0 192 localCandidateTable: buildEmptyCandTable(true),
michael@0 193 remoteCandidateTable: buildEmptyCandTable(false)
michael@0 194 };
michael@0 195 }
michael@0 196 return iceTablesByComponent[componentId];
michael@0 197 }
michael@0 198
michael@0 199 // Candidates
michael@0 200 var candidateMap = {}; // Used later to speed up recording of candidate pairs
michael@0 201
michael@0 202 if (stats.iceCandidateStats) {
michael@0 203 stats.iceCandidateStats.forEach(function(cand) {
michael@0 204 var tables = getIceTables(cand.componentId);
michael@0 205
michael@0 206 candidateMap[cand.id] = cand;
michael@0 207
michael@0 208 if (cand.type == "localcandidate") {
michael@0 209 tables.localCandidateTable.appendChild(buildCandTableRow(cand));
michael@0 210 } else {
michael@0 211 tables.remoteCandidateTable.appendChild(buildCandTableRow(cand));
michael@0 212 }
michael@0 213 });
michael@0 214 }
michael@0 215
michael@0 216 // Candidate pairs
michael@0 217 if (stats.iceCandidatePairStats) {
michael@0 218 stats.iceCandidatePairStats.forEach(function(candPair) {
michael@0 219 var candPairTable =
michael@0 220 getIceTables(candPair.componentId).candidatePairTable;
michael@0 221 candPairTable.appendChild(
michael@0 222 buildCandPairTableRow(candPair,
michael@0 223 candidateMap[candPair.localCandidateId],
michael@0 224 candidateMap[candPair.remoteCandidateId]));
michael@0 225 });
michael@0 226 }
michael@0 227
michael@0 228 // Now that tables are completely built, put them on the page.
michael@0 229 for (var cid in iceTablesByComponent) {
michael@0 230 if (iceTablesByComponent.hasOwnProperty(cid)) {
michael@0 231 var tables = iceTablesByComponent[cid];
michael@0 232 newPcDiv.appendChild(document.createElement('h4'))
michael@0 233 .appendChild(document.createTextNode(cid));
michael@0 234 newPcDiv.appendChild(tables.candidatePairTable);
michael@0 235 newPcDiv.appendChild(tables.localCandidateTable);
michael@0 236 newPcDiv.appendChild(tables.remoteCandidateTable);
michael@0 237 }
michael@0 238 }
michael@0 239
michael@0 240 // end of ICE stats
michael@0 241
michael@0 242 // Now, RTP stats
michael@0 243 var rtpHeading = document.createElement('h4');
michael@0 244 rtpHeading.appendChild(document.createTextNode("RTP statistics"));
michael@0 245 newPcDiv.appendChild(rtpHeading);
michael@0 246
michael@0 247 // Build map from id -> remote RTP stats (ie; stats obtained from RTCP
michael@0 248 // from the other end). This allows us to pair up local/remote stats for
michael@0 249 // the same stream more easily.
michael@0 250 var remoteRtpStatsMap = {};
michael@0 251
michael@0 252 var addRemoteStatToMap = function (rtpStat) {
michael@0 253 if (rtpStat.isRemote) {
michael@0 254 remoteRtpStatsMap[rtpStat.id] = rtpStat;
michael@0 255 }
michael@0 256 }
michael@0 257
michael@0 258 if (stats.inboundRTPStreamStats) {
michael@0 259 stats.inboundRTPStreamStats.forEach(addRemoteStatToMap);
michael@0 260 }
michael@0 261
michael@0 262 if (stats.outboundRTPStreamStats) {
michael@0 263 stats.outboundRTPStreamStats.forEach(addRemoteStatToMap);
michael@0 264 }
michael@0 265
michael@0 266 var addRtpStatPairToDocument = function (rtpStat) {
michael@0 267 if (!rtpStat.isRemote) {
michael@0 268 newPcDiv.appendChild(document.createElement('h5'))
michael@0 269 .appendChild(document.createTextNode(rtpStat.id));
michael@0 270 if (rtpStat.mozAvSyncDelay !== undefined ||
michael@0 271 rtpStat.mozJitterBufferDelay !== undefined) {
michael@0 272 newPcDiv.appendChild(dumpAvStat(rtpStat));
michael@0 273 }
michael@0 274 newPcDiv.appendChild(dumpRtpStat(rtpStat, "Local: "));
michael@0 275
michael@0 276 // Might not be receiving RTCP, so we have no idea what the
michael@0 277 // statistics look like from the perspective of the other end.
michael@0 278 if (rtpStat.remoteId) {
michael@0 279 var remoteRtpStat = remoteRtpStatsMap[rtpStat.remoteId];
michael@0 280 newPcDiv.appendChild(dumpRtpStat(remoteRtpStat, "Remote: "));
michael@0 281 }
michael@0 282 }
michael@0 283 }
michael@0 284
michael@0 285 if (stats.outboundRTPStreamStats) {
michael@0 286 stats.outboundRTPStreamStats.forEach(addRtpStatPairToDocument);
michael@0 287 }
michael@0 288
michael@0 289 if (stats.inboundRTPStreamStats) {
michael@0 290 stats.inboundRTPStreamStats.forEach(addRtpStatPairToDocument);
michael@0 291 }
michael@0 292
michael@0 293 return newPcDiv;
michael@0 294 }
michael@0 295
michael@0 296 function displayStats(globalReport) {
michael@0 297 console.log("Got stats callback.");
michael@0 298 globalReport.reports.forEach(function (report) {
michael@0 299 var pcDivHeading = 'PeerConnection:' + report.pcid;
michael@0 300
michael@0 301 var pcDiv = document.getElementById(pcDivHeading);
michael@0 302 var newPcDiv = buildPcDiv(report, pcDivHeading);
michael@0 303 newPcDiv.id = pcDivHeading;
michael@0 304
michael@0 305 if (!pcDiv) {
michael@0 306 document.getElementById('stats').appendChild(newPcDiv);
michael@0 307 } else {
michael@0 308 document.getElementById('stats').replaceChild(newPcDiv, pcDiv);
michael@0 309 }
michael@0 310 });
michael@0 311
michael@0 312 globalReport.errors.forEach(function (error) {
michael@0 313 var pcDivHeading = 'PeerConnection:' + error.pcid;
michael@0 314
michael@0 315 var pcDiv = document.getElementById(pcDivHeading);
michael@0 316 var newPcDiv = buildPcDiv(error, pcDivHeading);
michael@0 317 newPcDiv.id = pcDivHeading;
michael@0 318
michael@0 319 if (pcDiv) {
michael@0 320 document.getElementById('stats').replaceChild(newPcDiv, pcDiv);
michael@0 321 } else {
michael@0 322 document.getElementById('stats').appendChild(newPcDiv);
michael@0 323 }
michael@0 324 });
michael@0 325 }
michael@0 326
michael@0 327 </script>
michael@0 328
michael@0 329 <body id="body" onload="WebrtcGlobalInformation.getAllStats(displayStats)">
michael@0 330 <div id="stats">
michael@0 331 </div>
michael@0 332 <button onclick="WebrtcGlobalInformation.getLogging('', displayLogs)">
michael@0 333 Show/refresh logging
michael@0 334 </button>
michael@0 335 <div id="logs">
michael@0 336 </div>
michael@0 337 </body>
michael@0 338 </html>
michael@0 339 <!-- vim: softtabstop=2:shiftwidth=2:expandtab
michael@0 340 -->

mercurial