OLD | NEW |
| (Empty) |
1 /** | |
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 // StatTracker is a helper class to keep track of stats on a RTCPeerConnection | |
12 // object. It uses google visualization datatables to keep the recorded samples | |
13 // and simplify plugging them into graphs later. | |
14 // | |
15 // Usage example: | |
16 // var tracker = new StatTracker(pc, pollInterval); | |
17 // tracker.recordStat("EstimatedSendBitrate", | |
18 // "bweforvideo", "googAvailableSendBandwidth"); | |
19 // ... | |
20 // tracker.stop(); | |
21 // tracker.dataTable(); // returns the recorded values. In this case | |
22 // a table with 2 columns { Time, EstimatedSendBitrate } and a row for each | |
23 // sample taken until stop() was called. | |
24 // | |
25 function StatTracker(pc, pollInterval) { | |
26 pollInterval = pollInterval || 250; | |
27 | |
28 var dataTable = new google.visualization.DataTable(); | |
29 var timeColumnIndex = dataTable.addColumn('datetime', 'Time'); | |
30 var recording = true; | |
31 | |
32 // Set of sampling functions. Functions registered here are called | |
33 // once per getStats with the given report and a rowIndex for the | |
34 // sample period so they can extract and record the tracked variables. | |
35 var samplingFunctions = {}; | |
36 | |
37 // Accessor to the current recorded stats. | |
38 this.dataTable = function() { return dataTable; } | |
39 | |
40 // recordStat(varName, recordName, statName) adds a samplingFunction that | |
41 // records namedItem(recordName).stat(statName) from RTCStatsReport for each | |
42 // sample into a column named varName in the dataTable. | |
43 this.recordStat = function (varName, recordName, statName) { | |
44 var columnIndex = dataTable.addColumn('number', varName); | |
45 samplingFunctions[varName] = function (report, rowIndex) { | |
46 var sample; | |
47 var record = report.namedItem(recordName); | |
48 if (record) sample = record.stat(statName); | |
49 dataTable.setCell(rowIndex, columnIndex, sample); | |
50 } | |
51 } | |
52 | |
53 // Stops the polling of stats from the peer connection. | |
54 this.stop = function() { | |
55 recording = false; | |
56 } | |
57 | |
58 // RTCPeerConnection.getStats is asynchronous. In order to avoid having | |
59 // too many pending getStats requests going, this code only queues the | |
60 // next getStats with setTimeout after the previous one returns, instead | |
61 // of using setInterval. | |
62 function poll() { | |
63 pc.getStats(function (report) { | |
64 if (!recording) return; | |
65 setTimeout(poll, pollInterval); | |
66 var result = report.result(); | |
67 if (result.length < 1) return; | |
68 | |
69 var rowIndex = dataTable.addRow(); | |
70 dataTable.setCell(rowIndex, timeColumnIndex, result[0].timestamp); | |
71 for (var v in samplingFunctions) | |
72 samplingFunctions[v](report, rowIndex); | |
73 }); | |
74 } | |
75 setTimeout(poll, pollInterval); | |
76 } | |
77 | |
78 /** | |
79 * Utility method to perform a full join between data tables from StatTracker. | |
80 */ | |
81 function mergeDataTable(dataTable1, dataTable2) { | |
82 function allColumns(cols) { | |
83 var a = []; | |
84 for (var i = 1; i < cols; ++i) a.push(i); | |
85 return a; | |
86 } | |
87 return google.visualization.data.join( | |
88 dataTable1, | |
89 dataTable2, | |
90 'full', | |
91 [[0, 0]], | |
92 allColumns(dataTable1.getNumberOfColumns()), | |
93 allColumns(dataTable2.getNumberOfColumns())); | |
94 } | |
OLD | NEW |