| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/media/webrtc_browsertest_perf.h" | 5 #include "chrome/browser/media/webrtc_browsertest_perf.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
| 10 #include "base/values.h" | 10 #include "base/values.h" |
| 11 #include "chrome/test/base/in_process_browser_test.h" | 11 #include "chrome/test/base/in_process_browser_test.h" |
| 12 #include "testing/perf/perf_test.h" | 12 #include "testing/perf/perf_test.h" |
| 13 | 13 |
| 14 static std::string Statistic(const std::string& statistic, | 14 static std::string Statistic(const std::string& statistic, |
| 15 const std::string& bucket) { | 15 const std::string& bucket) { |
| 16 // A ssrc stats key will be on the form stats.<bucket>-<key>.values. | 16 // A ssrc stats key will be on the form stats.<bucket>-<key>.values. |
| 17 // This will give a json "path" which will dig into the time series for the | 17 // This will give a json "path" which will dig into the time series for the |
| 18 // specified statistic. Buckets can be for instance ssrc_1212344, bweforvideo, | 18 // specified statistic. Buckets can be for instance ssrc_1212344, bweforvideo, |
| 19 // and will each contain a bunch of statistics relevant to their nature. | 19 // and will each contain a bunch of statistics relevant to their nature. |
| 20 // Each peer connection has a number of such buckets. | 20 // Each peer connection has a number of such buckets. |
| 21 return base::StringPrintf("stats.%s-%s.values", bucket.c_str(), | 21 return base::StringPrintf("stats.%s-%s.values", bucket.c_str(), |
| 22 statistic.c_str()); | 22 statistic.c_str()); |
| 23 } | 23 } |
| 24 | 24 |
| 25 static bool MaybePrintResultsForAudioReceive( | 25 static void MaybePrintResultsForAudioReceive( |
| 26 const std::string& ssrc, const base::DictionaryValue& pc_dict, | 26 const std::string& ssrc, const base::DictionaryValue& pc_dict, |
| 27 const std::string& modifier) { | 27 const std::string& modifier) { |
| 28 std::string value; | 28 std::string value; |
| 29 if (!pc_dict.GetString(Statistic("audioOutputLevel", ssrc), &value)) { | 29 if (!pc_dict.GetString(Statistic("audioOutputLevel", ssrc), &value)) { |
| 30 // Not an audio receive stream. | 30 // Not an audio receive stream. |
| 31 return false; | 31 return; |
| 32 } | 32 } |
| 33 | 33 |
| 34 EXPECT_TRUE(pc_dict.GetString(Statistic("bytesReceived", ssrc), &value)); | 34 EXPECT_TRUE(pc_dict.GetString(Statistic("bytesReceived", ssrc), &value)); |
| 35 perf_test::PrintResult( | 35 perf_test::PrintResult( |
| 36 "audio_bytes", modifier, "bytes_recv", value, "bytes", false); | 36 "audio_bytes", modifier, "bytes_recv", value, "bytes", false); |
| 37 EXPECT_TRUE(pc_dict.GetString(Statistic("packetsLost", ssrc), &value)); | 37 EXPECT_TRUE(pc_dict.GetString(Statistic("packetsLost", ssrc), &value)); |
| 38 perf_test::PrintResult( | 38 perf_test::PrintResult( |
| 39 "audio_misc", modifier, "packets_lost", value, "frames", false); | 39 "audio_misc", modifier, "packets_lost", value, "frames", false); |
| 40 EXPECT_TRUE(pc_dict.GetString(Statistic("googJitterReceived", ssrc), &value)); | 40 EXPECT_TRUE(pc_dict.GetString(Statistic("googJitterReceived", ssrc), &value)); |
| 41 perf_test::PrintResult( | 41 perf_test::PrintResult( |
| 42 "audio_rx", modifier, "goog_jitter_recv", value, "ms", false); | 42 "audio_rx", modifier, "goog_jitter_recv", value, "ms", false); |
| 43 | 43 |
| 44 EXPECT_TRUE(pc_dict.GetString(Statistic("googExpandRate", ssrc), &value)); | 44 EXPECT_TRUE(pc_dict.GetString(Statistic("googExpandRate", ssrc), &value)); |
| 45 perf_test::PrintResult( | 45 perf_test::PrintResult( |
| 46 "audio_rates", modifier, "goog_expand_rate", value, "%", false); | 46 "audio_rates", modifier, "goog_expand_rate", value, "%", false); |
| 47 EXPECT_TRUE( | 47 EXPECT_TRUE( |
| 48 pc_dict.GetString(Statistic("googSpeechExpandRate", ssrc), &value)); | 48 pc_dict.GetString(Statistic("googSpeechExpandRate", ssrc), &value)); |
| 49 perf_test::PrintResult( | 49 perf_test::PrintResult( |
| 50 "audio_rates", modifier, "goog_speech_expand_rate", value, "%", false); | 50 "audio_rates", modifier, "goog_speech_expand_rate", value, "%", false); |
| 51 EXPECT_TRUE( | 51 EXPECT_TRUE( |
| 52 pc_dict.GetString(Statistic("googSecondaryDecodedRate", ssrc), &value)); | 52 pc_dict.GetString(Statistic("googSecondaryDecodedRate", ssrc), &value)); |
| 53 perf_test::PrintResult( | 53 perf_test::PrintResult( |
| 54 "audio_rates", modifier, "goog_secondary_decoded_rate", value, "%", | 54 "audio_rates", modifier, "goog_secondary_decoded_rate", value, "%", |
| 55 false); | 55 false); |
| 56 | |
| 57 return true; | |
| 58 } | 56 } |
| 59 | 57 |
| 60 static bool MaybePrintResultsForAudioSend( | 58 static void MaybePrintResultsForAudioSend( |
| 61 const std::string& ssrc, const base::DictionaryValue& pc_dict, | 59 const std::string& ssrc, const base::DictionaryValue& pc_dict, |
| 62 const std::string& modifier) { | 60 const std::string& modifier) { |
| 63 std::string value; | 61 std::string value; |
| 64 if (!pc_dict.GetString(Statistic("audioInputLevel", ssrc), &value)) { | 62 if (!pc_dict.GetString(Statistic("audioInputLevel", ssrc), &value)) { |
| 65 // Not an audio send stream. | 63 // Not an audio send stream. |
| 66 return false; | 64 return; |
| 67 } | 65 } |
| 68 | 66 |
| 69 EXPECT_TRUE(pc_dict.GetString(Statistic("bytesSent", ssrc), &value)); | 67 EXPECT_TRUE(pc_dict.GetString(Statistic("bytesSent", ssrc), &value)); |
| 70 perf_test::PrintResult( | 68 perf_test::PrintResult( |
| 71 "audio_bytes", modifier, "bytes_sent", value, "bytes", false); | 69 "audio_bytes", modifier, "bytes_sent", value, "bytes", false); |
| 72 EXPECT_TRUE(pc_dict.GetString(Statistic("googJitterReceived", ssrc), &value)); | 70 EXPECT_TRUE(pc_dict.GetString(Statistic("googJitterReceived", ssrc), &value)); |
| 73 perf_test::PrintResult( | 71 perf_test::PrintResult( |
| 74 "audio_tx", modifier, "goog_jitter_recv", value, "ms", false); | 72 "audio_tx", modifier, "goog_jitter_recv", value, "ms", false); |
| 75 EXPECT_TRUE(pc_dict.GetString(Statistic("googRtt", ssrc), &value)); | 73 EXPECT_TRUE(pc_dict.GetString(Statistic("googRtt", ssrc), &value)); |
| 76 perf_test::PrintResult( | 74 perf_test::PrintResult( |
| 77 "audio_tx", modifier, "goog_rtt", value, "ms", false); | 75 "audio_tx", modifier, "goog_rtt", value, "ms", false); |
| 78 return true; | |
| 79 } | 76 } |
| 80 | 77 |
| 81 static bool MaybePrintResultsForVideoSend( | 78 static void MaybePrintResultsForVideoSend( |
| 82 const std::string& ssrc, const base::DictionaryValue& pc_dict, | 79 const std::string& ssrc, const base::DictionaryValue& pc_dict, |
| 83 const std::string& modifier) { | 80 const std::string& modifier) { |
| 84 std::string value; | 81 std::string value; |
| 85 if (!pc_dict.GetString(Statistic("googFrameRateSent", ssrc), &value)) { | 82 if (!pc_dict.GetString(Statistic("googFrameRateSent", ssrc), &value)) { |
| 86 // Not a video send stream. | 83 // Not a video send stream. |
| 87 return false; | 84 return; |
| 88 } | 85 } |
| 89 | 86 |
| 90 // Graph these by unit: the dashboard expects all stats in one graph to have | 87 // Graph these by unit: the dashboard expects all stats in one graph to have |
| 91 // the same unit (e.g. ms, fps, etc). Most graphs, like video_fps, will also | 88 // the same unit (e.g. ms, fps, etc). Most graphs, like video_fps, will also |
| 92 // be populated by the counterparts on the video receiving side. | 89 // be populated by the counterparts on the video receiving side. |
| 93 perf_test::PrintResult( | 90 perf_test::PrintResult( |
| 94 "video_fps", modifier, "goog_frame_rate_sent", value, "fps", false); | 91 "video_fps", modifier, "goog_frame_rate_sent", value, "fps", false); |
| 95 EXPECT_TRUE(pc_dict.GetString(Statistic("googFrameRateInput", ssrc), &value)); | 92 EXPECT_TRUE(pc_dict.GetString(Statistic("googFrameRateInput", ssrc), &value)); |
| 96 perf_test::PrintResult( | 93 perf_test::PrintResult( |
| 97 "video_fps", modifier, "goog_frame_rate_input", value, "fps", false); | 94 "video_fps", modifier, "goog_frame_rate_input", value, "fps", false); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 118 EXPECT_TRUE(pc_dict.GetString(Statistic("googAvgEncodeMs", ssrc), &value)); | 115 EXPECT_TRUE(pc_dict.GetString(Statistic("googAvgEncodeMs", ssrc), &value)); |
| 119 perf_test::PrintResult( | 116 perf_test::PrintResult( |
| 120 "video_tx", modifier, "goog_avg_encode_ms", value, "ms", false); | 117 "video_tx", modifier, "goog_avg_encode_ms", value, "ms", false); |
| 121 EXPECT_TRUE(pc_dict.GetString(Statistic("googRtt", ssrc), &value)); | 118 EXPECT_TRUE(pc_dict.GetString(Statistic("googRtt", ssrc), &value)); |
| 122 perf_test::PrintResult("video_tx", modifier, "goog_rtt", value, "ms", false); | 119 perf_test::PrintResult("video_tx", modifier, "goog_rtt", value, "ms", false); |
| 123 | 120 |
| 124 EXPECT_TRUE(pc_dict.GetString( | 121 EXPECT_TRUE(pc_dict.GetString( |
| 125 Statistic("googEncodeUsagePercent", ssrc), &value)); | 122 Statistic("googEncodeUsagePercent", ssrc), &value)); |
| 126 perf_test::PrintResult("video_cpu_usage", modifier, | 123 perf_test::PrintResult("video_cpu_usage", modifier, |
| 127 "goog_encode_usage_percent", value, "%", false); | 124 "goog_encode_usage_percent", value, "%", false); |
| 128 return true; | |
| 129 } | 125 } |
| 130 | 126 |
| 131 static bool MaybePrintResultsForVideoReceive( | 127 static void MaybePrintResultsForVideoReceive( |
| 132 const std::string& ssrc, const base::DictionaryValue& pc_dict, | 128 const std::string& ssrc, const base::DictionaryValue& pc_dict, |
| 133 const std::string& modifier) { | 129 const std::string& modifier) { |
| 134 std::string value; | 130 std::string value; |
| 135 if (!pc_dict.GetString(Statistic("googFrameRateReceived", ssrc), &value)) { | 131 if (!pc_dict.GetString(Statistic("googFrameRateReceived", ssrc), &value)) { |
| 136 // Not a video receive stream. | 132 // Not a video receive stream. |
| 137 return false; | 133 return; |
| 138 } | 134 } |
| 139 | 135 |
| 140 perf_test::PrintResult( | 136 perf_test::PrintResult( |
| 141 "video_fps", modifier, "goog_frame_rate_recv", value, "fps", false); | 137 "video_fps", modifier, "goog_frame_rate_recv", value, "fps", false); |
| 142 EXPECT_TRUE( | 138 EXPECT_TRUE( |
| 143 pc_dict.GetString(Statistic("googFrameRateOutput", ssrc), &value)); | 139 pc_dict.GetString(Statistic("googFrameRateOutput", ssrc), &value)); |
| 144 perf_test::PrintResult( | 140 perf_test::PrintResult( |
| 145 "video_fps", modifier, "goog_frame_rate_output", value, "fps", false); | 141 "video_fps", modifier, "goog_frame_rate_output", value, "fps", false); |
| 146 | 142 |
| 147 EXPECT_TRUE(pc_dict.GetString(Statistic("packetsLost", ssrc), &value)); | 143 EXPECT_TRUE(pc_dict.GetString(Statistic("packetsLost", ssrc), &value)); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 172 false); | 168 false); |
| 173 EXPECT_TRUE(pc_dict.GetString(Statistic("googMaxDecodeMs", ssrc), &value)); | 169 EXPECT_TRUE(pc_dict.GetString(Statistic("googMaxDecodeMs", ssrc), &value)); |
| 174 perf_test::PrintResult( | 170 perf_test::PrintResult( |
| 175 "video_rx", modifier, "goog_max_decode_ms", value, "ms", false); | 171 "video_rx", modifier, "goog_max_decode_ms", value, "ms", false); |
| 176 EXPECT_TRUE(pc_dict.GetString(Statistic("googJitterBufferMs", ssrc), &value)); | 172 EXPECT_TRUE(pc_dict.GetString(Statistic("googJitterBufferMs", ssrc), &value)); |
| 177 perf_test::PrintResult( | 173 perf_test::PrintResult( |
| 178 "video_rx", modifier, "goog_jitter_buffer_ms", value, "ms", false); | 174 "video_rx", modifier, "goog_jitter_buffer_ms", value, "ms", false); |
| 179 EXPECT_TRUE(pc_dict.GetString(Statistic("googRenderDelayMs", ssrc), &value)); | 175 EXPECT_TRUE(pc_dict.GetString(Statistic("googRenderDelayMs", ssrc), &value)); |
| 180 perf_test::PrintResult( | 176 perf_test::PrintResult( |
| 181 "video_rx", modifier, "goog_render_delay_ms", value, "ms", false); | 177 "video_rx", modifier, "goog_render_delay_ms", value, "ms", false); |
| 182 | |
| 183 return true; | |
| 184 } | 178 } |
| 185 | 179 |
| 186 static std::string ExtractSsrcIdentifier(const std::string& key) { | 180 static std::string ExtractSsrcIdentifier(const std::string& key) { |
| 187 // Example key: ssrc_1234-someStatName. Grab the part before the dash. | 181 // Example key: ssrc_1234-someStatName. Grab the part before the dash. |
| 188 size_t key_start_pos = 0; | 182 size_t key_start_pos = 0; |
| 189 size_t key_end_pos = key.find("-"); | 183 size_t key_end_pos = key.find("-"); |
| 190 CHECK(key_end_pos != std::string::npos) << "Could not parse key " << key; | 184 CHECK(key_end_pos != std::string::npos) << "Could not parse key " << key; |
| 191 return key.substr(key_start_pos, key_end_pos - key_start_pos); | 185 return key.substr(key_start_pos, key_end_pos - key_start_pos); |
| 192 } | 186 } |
| 193 | 187 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 value, "bit/s", false); | 227 value, "bit/s", false); |
| 234 ASSERT_TRUE(pc_dict.GetString( | 228 ASSERT_TRUE(pc_dict.GetString( |
| 235 Statistic("googTransmitBitrate", kBweStatsKey), &value)); | 229 Statistic("googTransmitBitrate", kBweStatsKey), &value)); |
| 236 perf_test::PrintResult("bwe_stats", video_modifier, "transmit_bitrate", value, | 230 perf_test::PrintResult("bwe_stats", video_modifier, "transmit_bitrate", value, |
| 237 "bit/s", false); | 231 "bit/s", false); |
| 238 } | 232 } |
| 239 | 233 |
| 240 void PrintMetricsForAllStreams(const base::DictionaryValue& pc_dict, | 234 void PrintMetricsForAllStreams(const base::DictionaryValue& pc_dict, |
| 241 const std::string& modifier, | 235 const std::string& modifier, |
| 242 const std::string& video_codec) { | 236 const std::string& video_codec) { |
| 237 PrintMetricsForSendStreams(pc_dict, modifier, video_codec); |
| 238 PrintMetricsForRecvStreams(pc_dict, modifier, video_codec); |
| 239 } |
| 240 |
| 241 void PrintMetricsForSendStreams(const base::DictionaryValue& pc_dict, |
| 242 const std::string& modifier, |
| 243 const std::string& video_codec) { |
| 243 std::string video_modifier = | 244 std::string video_modifier = |
| 244 video_codec.empty() ? modifier : modifier + "_" + video_codec; | 245 video_codec.empty() ? modifier : modifier + "_" + video_codec; |
| 245 const base::DictionaryValue* stats_dict; | 246 const base::DictionaryValue* stats_dict; |
| 247 ASSERT_TRUE(pc_dict.GetDictionary("stats", &stats_dict)); |
| 248 std::set<std::string> ssrc_identifiers = FindAllSsrcIdentifiers(*stats_dict); |
| 249 |
| 250 std::set<std::string>::const_iterator ssrc_iterator = |
| 251 ssrc_identifiers.begin(); |
| 252 for (; ssrc_iterator != ssrc_identifiers.end(); ++ssrc_iterator) { |
| 253 const std::string& ssrc = *ssrc_iterator; |
| 254 MaybePrintResultsForAudioSend(ssrc, pc_dict, modifier); |
| 255 MaybePrintResultsForVideoSend(ssrc, pc_dict, video_modifier); |
| 256 } |
| 257 } |
| 258 |
| 259 void PrintMetricsForRecvStreams(const base::DictionaryValue& pc_dict, |
| 260 const std::string& modifier, |
| 261 const std::string& video_codec) { |
| 262 std::string video_modifier = |
| 263 video_codec.empty() ? modifier : modifier + "_" + video_codec; |
| 264 const base::DictionaryValue* stats_dict; |
| 246 ASSERT_TRUE(pc_dict.GetDictionary("stats", &stats_dict)); | 265 ASSERT_TRUE(pc_dict.GetDictionary("stats", &stats_dict)); |
| 247 std::set<std::string> ssrc_identifiers = FindAllSsrcIdentifiers(*stats_dict); | 266 std::set<std::string> ssrc_identifiers = FindAllSsrcIdentifiers(*stats_dict); |
| 248 | 267 |
| 249 std::set<std::string>::const_iterator ssrc_iterator = | 268 std::set<std::string>::const_iterator ssrc_iterator = |
| 250 ssrc_identifiers.begin(); | 269 ssrc_identifiers.begin(); |
| 251 for (; ssrc_iterator != ssrc_identifiers.end(); ++ssrc_iterator) { | 270 for (; ssrc_iterator != ssrc_identifiers.end(); ++ssrc_iterator) { |
| 252 // Figure out which stream type this ssrc represents and print all the | |
| 253 // interesting metrics for it. | |
| 254 const std::string& ssrc = *ssrc_iterator; | 271 const std::string& ssrc = *ssrc_iterator; |
| 255 bool did_recognize_stream_type = | 272 MaybePrintResultsForAudioReceive(ssrc, pc_dict, modifier); |
| 256 MaybePrintResultsForAudioReceive(ssrc, pc_dict, modifier) || | 273 MaybePrintResultsForVideoReceive(ssrc, pc_dict, video_modifier); |
| 257 MaybePrintResultsForAudioSend(ssrc, pc_dict, modifier) || | |
| 258 MaybePrintResultsForVideoReceive(ssrc, pc_dict, video_modifier) || | |
| 259 MaybePrintResultsForVideoSend(ssrc, pc_dict, video_modifier); | |
| 260 ASSERT_TRUE(did_recognize_stream_type) << "Failed to figure out which " | |
| 261 "kind of stream SSRC " << ssrc | |
| 262 << " is. "; | |
| 263 } | 274 } |
| 264 } | 275 } |
| 265 | 276 |
| 266 } // namespace test | 277 } // namespace test |
| OLD | NEW |