diff --git a/webrtc/modules/modules.gyp b/webrtc/modules/modules.gyp index 65c482756..5c2f77f99 100644 --- a/webrtc/modules/modules.gyp +++ b/webrtc/modules/modules.gyp @@ -173,7 +173,7 @@ 'module_common_types_unittest.cc', 'pacing/paced_sender_unittest.cc', 'remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h', - 'remote_bitrate_estimator/bitrate_estimator_unittest.cc', + 'remote_bitrate_estimator/rate_statistics_unittest.cc', 'remote_bitrate_estimator/remote_bitrate_estimator_single_stream_unittest.cc', 'remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.cc', 'remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h', diff --git a/webrtc/modules/remote_bitrate_estimator/bitrate_estimator.h b/webrtc/modules/remote_bitrate_estimator/bitrate_estimator.h deleted file mode 100644 index 9ee31eb17..000000000 --- a/webrtc/modules/remote_bitrate_estimator/bitrate_estimator.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_BITRATE_ESTIMATOR_H_ -#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_BITRATE_ESTIMATOR_H_ - -#include "webrtc/system_wrappers/interface/scoped_ptr.h" -#include "webrtc/typedefs.h" - -namespace webrtc { - -class BitRateStats { - public: - BitRateStats(); - ~BitRateStats(); - - void Init(); - void Update(uint32_t packet_size_bytes, int64_t now_ms); - uint32_t BitRate(int64_t now_ms); - - private: - void EraseOld(int64_t now_ms); - - // Numbers of bytes are kept in buckets (circular buffer), with one bucket - // per millisecond. - const int num_buckets_; - scoped_array buckets_; - - // Total number of bytes recorded in buckets. - uint32_t accumulated_bytes_; - - // Oldest time recorded in buckets. - int64_t oldest_time_; - - // Bucket index of oldest bytes recorded in buckets. - int oldest_index_; - - // To convert number of bytes in bits/second. - const float bps_coefficient_; -}; -} // namespace webrtc - -#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_BITRATE_ESTIMATOR_H_ diff --git a/webrtc/modules/remote_bitrate_estimator/bitrate_estimator.cc b/webrtc/modules/remote_bitrate_estimator/rate_statistics.cc similarity index 58% rename from webrtc/modules/remote_bitrate_estimator/bitrate_estimator.cc rename to webrtc/modules/remote_bitrate_estimator/rate_statistics.cc index 8934d43ad..4a9b44881 100644 --- a/webrtc/modules/remote_bitrate_estimator/bitrate_estimator.cc +++ b/webrtc/modules/remote_bitrate_estimator/rate_statistics.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source @@ -8,26 +8,24 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/remote_bitrate_estimator/bitrate_estimator.h" +#include "webrtc/modules/remote_bitrate_estimator/rate_statistics.h" namespace webrtc { -const int kBitrateAverageWindowMs = 500; - -BitRateStats::BitRateStats() - : num_buckets_(kBitrateAverageWindowMs + 1), // N ms in (N+1) buckets. +RateStatistics::RateStatistics(uint32_t window_size_ms, float scale) + : num_buckets_(window_size_ms + 1), // N ms in (N+1) buckets. buckets_(new uint32_t[num_buckets_]()), - accumulated_bytes_(0), + accumulated_count_(0), oldest_time_(0), oldest_index_(0), - bps_coefficient_(8.f * 1000.f / (num_buckets_ - 1)) { + scale_(scale / (num_buckets_ - 1)) { } -BitRateStats::~BitRateStats() { +RateStatistics::~RateStatistics() { } -void BitRateStats::Init() { - accumulated_bytes_ = 0; +void RateStatistics::Reset() { + accumulated_count_ = 0; oldest_time_ = 0; oldest_index_ = 0; for (int i = 0; i < num_buckets_; i++) { @@ -35,7 +33,7 @@ void BitRateStats::Init() { } } -void BitRateStats::Update(uint32_t packet_size_bytes, int64_t now_ms) { +void RateStatistics::Update(uint32_t count, int64_t now_ms) { if (now_ms < oldest_time_) { // Too old data is ignored. return; @@ -49,31 +47,31 @@ void BitRateStats::Update(uint32_t packet_size_bytes, int64_t now_ms) { if (index >= num_buckets_) { index -= num_buckets_; } - buckets_[index] += packet_size_bytes; - accumulated_bytes_ += packet_size_bytes; + buckets_[index] += count; + accumulated_count_ += count; } -uint32_t BitRateStats::BitRate(int64_t now_ms) { +uint32_t RateStatistics::Rate(int64_t now_ms) { EraseOld(now_ms); - return static_cast(accumulated_bytes_ * bps_coefficient_ + 0.5f); + return static_cast(accumulated_count_ * scale_ + 0.5f); } -void BitRateStats::EraseOld(int64_t now_ms) { +void RateStatistics::EraseOld(int64_t now_ms) { int64_t new_oldest_time = now_ms - num_buckets_ + 1; if (new_oldest_time <= oldest_time_) { return; } while (oldest_time_ < new_oldest_time) { - uint32_t num_bytes_in_oldest_bucket = buckets_[oldest_index_]; - assert(accumulated_bytes_ >= num_bytes_in_oldest_bucket); - accumulated_bytes_ -= num_bytes_in_oldest_bucket; + uint32_t count_in_oldest_bucket = buckets_[oldest_index_]; + assert(accumulated_count_ >= count_in_oldest_bucket); + accumulated_count_ -= count_in_oldest_bucket; buckets_[oldest_index_] = 0; if (++oldest_index_ >= num_buckets_) { oldest_index_ = 0; } ++oldest_time_; - if (accumulated_bytes_ == 0) { + if (accumulated_count_ == 0) { // This guarantees we go through all the buckets at most once, even if // |new_oldest_time| is far greater than |oldest_time_|. break; @@ -81,4 +79,5 @@ void BitRateStats::EraseOld(int64_t now_ms) { } oldest_time_ = new_oldest_time; } + } // namespace webrtc diff --git a/webrtc/modules/remote_bitrate_estimator/rate_statistics.h b/webrtc/modules/remote_bitrate_estimator/rate_statistics.h new file mode 100644 index 000000000..429669059 --- /dev/null +++ b/webrtc/modules/remote_bitrate_estimator/rate_statistics.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_RATE_STATISTICS_H_ +#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_RATE_STATISTICS_H_ + +#include "webrtc/system_wrappers/interface/scoped_ptr.h" +#include "webrtc/typedefs.h" + +namespace webrtc { + +class RateStatistics { + public: + // window_size = window size in ms for the rate estimation + // scale = coefficient to convert counts/ms to desired units, + // ex: if counts represents bytes, use 8*1000 to go to bits/s + RateStatistics(uint32_t window_size_ms, float scale); + ~RateStatistics(); + + void Reset(); + void Update(uint32_t count, int64_t now_ms); + uint32_t Rate(int64_t now_ms); + + private: + void EraseOld(int64_t now_ms); + + // Counters are kept in buckets (circular buffer), with one bucket + // per millisecond. + const int num_buckets_; + scoped_array buckets_; + + // Total count recorded in buckets. + uint32_t accumulated_count_; + + // Oldest time recorded in buckets. + int64_t oldest_time_; + + // Bucket index of oldest counter recorded in buckets. + int oldest_index_; + + // To convert counts/ms to desired units + const float scale_; +}; +} // namespace webrtc + +#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_RATE_STATISTICS_H_ diff --git a/webrtc/modules/remote_bitrate_estimator/bitrate_estimator_unittest.cc b/webrtc/modules/remote_bitrate_estimator/rate_statistics_unittest.cc similarity index 74% rename from webrtc/modules/remote_bitrate_estimator/bitrate_estimator_unittest.cc rename to webrtc/modules/remote_bitrate_estimator/rate_statistics_unittest.cc index 3d49ca477..0cbab30bc 100644 --- a/webrtc/modules/remote_bitrate_estimator/bitrate_estimator_unittest.cc +++ b/webrtc/modules/remote_bitrate_estimator/rate_statistics_unittest.cc @@ -9,28 +9,28 @@ */ #include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/modules/remote_bitrate_estimator/bitrate_estimator.h" +#include "webrtc/modules/remote_bitrate_estimator/rate_statistics.h" namespace { -using webrtc::BitRateStats; +using webrtc::RateStatistics; -class BitRateStatsTest : public ::testing::Test { +class RateStatisticsTest : public ::testing::Test { protected: - BitRateStatsTest() {} - BitRateStats stats_; + RateStatisticsTest() : stats_(500, 8000) {} + RateStatistics stats_; }; -TEST_F(BitRateStatsTest, TestStrictMode) { +TEST_F(RateStatisticsTest, TestStrictMode) { int64_t now_ms = 0; // Should be initialized to 0. - EXPECT_EQ(0u, stats_.BitRate(now_ms)); + EXPECT_EQ(0u, stats_.Rate(now_ms)); stats_.Update(1500, now_ms); // Expecting 24 kbps given a 500 ms window with one 1500 bytes packet. - EXPECT_EQ(24000u, stats_.BitRate(now_ms)); - stats_.Init(); + EXPECT_EQ(24000u, stats_.Rate(now_ms)); + stats_.Reset(); // Expecting 0 after init. - EXPECT_EQ(0u, stats_.BitRate(now_ms)); + EXPECT_EQ(0u, stats_.Rate(now_ms)); for (int i = 0; i < 100000; ++i) { if (now_ms % 10 == 0) { stats_.Update(1500, now_ms); @@ -38,26 +38,26 @@ TEST_F(BitRateStatsTest, TestStrictMode) { // Approximately 1200 kbps expected. Not exact since when packets // are removed we will jump 10 ms to the next packet. if (now_ms > 0 && now_ms % 500 == 0) { - EXPECT_NEAR(1200000u, stats_.BitRate(now_ms), 24000u); + EXPECT_NEAR(1200000u, stats_.Rate(now_ms), 24000u); } now_ms += 1; } now_ms += 500; // The window is 2 seconds. If nothing has been received for that time // the estimate should be 0. - EXPECT_EQ(0u, stats_.BitRate(now_ms)); + EXPECT_EQ(0u, stats_.Rate(now_ms)); } -TEST_F(BitRateStatsTest, IncreasingThenDecreasingBitrate) { +TEST_F(RateStatisticsTest, IncreasingThenDecreasingBitrate) { int64_t now_ms = 0; - stats_.Init(); + stats_.Reset(); // Expecting 0 after init. - uint32_t bitrate = stats_.BitRate(now_ms); + uint32_t bitrate = stats_.Rate(now_ms); EXPECT_EQ(0u, bitrate); // 1000 bytes per millisecond until plateau is reached. while (++now_ms < 10000) { stats_.Update(1000, now_ms); - uint32_t new_bitrate = stats_.BitRate(now_ms); + uint32_t new_bitrate = stats_.Rate(now_ms); if (new_bitrate != bitrate) { // New bitrate must be higher than previous one. EXPECT_GT(new_bitrate, bitrate); @@ -71,13 +71,13 @@ TEST_F(BitRateStatsTest, IncreasingThenDecreasingBitrate) { // 1000 bytes per millisecond until 10-second mark, 8000 kbps expected. while (++now_ms < 10000) { stats_.Update(1000, now_ms); - bitrate = stats_.BitRate(now_ms); + bitrate = stats_.Rate(now_ms); EXPECT_NEAR(8000000u, bitrate, 80000u); } // Zero bytes per millisecond until 0 is reached. while (++now_ms < 20000) { stats_.Update(0, now_ms); - uint32_t new_bitrate = stats_.BitRate(now_ms); + uint32_t new_bitrate = stats_.Rate(now_ms); if (new_bitrate != bitrate) { // New bitrate must be lower than previous one. EXPECT_LT(new_bitrate, bitrate); @@ -91,7 +91,7 @@ TEST_F(BitRateStatsTest, IncreasingThenDecreasingBitrate) { // Zero bytes per millisecond until 20-second mark, 0 kbps expected. while (++now_ms < 20000) { stats_.Update(0, now_ms); - EXPECT_EQ(0u, stats_.BitRate(now_ms)); + EXPECT_EQ(0u, stats_.Rate(now_ms)); } } } // namespace diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi index f8f7e43dd..bbd353fcd 100644 --- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi +++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator.gypi @@ -22,8 +22,8 @@ 'include/bwe_defines.h', 'include/remote_bitrate_estimator.h', 'include/rtp_to_ntp.h', - 'bitrate_estimator.cc', - 'bitrate_estimator.h', + 'rate_statistics.cc', + 'rate_statistics.h', 'rtp_to_ntp.cc', ], # source }, diff --git a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc index 8eec34283..69ebab45f 100644 --- a/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc +++ b/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc @@ -10,7 +10,7 @@ #include -#include "webrtc/modules/remote_bitrate_estimator/bitrate_estimator.h" +#include "webrtc/modules/remote_bitrate_estimator/rate_statistics.h" #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" #include "webrtc/modules/remote_bitrate_estimator/overuse_detector.h" #include "webrtc/modules/remote_bitrate_estimator/remote_rate_control.h" @@ -63,7 +63,7 @@ class RemoteBitrateEstimatorSingleStream : public RemoteBitrateEstimator { Clock* clock_; SsrcOveruseDetectorMap overuse_detectors_; - BitRateStats incoming_bitrate_; + RateStatistics incoming_bitrate_; RemoteRateControl remote_rate_; RemoteBitrateObserver* observer_; scoped_ptr crit_sect_; @@ -74,6 +74,7 @@ RemoteBitrateEstimatorSingleStream::RemoteBitrateEstimatorSingleStream( RemoteBitrateObserver* observer, Clock* clock) : clock_(clock), + incoming_bitrate_(500, 8000), observer_(observer), crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), last_process_time_(-1) { @@ -106,7 +107,7 @@ void RemoteBitrateEstimatorSingleStream::IncomingPacket( const BandwidthUsage prior_state = overuse_detector->State(); overuse_detector->Update(payload_size, -1, rtp_timestamp, arrival_time_ms); if (overuse_detector->State() == kBwOverusing) { - unsigned int incoming_bitrate = incoming_bitrate_.BitRate(arrival_time_ms); + unsigned int incoming_bitrate = incoming_bitrate_.Rate(arrival_time_ms); if (prior_state != kBwOverusing || remote_rate_.TimeToReduceFurther(arrival_time_ms, incoming_bitrate)) { // The first overuse should immediately trigger a new estimate. @@ -164,7 +165,7 @@ void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t time_now) { double mean_noise_var = sum_noise_var / static_cast(overuse_detectors_.size()); const RateControlInput input(bw_state, - incoming_bitrate_.BitRate(time_now), + incoming_bitrate_.Rate(time_now), mean_noise_var); const RateControlRegion region = remote_rate_.Update(&input, time_now); unsigned int target_bitrate = remote_rate_.UpdateBandwidthEstimate(time_now);