Tool to establish a loopback call via apprtc turn server.
For now the test keeps track of video bandwidth estimation and plots it
using google visualization libraries after the test is concluded.
There is also scripts to run a test and record the tcpdump.
BUG=3037
R=hta@webrtc.org, phoglund@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/9729004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@5707 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/tools/loopback_test/stat_tracker.js b/webrtc/tools/loopback_test/stat_tracker.js
new file mode 100644
index 0000000..49f46c3
--- /dev/null
+++ b/webrtc/tools/loopback_test/stat_tracker.js
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// StatTracker is a helper class to keep track of stats on a RTCPeerConnection
+// object. It uses google visualization datatables to keep the recorded samples
+// and simplify plugging them into graphs later.
+//
+// Usage example:
+// var tracker = new StatTracker(pc, pollInterval);
+// tracker.recordStat("EstimatedSendBitrate",
+// "bweforvideo", "googAvailableSendBandwidth");
+// ...
+// tracker.stop();
+// tracker.dataTable(); // returns the recorded values. In this case
+// a table with 2 columns { Time, EstimatedSendBitrate } and a row for each
+// sample taken until stop() was called.
+//
+function StatTracker(pc, pollInterval) {
+ pollInterval = pollInterval || 250;
+
+ var dataTable = new google.visualization.DataTable();
+ var timeColumnIndex = dataTable.addColumn('datetime', 'Time');
+ var recording = true;
+
+ // Set of sampling functions. Functions registered here are called
+ // once per getStats with the given report and a rowIndex for the
+ // sample period so they can extract and record the tracked variables.
+ var samplingFunctions = {};
+
+ // Accessor to the current recorded stats.
+ this.dataTable = function() { return dataTable; }
+
+ // recordStat(varName, recordName, statName) adds a samplingFunction that
+ // records namedItem(recordName).stat(statName) from RTCStatsReport for each
+ // sample into a column named varName in the dataTable.
+ this.recordStat = function (varName, recordName, statName) {
+ var columnIndex = dataTable.addColumn('number', varName);
+ samplingFunctions[varName] = function (report, rowIndex) {
+ var sample;
+ var record = report.namedItem(recordName);
+ if (record) sample = record.stat(statName);
+ dataTable.setCell(rowIndex, columnIndex, sample);
+ }
+ }
+
+ // Stops the polling of stats from the peer connection.
+ this.stop = function() {
+ recording = false;
+ }
+
+ // RTCPeerConnection.getStats is asynchronous. In order to avoid having
+ // too many pending getStats requests going, this code only queues the
+ // next getStats with setTimeout after the previous one returns, instead
+ // of using setInterval.
+ function poll() {
+ pc.getStats(function (report) {
+ if (!recording) return;
+ setTimeout(poll, pollInterval);
+ var result = report.result();
+ if (result.length < 1) return;
+
+ var rowIndex = dataTable.addRow();
+ dataTable.setCell(rowIndex, timeColumnIndex, result[0].timestamp);
+ for (var v in samplingFunctions)
+ samplingFunctions[v](report, rowIndex);
+ });
+ }
+ setTimeout(poll, pollInterval);
+}
+
+/**
+ * Utility method to perform a full join between data tables from StatTracker.
+ */
+function mergeDataTable(dataTable1, dataTable2) {
+ function allColumns(cols) {
+ var a = [];
+ for (var i = 1; i < cols; ++i) a.push(i);
+ return a;
+ }
+ return google.visualization.data.join(
+ dataTable1,
+ dataTable2,
+ 'full',
+ [[0, 0]],
+ allColumns(dataTable1.getNumberOfColumns()),
+ allColumns(dataTable2.getNumberOfColumns()));
+}