summaryrefslogtreecommitdiffstats
path: root/remoting
diff options
context:
space:
mode:
Diffstat (limited to 'remoting')
-rw-r--r--remoting/base/rate_counter.cc49
-rw-r--r--remoting/base/rate_counter.h61
-rw-r--r--remoting/base/running_average.cc39
-rw-r--r--remoting/base/running_average.h57
-rw-r--r--remoting/client/chromoting_client.cc7
-rw-r--r--remoting/client/chromoting_client.h13
-rw-r--r--remoting/client/chromoting_stats.cc20
-rw-r--r--remoting/client/chromoting_stats.h29
-rw-r--r--remoting/client/plugin/chromoting_instance.cc4
-rw-r--r--remoting/client/plugin/chromoting_instance.h4
-rw-r--r--remoting/client/plugin/chromoting_scriptable_object.cc11
-rw-r--r--remoting/client/plugin/chromoting_scriptable_object.h5
-rw-r--r--remoting/remoting.gyp6
13 files changed, 302 insertions, 3 deletions
diff --git a/remoting/base/rate_counter.cc b/remoting/base/rate_counter.cc
new file mode 100644
index 0000000..fff9b6c
--- /dev/null
+++ b/remoting/base/rate_counter.cc
@@ -0,0 +1,49 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "remoting/base/rate_counter.h"
+
+namespace remoting {
+
+RateCounter::RateCounter(base::TimeDelta time_window)
+ : time_window_(time_window),
+ sum_(0) {
+}
+
+RateCounter::~RateCounter() {
+}
+
+void RateCounter::Record(int64 value) {
+ base::Time current_time = base::Time::Now();
+ Evict(current_time);
+
+ base::AutoLock auto_lock(lock_);
+ sum_ += value;
+ data_points_.push(std::make_pair(current_time, value));
+}
+
+double RateCounter::Rate() {
+ Evict(base::Time::Now());
+
+ base::AutoLock auto_lock(lock_);
+ return static_cast<double>(base::Time::kMillisecondsPerSecond) * sum_ /
+ time_window_.InMilliseconds();
+}
+
+void RateCounter::Evict(base::Time current_time) {
+ base::AutoLock auto_lock(lock_);
+
+ // Remove data points outside of the window.
+ base::Time window_start = current_time - time_window_;
+
+ while (!data_points_.empty()) {
+ if (data_points_.front().first > window_start)
+ break;
+
+ sum_ -= data_points_.front().second;
+ data_points_.pop();
+ }
+}
+
+} // namespace remoting
diff --git a/remoting/base/rate_counter.h b/remoting/base/rate_counter.h
new file mode 100644
index 0000000..c427b96
--- /dev/null
+++ b/remoting/base/rate_counter.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// RateCounter is defined to measure average rate over a given time window.
+// Rate is reported as the sum of values recorded divided by the time window.
+// This can be used for measuring bandwidth, bitrate, etc.
+
+// This class is thread-safe.
+
+#ifndef REMOTING_BASE_RATE_COUNTER_H_
+#define REMOTING_BASE_RATE_COUNTER_H_
+
+#include <queue>
+#include <utility>
+
+#include "base/basictypes.h"
+#include "base/synchronization/lock.h"
+#include "base/time.h"
+
+namespace remoting {
+
+class RateCounter {
+ public:
+ // Construct a counter for a specific time window.
+ RateCounter(base::TimeDelta time_window);
+
+ virtual ~RateCounter();
+
+ // Record the data point.
+ void Record(int64 value);
+
+ // Report the rate recorded. At the beginning of recording the numbers before
+ // |time_window| is reached the reported rate will not be accurate.
+ double Rate();
+
+ private:
+ // Helper function to evict old data points.
+ void Evict(base::Time current_time);
+
+ // A data point consists of a timestamp and a data value.
+ typedef std::pair<base::Time, int64> DataPoint;
+
+ // Duration of the time window.
+ base::TimeDelta time_window_;
+
+ // Protects |data_points_| and |sum_|.
+ base::Lock lock_;
+
+ // Keep the values of all the data points in a queue.
+ std::queue<DataPoint> data_points_;
+
+ // Sum of values in |data_points_|.
+ int64 sum_;
+
+ DISALLOW_COPY_AND_ASSIGN(RateCounter);
+};
+
+} // namespace remoting
+
+#endif // REMOTING_BASE_RATE_COUNTER_H_
diff --git a/remoting/base/running_average.cc b/remoting/base/running_average.cc
new file mode 100644
index 0000000..4daa650
--- /dev/null
+++ b/remoting/base/running_average.cc
@@ -0,0 +1,39 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/logging.h"
+#include "remoting/base/running_average.h"
+
+namespace remoting {
+
+RunningAverage::RunningAverage(int window_size)
+ : window_size_(window_size),
+ sum_(0) {
+ CHECK(window_size_);
+}
+
+RunningAverage::~RunningAverage() {
+}
+
+void RunningAverage::Record(int64 value) {
+ base::AutoLock auto_lock(lock_);
+
+ data_points_.push_back(value);
+ sum_ += value;
+
+ if (data_points_.size() > window_size_) {
+ sum_ -= data_points_[0];
+ data_points_.pop_front();
+ }
+}
+
+double RunningAverage::Average() {
+ base::AutoLock auto_lock(lock_);
+
+ if (data_points_.empty())
+ return 0;
+ return static_cast<double>(sum_) / data_points_.size();
+}
+
+} // namespace remoting
diff --git a/remoting/base/running_average.h b/remoting/base/running_average.h
new file mode 100644
index 0000000..fadea1f
--- /dev/null
+++ b/remoting/base/running_average.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// RunningAverage defined in this file is used to generate statistics for
+// bandwidth, latency and other performance metrics for remoting. Usually
+// this data comes in as a stream and fluctuates a lot. They are processed by
+// this class to generate a more stable value by taking average within a
+// window of data points.
+
+// All classes defined are thread-safe.
+
+#ifndef REMOTING_BASE_RUNNING_AVERAGE_H_
+#define REMOTING_BASE_RUNNING_AVERAGE_H_
+
+#include <deque>
+
+#include "base/basictypes.h"
+#include "base/synchronization/lock.h"
+#include "base/time.h"
+
+namespace remoting {
+
+class RunningAverage {
+ public:
+ // Construct a running average counter for a specific window size. The
+ // |windows_size| most recent values are kept and the average is reported.
+ RunningAverage(int window_size);
+
+ virtual ~RunningAverage();
+
+ // Record the provided data point.
+ void Record(int64 value);
+
+ // Return the average of data points in the last window.
+ double Average();
+
+ private:
+ // Size of the window. This is of type size_t to avoid casting when comparing
+ // with the size of |data_points_|.
+ size_t window_size_;
+
+ // Protects |data_points_| and |sum_|.
+ base::Lock lock_;
+
+ // Keep the values of all the data points.
+ std::deque<int64> data_points_;
+
+ // Sum of values in |data_points_|.
+ int64 sum_;
+
+ DISALLOW_COPY_AND_ASSIGN(RunningAverage);
+};
+
+} // namespace remoting
+
+#endif // REMOTING_BASE_RUNNING_AVERAGE_H_
diff --git a/remoting/client/chromoting_client.cc b/remoting/client/chromoting_client.cc
index aee6df4..bf1ad39 100644
--- a/remoting/client/chromoting_client.cc
+++ b/remoting/client/chromoting_client.cc
@@ -92,6 +92,10 @@ void ChromotingClient::ClientDone() {
}
}
+ChromotingStats* ChromotingClient::GetStats() {
+ return &stats_;
+}
+
void ChromotingClient::Repaint() {
if (message_loop() != MessageLoop::current()) {
message_loop()->PostTask(
@@ -125,6 +129,9 @@ void ChromotingClient::ProcessVideoPacket(const VideoPacket* packet,
return;
}
+ // Record size of the packet for statistics.
+ stats_.video_bandwidth()->Record(packet->data().size());
+
received_packets_.push_back(QueuedVideoPacket(packet, done));
if (!packet_being_processed_)
DispatchPacket();
diff --git a/remoting/client/chromoting_client.h b/remoting/client/chromoting_client.h
index 83702db..f936ddb 100644
--- a/remoting/client/chromoting_client.h
+++ b/remoting/client/chromoting_client.h
@@ -4,13 +4,14 @@
// ChromotingClient is the controller for the Client implementation.
-#ifndef REMOTING_CLIENT_CHROMOTING_CLIENT_H
-#define REMOTING_CLIENT_CHROMOTING_CLIENT_H
+#ifndef REMOTING_CLIENT_CHROMOTING_CLIENT_H_
+#define REMOTING_CLIENT_CHROMOTING_CLIENT_H_
#include <list>
#include "base/task.h"
#include "remoting/client/client_config.h"
+#include "remoting/client/chromoting_stats.h"
#include "remoting/client/chromoting_view.h"
#include "remoting/protocol/client_stub.h"
#include "remoting/protocol/connection_to_host.h"
@@ -53,6 +54,9 @@ class ChromotingClient : public protocol::ConnectionToHost::HostEventCallback,
void Stop();
void ClientDone();
+ // Return the stats recorded by this client.
+ ChromotingStats* GetStats();
+
// Signals that the associated view may need updating.
virtual void Repaint();
@@ -125,6 +129,9 @@ class ChromotingClient : public protocol::ConnectionToHost::HostEventCallback,
// safe to dispatch another message.
bool packet_being_processed_;
+ // Record the statistics of the connection.
+ ChromotingStats stats_;
+
DISALLOW_COPY_AND_ASSIGN(ChromotingClient);
};
@@ -132,4 +139,4 @@ class ChromotingClient : public protocol::ConnectionToHost::HostEventCallback,
DISABLE_RUNNABLE_METHOD_REFCOUNT(remoting::ChromotingClient);
-#endif // REMOTING_CLIENT_CHROMOTING_CLIENT_H
+#endif // REMOTING_CLIENT_CHROMOTING_CLIENT_H_
diff --git a/remoting/client/chromoting_stats.cc b/remoting/client/chromoting_stats.cc
new file mode 100644
index 0000000..33f10173bf
--- /dev/null
+++ b/remoting/client/chromoting_stats.cc
@@ -0,0 +1,20 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "remoting/client/chromoting_stats.h"
+
+namespace {
+
+// The default window of bandwidth in seconds.
+static const int kBandwidthWindow = 3;
+
+} // namespace
+
+namespace remoting {
+
+ChromotingStats::ChromotingStats()
+ : video_bandwidth_(base::TimeDelta::FromSeconds(kBandwidthWindow)) {
+}
+
+} // namespace remoting
diff --git a/remoting/client/chromoting_stats.h b/remoting/client/chromoting_stats.h
new file mode 100644
index 0000000..171c46e
--- /dev/null
+++ b/remoting/client/chromoting_stats.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// ChromotingStats defines a bundle of performance counters and statistics
+// for chromoting.
+
+#ifndef REMOTING_CLIENT_CHROMOTING_STATS_H_
+#define REMOTING_CLIENT_CHROMOTING_STATS_H_
+
+#include "remoting/base/rate_counter.h"
+
+namespace remoting {
+
+class ChromotingStats {
+ public:
+ ChromotingStats();
+
+ RateCounter* video_bandwidth() { return &video_bandwidth_; }
+
+ private:
+ RateCounter video_bandwidth_;
+
+ DISALLOW_COPY_AND_ASSIGN(ChromotingStats);
+};
+
+} // namespace remoting
+
+#endif // REMOTING_CLIENT_CHROMOTING_STATS_H_
diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc
index 45497c5..a23598c 100644
--- a/remoting/client/plugin/chromoting_instance.cc
+++ b/remoting/client/plugin/chromoting_instance.cc
@@ -277,4 +277,8 @@ pp::Var ChromotingInstance::GetInstanceObject() {
return instance_object_;
}
+ChromotingStats* ChromotingInstance::GetStats() {
+ return client_->GetStats();
+}
+
} // namespace remoting
diff --git a/remoting/client/plugin/chromoting_instance.h b/remoting/client/plugin/chromoting_instance.h
index 44c4c18..8c5aee8 100644
--- a/remoting/client/plugin/chromoting_instance.h
+++ b/remoting/client/plugin/chromoting_instance.h
@@ -39,6 +39,7 @@ class ConnectionToHost;
} // namespace protocol
class ChromotingClient;
+class ChromotingStats;
class ClientContext;
class InputHandler;
class JingleThread;
@@ -78,6 +79,9 @@ class ChromotingInstance : public pp::Instance {
void LogDebugInfo(const std::string& info);
+ // Return statistics record by ChromotingClient.
+ ChromotingStats* GetStats();
+
private:
FRIEND_TEST_ALL_PREFIXES(ChromotingInstanceTest, TestCaseSetup);
diff --git a/remoting/client/plugin/chromoting_scriptable_object.cc b/remoting/client/plugin/chromoting_scriptable_object.cc
index 9a3e2c0..64d6cd5 100644
--- a/remoting/client/plugin/chromoting_scriptable_object.cc
+++ b/remoting/client/plugin/chromoting_scriptable_object.cc
@@ -8,6 +8,7 @@
#include "base/stringprintf.h"
#include "ppapi/cpp/var.h"
#include "remoting/client/client_config.h"
+#include "remoting/client/chromoting_stats.h"
#include "remoting/client/plugin/chromoting_instance.h"
#include "remoting/client/plugin/pepper_xmpp_proxy.h"
@@ -26,6 +27,7 @@ const char kLoginChallenge[] = "loginChallenge";
const char kSendIq[] = "sendIq";
const char kQualityAttribute[] = "quality";
const char kStatusAttribute[] = "status";
+const char kVideoBandwidthAttribute[] = "videoBandwidth";
} // namespace
@@ -69,6 +71,9 @@ void ChromotingScriptableObject::Init() {
AddAttribute(kDesktopWidth, Var(0));
AddAttribute(kDesktopHeight, Var(0));
+ // Statistics.
+ AddAttribute(kVideoBandwidthAttribute, Var());
+
AddMethod("connect", &ChromotingScriptableObject::DoConnect);
AddMethod("connectSandboxed",
&ChromotingScriptableObject::DoConnectSandboxed);
@@ -126,6 +131,12 @@ Var ChromotingScriptableObject::GetProperty(const Var& name, Var* exception) {
return ScriptableObject::GetProperty(name, exception);
}
+ // If this is a statistics attribute then return the value from
+ // ChromotingStats structure.
+ if (name.AsString() == kVideoBandwidthAttribute) {
+ return instance_->GetStats()->video_bandwidth()->Rate();
+ }
+
// TODO(ajwong): This incorrectly return a null object if a function
// property is requested.
return properties_[iter->second].attribute;
diff --git a/remoting/client/plugin/chromoting_scriptable_object.h b/remoting/client/plugin/chromoting_scriptable_object.h
index 09ac054..399fb6d 100644
--- a/remoting/client/plugin/chromoting_scriptable_object.h
+++ b/remoting/client/plugin/chromoting_scriptable_object.h
@@ -13,6 +13,11 @@
//
// // Connection status.
// readonly attribute unsigned short status;
+//
+// // Statistics.
+// // Video Bandwidth in bytes per second.
+// readonly attribute float videoBandwidth;
+//
// // Constants for connection status.
// const unsigned short STATUS_UNKNOWN = 0;
// const unsigned short STATUS_CONNECTING = 1;
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index f2080f1..74c5817 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -159,6 +159,10 @@
'base/encoder_vp8.h',
'base/encoder_row_based.cc',
'base/encoder_row_based.h',
+ 'base/rate_counter.cc',
+ 'base/rate_counter.h',
+ 'base/running_average.cc',
+ 'base/running_avarage.h',
'base/tracer.cc',
'base/tracer.h',
'base/types.h',
@@ -272,6 +276,8 @@
'sources': [
'client/chromoting_client.cc',
'client/chromoting_client.h',
+ 'client/chromoting_stats.cc',
+ 'client/chromoting_stats.h',
'client/chromoting_view.cc',
'client/chromoting_view.h',
'client/client_config.h',