diff options
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/base/rate_counter.cc | 49 | ||||
-rw-r--r-- | remoting/base/rate_counter.h | 61 | ||||
-rw-r--r-- | remoting/base/running_average.cc | 39 | ||||
-rw-r--r-- | remoting/base/running_average.h | 57 | ||||
-rw-r--r-- | remoting/client/chromoting_client.cc | 7 | ||||
-rw-r--r-- | remoting/client/chromoting_client.h | 13 | ||||
-rw-r--r-- | remoting/client/chromoting_stats.cc | 20 | ||||
-rw-r--r-- | remoting/client/chromoting_stats.h | 29 | ||||
-rw-r--r-- | remoting/client/plugin/chromoting_instance.cc | 4 | ||||
-rw-r--r-- | remoting/client/plugin/chromoting_instance.h | 4 | ||||
-rw-r--r-- | remoting/client/plugin/chromoting_scriptable_object.cc | 11 | ||||
-rw-r--r-- | remoting/client/plugin/chromoting_scriptable_object.h | 5 | ||||
-rw-r--r-- | remoting/remoting.gyp | 6 |
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', |