No dual_mode on Win10+ shortcuts.
[chromium-blink-merge.git] / chrome / browser / media / webrtc_browsertest_perf.cc
blobf3883e3ebd2ea8aa14a5d25e1c648468e04b6213
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/media/webrtc_browsertest_perf.h"
7 #include "base/strings/stringprintf.h"
8 #include "base/values.h"
9 #include "chrome/test/base/in_process_browser_test.h"
10 #include "testing/perf/perf_test.h"
12 static std::string Statistic(const std::string& statistic,
13 const std::string& bucket) {
14 // A ssrc stats key will be on the form stats.<bucket>-<key>.values.
15 // This will give a json "path" which will dig into the time series for the
16 // specified statistic. Buckets can be for instance ssrc_1212344, bweforvideo,
17 // and will each contain a bunch of statistics relevant to their nature.
18 // Each peer connection has a number of such buckets.
19 return base::StringPrintf("stats.%s-%s.values", bucket.c_str(),
20 statistic.c_str());
23 static bool MaybePrintResultsForAudioReceive(
24 const std::string& ssrc, const base::DictionaryValue& pc_dict,
25 const std::string& modifier) {
26 std::string value;
27 if (!pc_dict.GetString(Statistic("audioOutputLevel", ssrc), &value)) {
28 // Not an audio receive stream.
29 return false;
32 EXPECT_TRUE(pc_dict.GetString(Statistic("bytesReceived", ssrc), &value));
33 perf_test::PrintResult(
34 "audio_bytes", modifier, "bytes_recv", value, "bytes", false);
35 EXPECT_TRUE(pc_dict.GetString(Statistic("packetsLost", ssrc), &value));
36 perf_test::PrintResult(
37 "audio_misc", modifier, "packets_lost", value, "frames", false);
39 EXPECT_TRUE(pc_dict.GetString(Statistic("googExpandRate", ssrc), &value));
40 perf_test::PrintResult(
41 "audio_rates", modifier, "goog_expand_rate", value, "%", false);
42 EXPECT_TRUE(
43 pc_dict.GetString(Statistic("googSpeechExpandRate", ssrc), &value));
44 perf_test::PrintResult(
45 "audio_rates", modifier, "goog_speech_expand_rate", value, "%", false);
46 EXPECT_TRUE(
47 pc_dict.GetString(Statistic("googSecondaryDecodedRate", ssrc), &value));
48 perf_test::PrintResult(
49 "audio_rates", modifier, "goog_secondary_decoded_rate", value, "%",
50 false);
52 return true;
55 static bool MaybePrintResultsForAudioSend(
56 const std::string& ssrc, const base::DictionaryValue& pc_dict,
57 const std::string& modifier) {
58 std::string value;
59 if (!pc_dict.GetString(Statistic("audioInputLevel", ssrc), &value)) {
60 // Not an audio send stream.
61 return false;
64 EXPECT_TRUE(pc_dict.GetString(Statistic("bytesSent", ssrc), &value));
65 perf_test::PrintResult(
66 "audio_bytes", modifier, "bytes_sent", value, "bytes", false);
67 EXPECT_TRUE(pc_dict.GetString(Statistic("googJitterReceived", ssrc), &value));
68 perf_test::PrintResult(
69 "audio_tx", modifier, "goog_jitter_recv", value, "ms", false);
70 EXPECT_TRUE(pc_dict.GetString(Statistic("googRtt", ssrc), &value));
71 perf_test::PrintResult(
72 "audio_tx", modifier, "goog_rtt", value, "ms", false);
73 return true;
76 static bool MaybePrintResultsForVideoSend(
77 const std::string& ssrc, const base::DictionaryValue& pc_dict,
78 const std::string& modifier) {
79 std::string value;
80 if (!pc_dict.GetString(Statistic("googFrameRateSent", ssrc), &value)) {
81 // Not a video send stream.
82 return false;
85 // Graph these by unit: the dashboard expects all stats in one graph to have
86 // the same unit (e.g. ms, fps, etc). Most graphs, like video_fps, will also
87 // be populated by the counterparts on the video receiving side.
88 perf_test::PrintResult(
89 "video_fps", modifier, "goog_frame_rate_sent", value, "fps", false);
90 EXPECT_TRUE(pc_dict.GetString(Statistic("googFrameRateInput", ssrc), &value));
91 perf_test::PrintResult(
92 "video_fps", modifier, "goog_frame_rate_input", value, "fps", false);
94 EXPECT_TRUE(pc_dict.GetString(Statistic("bytesSent", ssrc), &value));
95 perf_test::PrintResult(
96 "video_total_bytes", modifier, "bytes_sent", value, "bytes", false);
98 EXPECT_TRUE(pc_dict.GetString(Statistic("googFirsReceived", ssrc), &value));
99 perf_test::PrintResult(
100 "video_misc", modifier, "goog_firs_recv", value, "", false);
101 EXPECT_TRUE(pc_dict.GetString(Statistic("googNacksReceived", ssrc), &value));
102 perf_test::PrintResult(
103 "video_misc", modifier, "goog_nacks_recv", value, "", false);
105 EXPECT_TRUE(pc_dict.GetString(Statistic("googFrameWidthSent", ssrc), &value));
106 perf_test::PrintResult("video_resolution", modifier, "goog_frame_width_sent",
107 value, "pixels", false);
108 EXPECT_TRUE(
109 pc_dict.GetString(Statistic("googFrameHeightSent", ssrc), &value));
110 perf_test::PrintResult("video_resolution", modifier, "goog_frame_height_sent",
111 value, "pixels", false);
113 EXPECT_TRUE(pc_dict.GetString(Statistic("googAvgEncodeMs", ssrc), &value));
114 perf_test::PrintResult(
115 "video_tx", modifier, "goog_avg_encode_ms", value, "ms", false);
116 EXPECT_TRUE(pc_dict.GetString(Statistic("googRtt", ssrc), &value));
117 perf_test::PrintResult("video_tx", modifier, "goog_rtt", value, "ms", false);
119 EXPECT_TRUE(pc_dict.GetString(
120 Statistic("googEncodeUsagePercent", ssrc), &value));
121 perf_test::PrintResult("video_cpu_usage", modifier,
122 "goog_encode_usage_percent", value, "%", false);
123 return true;
126 static bool MaybePrintResultsForVideoReceive(
127 const std::string& ssrc, const base::DictionaryValue& pc_dict,
128 const std::string& modifier) {
129 std::string value;
130 if (!pc_dict.GetString(Statistic("googFrameRateReceived", ssrc), &value)) {
131 // Not a video receive stream.
132 return false;
135 perf_test::PrintResult(
136 "video_fps", modifier, "goog_frame_rate_recv", value, "fps", false);
137 EXPECT_TRUE(
138 pc_dict.GetString(Statistic("googFrameRateOutput", ssrc), &value));
139 perf_test::PrintResult(
140 "video_fps", modifier, "goog_frame_rate_output", value, "fps", false);
142 EXPECT_TRUE(pc_dict.GetString(Statistic("packetsLost", ssrc), &value));
143 perf_test::PrintResult("video_misc", modifier, "packets_lost", value,
144 "frames", false);
146 EXPECT_TRUE(pc_dict.GetString(Statistic("bytesReceived", ssrc), &value));
147 perf_test::PrintResult(
148 "video_total_bytes", modifier, "bytes_recv", value, "bytes", false);
150 EXPECT_TRUE(
151 pc_dict.GetString(Statistic("googFrameWidthReceived", ssrc), &value));
152 perf_test::PrintResult("video_resolution", modifier, "goog_frame_width_recv",
153 value, "pixels", false);
154 EXPECT_TRUE(
155 pc_dict.GetString(Statistic("googFrameHeightReceived", ssrc), &value));
156 perf_test::PrintResult("video_resolution", modifier, "goog_frame_height_recv",
157 value, "pixels", false);
159 EXPECT_TRUE(pc_dict.GetString(Statistic("googCurrentDelayMs", ssrc), &value));
160 perf_test::PrintResult(
161 "video_rx", modifier, "goog_current_delay_ms", value, "ms", false);
162 EXPECT_TRUE(pc_dict.GetString(Statistic("googTargetDelayMs", ssrc), &value));
163 perf_test::PrintResult(
164 "video_rx", modifier, "goog_target_delay_ms", value, "ms", false);
165 EXPECT_TRUE(pc_dict.GetString(Statistic("googDecodeMs", ssrc), &value));
166 perf_test::PrintResult("video_rx", modifier, "goog_decode_ms", value, "ms",
167 false);
168 EXPECT_TRUE(pc_dict.GetString(Statistic("googMaxDecodeMs", ssrc), &value));
169 perf_test::PrintResult(
170 "video_rx", modifier, "goog_max_decode_ms", value, "ms", false);
171 EXPECT_TRUE(pc_dict.GetString(Statistic("googJitterBufferMs", ssrc), &value));
172 perf_test::PrintResult(
173 "video_rx", modifier, "goog_jitter_buffer_ms", value, "ms", false);
174 EXPECT_TRUE(pc_dict.GetString(Statistic("googRenderDelayMs", ssrc), &value));
175 perf_test::PrintResult(
176 "video_rx", modifier, "goog_render_delay_ms", value, "ms", false);
178 return true;
181 static std::string ExtractSsrcIdentifier(const std::string& key) {
182 // Example key: ssrc_1234-someStatName. Grab the part before the dash.
183 size_t key_start_pos = 0;
184 size_t key_end_pos = key.find("-");
185 CHECK(key_end_pos != std::string::npos) << "Could not parse key " << key;
186 return key.substr(key_start_pos, key_end_pos - key_start_pos);
189 // Returns the set of unique ssrc identifiers in the call (e.g. ssrc_1234,
190 // ssrc_12356, etc). |stats_dict| is the .stats dict from one peer connection.
191 static std::set<std::string> FindAllSsrcIdentifiers(
192 const base::DictionaryValue& stats_dict) {
193 std::set<std::string> result;
194 base::DictionaryValue::Iterator stats_iterator(stats_dict);
196 while (!stats_iterator.IsAtEnd()) {
197 if (stats_iterator.key().find("ssrc_") != std::string::npos)
198 result.insert(ExtractSsrcIdentifier(stats_iterator.key()));
199 stats_iterator.Advance();
201 return result;
204 namespace test {
206 void PrintBweForVideoMetrics(const base::DictionaryValue& pc_dict,
207 const std::string& modifier) {
208 const std::string kBweStatsKey = "bweforvideo";
209 std::string value;
210 ASSERT_TRUE(pc_dict.GetString(
211 Statistic("googAvailableSendBandwidth", kBweStatsKey), &value));
212 perf_test::PrintResult(
213 "bwe_stats", modifier, "available_send_bw", value, "bit/s", false);
214 ASSERT_TRUE(pc_dict.GetString(
215 Statistic("googAvailableReceiveBandwidth", kBweStatsKey), &value));
216 perf_test::PrintResult(
217 "bwe_stats", modifier, "available_recv_bw", value, "bit/s", false);
218 ASSERT_TRUE(pc_dict.GetString(
219 Statistic("googTargetEncBitrate", kBweStatsKey), &value));
220 perf_test::PrintResult(
221 "bwe_stats", modifier, "target_enc_bitrate", value, "bit/s", false);
222 ASSERT_TRUE(pc_dict.GetString(
223 Statistic("googActualEncBitrate", kBweStatsKey), &value));
224 perf_test::PrintResult(
225 "bwe_stats", modifier, "actual_enc_bitrate", value, "bit/s", false);
226 ASSERT_TRUE(pc_dict.GetString(
227 Statistic("googTransmitBitrate", kBweStatsKey), &value));
228 perf_test::PrintResult(
229 "bwe_stats", modifier, "transmit_bitrate", value, "bit/s",false);
232 void PrintMetricsForAllStreams(const base::DictionaryValue& pc_dict,
233 const std::string& modifier) {
234 const base::DictionaryValue* stats_dict;
235 ASSERT_TRUE(pc_dict.GetDictionary("stats", &stats_dict));
236 std::set<std::string> ssrc_identifiers = FindAllSsrcIdentifiers(*stats_dict);
238 std::set<std::string>::const_iterator ssrc_iterator =
239 ssrc_identifiers.begin();
240 for (; ssrc_iterator != ssrc_identifiers.end(); ++ssrc_iterator) {
241 // Figure out which stream type this ssrc represents and print all the
242 // interesting metrics for it.
243 const std::string& ssrc = *ssrc_iterator;
244 bool did_recognize_stream_type =
245 MaybePrintResultsForAudioReceive(ssrc, pc_dict, modifier) ||
246 MaybePrintResultsForAudioSend(ssrc, pc_dict, modifier) ||
247 MaybePrintResultsForVideoReceive(ssrc, pc_dict, modifier) ||
248 MaybePrintResultsForVideoSend(ssrc, pc_dict, modifier);
249 ASSERT_TRUE(did_recognize_stream_type) << "Failed to figure out which "
250 "kind of stream SSRC " << ssrc
251 << " is. ";
255 } // namespace test