Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Unified Diff: remoting/client/plugin/chromoting_instance.cc

Issue 1181743005: Report video and network stats averaged over 1s, and create corresponding UMA metrics. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Declare time-window constants as static. Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: remoting/client/plugin/chromoting_instance.cc
diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc
index c32d31ded27bcd4d333f047d9af82c1536d5442a..e08a4bc68be3b52b4d20838783a1e913e4a84df0 100644
--- a/remoting/client/plugin/chromoting_instance.cc
+++ b/remoting/client/plugin/chromoting_instance.cc
@@ -32,6 +32,7 @@
#include "ppapi/cpp/dev/url_util_dev.h"
#include "ppapi/cpp/image_data.h"
#include "ppapi/cpp/input_event.h"
+#include "ppapi/cpp/private/uma_private.h"
#include "ppapi/cpp/rect.h"
#include "ppapi/cpp/var_array_buffer.h"
#include "ppapi/cpp/var_dictionary.h"
@@ -67,12 +68,29 @@ namespace {
// Default DPI to assume for old clients that use notifyClientResolution.
const int kDefaultDPI = 96;
-// Interval at which to sample performance statistics.
-const int kPerfStatsIntervalMs = 1000;
-
// URL scheme used by Chrome apps and extensions.
const char kChromeExtensionUrlScheme[] = "chrome-extension";
+// The boundary value for the FPS histogram: we don't expect video frame-rate to
+// be greater than 40fps.
Wez 2015/07/08 23:42:29 Why not? Where does the 40fps come from? What happ
anandc 2015/07/09 19:17:10 The 40fps came from our expected happy-path scenar
+// Histograms expect samples to be less than the boundary value, so set to 41.
+const int kMaxFrameRate = 41;
Wez 2015/07/08 23:42:29 nit: Blank line after this.
anandc 2015/07/09 19:17:10 Done.
+// For bandwidth, we'll use a histogram ranging from 0 to 1MB/s, spread across
Wez 2015/07/08 23:42:29 Why is 1MB/s the maximum?
anandc 2015/07/09 19:17:10 Added clarification.
+// 1000 buckets.
+// Histograms are log-scaled by default. This results in fine-grained buckets at
+// lower values and wider-ranged buckets closer to the maximum.
+// Values above the maximum defined here end up in the right-most bucket.
+// See $/src/base/metrics/histogram.h for more details.
+const int kBandwidthHistogramMin = 1;
+const int kBandwidthHistogramMax = 1024000;
+const int kBandwidthHistogramNumBuckets = 1000;
+
+// For the latency metrics, we'll set the max histogram value to 20,000ms, split
+// over 1000 buckets.
Wez 2015/07/08 23:42:29 Again, explain why these numbers were chosen?
anandc 2015/07/09 19:17:10 Removed from this CL.
+const int kLatencyHistogramMin = 1;
+const int kLatencyHistogramMax = 20000;
+const int kLatencyHistogramNumBuckets = 1000;
+
#if defined(USE_OPENSSL)
// Size of the random seed blob used to initialize RNG in libjingle. Libjingle
// uses the seed only for OpenSSL builds. OpenSSL needs at least 32 bytes of
@@ -728,11 +746,17 @@ void ChromotingInstance::HandleConnect(const base::DictionaryValue& data) {
client_->Start(signal_strategy_.get(), authenticator.Pass(),
transport_factory.Pass(), host_jid, capabilities);
- // Start timer that periodically sends perf stats.
+ // Start timers that periodically send perf stats, for display and for UMA.
+ plugin_task_runner_->PostDelayedTask(
+ FROM_HERE, base::Bind(&ChromotingInstance::SendDisplayPerfStats,
+ weak_factory_.GetWeakPtr()),
+ base::TimeDelta::FromSeconds(
+ video_renderer_->GetStats()->kDisplayStatsUpdateWindowInSeconds));
Wez 2015/07/08 23:42:29 This is a constant, not a member, so you can just
anandc 2015/07/09 19:17:10 Done.
plugin_task_runner_->PostDelayedTask(
- FROM_HERE, base::Bind(&ChromotingInstance::SendPerfStats,
+ FROM_HERE, base::Bind(&ChromotingInstance::SendUMAPerfStats,
weak_factory_.GetWeakPtr()),
- base::TimeDelta::FromMilliseconds(kPerfStatsIntervalMs));
+ base::TimeDelta::FromSeconds(
+ video_renderer_->GetStats()->kUMAStatsTimeWindowInSeconds));
}
void ChromotingInstance::HandleDisconnect(const base::DictionaryValue& data) {
@@ -1044,20 +1068,24 @@ void ChromotingInstance::SendOutgoingIq(const std::string& iq) {
PostLegacyJsonMessage("sendOutgoingIq", data.Pass());
}
-void ChromotingInstance::SendPerfStats() {
+void ChromotingInstance::SendDisplayPerfStats() {
if (!video_renderer_.get()) {
return;
}
plugin_task_runner_->PostDelayedTask(
- FROM_HERE, base::Bind(&ChromotingInstance::SendPerfStats,
+ FROM_HERE, base::Bind(&ChromotingInstance::SendDisplayPerfStats,
weak_factory_.GetWeakPtr()),
- base::TimeDelta::FromMilliseconds(kPerfStatsIntervalMs));
+ base::TimeDelta::FromSeconds(
+ ChromotingStats::kDisplayStatsUpdateWindowInSeconds));
+ // Update performance stats, averaged over the past few seconds.
+ // These are eventually upstreamed to the client and available for display to
+ // the user.
Wez 2015/07/08 23:42:29 This is very vague... why "eventually", and what d
anandc 2015/07/09 19:17:10 Thanks. PTAL at latest comment.
scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue());
ChromotingStats* stats = video_renderer_->GetStats();
- data->SetDouble("videoBandwidth", stats->video_bandwidth()->Rate());
- data->SetDouble("videoFrameRate", stats->video_frame_rate()->Rate());
+ data->SetDouble("videoBandwidth", stats->video_bandwidth_display()->Rate());
+ data->SetDouble("videoFrameRate", stats->video_frame_rate_display()->Rate());
data->SetDouble("captureLatency", stats->video_capture_ms()->Average());
data->SetDouble("encodeLatency", stats->video_encode_ms()->Average());
data->SetDouble("decodeLatency", stats->video_decode_ms()->Average());
@@ -1066,6 +1094,39 @@ void ChromotingInstance::SendPerfStats() {
PostLegacyJsonMessage("onPerfStats", data.Pass());
}
+void ChromotingInstance::SendUMAPerfStats() {
+ if (!video_renderer_.get()) {
+ return;
+ }
+
+ plugin_task_runner_->PostDelayedTask(
+ FROM_HERE, base::Bind(&ChromotingInstance::SendUMAPerfStats,
+ weak_factory_.GetWeakPtr()),
+ base::TimeDelta::FromSeconds(
+ ChromotingStats::kUMAStatsTimeWindowInSeconds));
+
+ // Update UMA histograms for video frame-rate, bandwidth and latencies.
+ // These metrics will be averaged over the last second.
Wez 2015/07/08 23:42:29 Will be averaged by whom...? The UMA APIs average
anandc 2015/07/09 19:17:09 Yes, we are averaging them. Clarified.
+ ChromotingStats* stats = video_renderer_->GetStats();
+ pp::UMAPrivate uma(this);
+ uma.HistogramEnumeration("Chromoting.Video.FrameRate",
+ stats->video_frame_rate_uma()->Rate(), kMaxFrameRate);
+ uma.HistogramEnumeration("Chromoting.Video.PacketRate",
+ stats->video_packet_rate_uma()->Rate(), kMaxFrameRate);
+ uma.HistogramCustomCounts("Chromoting.Video.Bandwidth",
+ stats->video_bandwidth_uma()->Rate(), kBandwidthHistogramMin,
+ kBandwidthHistogramMax, kBandwidthHistogramNumBuckets);
+ uma.HistogramCustomTimes("Chromoting.Video.CaptureLatency",
Wez 2015/07/08 23:42:29 nit: This isn't a latency, it's the time taken to
anandc 2015/07/09 19:17:09 You are correct. The latency metrics, if uploaded
+ stats->video_capture_ms()->Average(), kLatencyHistogramMin,
+ kLatencyHistogramMax, kLatencyHistogramNumBuckets);
+ uma.HistogramCustomTimes("Chromoting.Video.EncodeLatency",
+ stats->video_encode_ms()->Average(), kLatencyHistogramMin,
+ kLatencyHistogramMax, kLatencyHistogramNumBuckets);
+ uma.HistogramCustomTimes("Chromoting.Video.RoundTripLatency",
+ stats->round_trip_ms()->Average(), kLatencyHistogramMin,
+ kLatencyHistogramMax, kLatencyHistogramNumBuckets);
+}
+
// static
void ChromotingInstance::RegisterLogMessageHandler() {
base::AutoLock lock(g_logging_lock.Get());

Powered by Google App Engine
This is Rietveld 408576698