From 157cbbd3a734150aa702a4b46cd6d1eb10dc7be8 Mon Sep 17 00:00:00 2001 From: gnish Date: Tue, 18 Jul 2017 02:50:22 -0700 Subject: [PATCH] Added implementation of three classes: 1) MaxBandwidthFilter 2) MinRttFilter 3) CongestionWindow Added unit-tests for those classes. BUG=webrtc:7713 Review-Url: https://codereview.webrtc.org/2966403002 Cr-Commit-Position: refs/heads/master@{#19067} --- .../modules/remote_bitrate_estimator/BUILD.gn | 4 + .../test/estimators/bbr.cc | 22 ++--- .../test/estimators/bbr.h | 12 +-- .../test/estimators/congestion_window.cc | 69 ++++++++++++++++ .../test/estimators/congestion_window.h | 29 +++++-- .../estimators/congestion_window_unittest.cc | 82 +++++++++++++++++++ .../test/estimators/max_bandwidth_filter.cc | 29 +++++-- .../test/estimators/max_bandwidth_filter.h | 18 ++-- .../max_bandwidth_filter_unittest.cc | 68 +++++++++++++++ .../test/estimators/min_rtt_filter.h | 31 +++++-- .../estimators/min_rtt_filter_unittest.cc | 43 ++++++++++ 11 files changed, 359 insertions(+), 48 deletions(-) create mode 100644 webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_window.cc create mode 100644 webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_window_unittest.cc create mode 100644 webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter_unittest.cc create mode 100644 webrtc/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter_unittest.cc diff --git a/webrtc/modules/remote_bitrate_estimator/BUILD.gn b/webrtc/modules/remote_bitrate_estimator/BUILD.gn index 5a4c688431..ffe5a83bfd 100644 --- a/webrtc/modules/remote_bitrate_estimator/BUILD.gn +++ b/webrtc/modules/remote_bitrate_estimator/BUILD.gn @@ -74,6 +74,7 @@ if (rtc_include_tests) { "test/bwe_test_logging.h", "test/estimators/bbr.cc", "test/estimators/bbr.h", + "test/estimators/congestion_window.cc", "test/estimators/congestion_window.h", "test/estimators/max_bandwidth_filter.cc", "test/estimators/max_bandwidth_filter.h", @@ -177,6 +178,9 @@ if (rtc_include_tests) { "send_time_history_unittest.cc", "test/bwe_test_framework_unittest.cc", "test/bwe_unittest.cc", + "test/estimators/congestion_window_unittest.cc", + "test/estimators/max_bandwidth_filter_unittest.cc", + "test/estimators/min_rtt_filter_unittest.cc", "test/estimators/nada_unittest.cc", "test/metric_recorder_unittest.cc", ] diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc b/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc index fb7d29a387..a2463fc872 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc +++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.cc @@ -25,7 +25,7 @@ const float kHighGain = 2.885f; // time. const float kDrainGain = 1 / kHighGain; // kStartupGrowthTarget and kMaxRoundsWithoutGrowth are chosen from -// experiments,according to design document. +// experiments, according to the design document. const float kStartupGrowthTarget = 1.25f; const int kMaxRoundsWithoutGrowth = 3; } // namespace @@ -68,23 +68,23 @@ void BbrBweSender::GiveFeedback(const FeedbackPacket& feedback) { full_bandwidth_reached_ = max_bandwidth_filter_->FullBandwidthReached( kStartupGrowthTarget, kMaxRoundsWithoutGrowth); } - int now = clock_->TimeInMilliseconds(); + int now_ms = clock_->TimeInMilliseconds(); switch (mode_) { break; case STARTUP: TryExitingStartup(); break; case DRAIN: - TryExitingDrain(now); + TryExitingDrain(now_ms); break; case PROBE_BW: - TryUpdatingCyclePhase(now); + TryUpdatingCyclePhase(now_ms); break; case PROBE_RTT: - TryExitingProbeRtt(now); + TryExitingProbeRtt(now_ms); break; } - TryEnteringProbeRtt(now); + TryEnteringProbeRtt(now_ms); // TODO(gnish): implement functions updating congestion window and pacing rate // controllers. } @@ -107,14 +107,14 @@ void BbrBweSender::TryExitingStartup() { } } -void BbrBweSender::TryExitingDrain(int64_t now) {} +void BbrBweSender::TryExitingDrain(int64_t now_ms) {} -void BbrBweSender::EnterProbeBw(int64_t now) {} +void BbrBweSender::EnterProbeBw(int64_t now_ms) {} -void BbrBweSender::TryUpdatingCyclePhase(int64_t now) {} +void BbrBweSender::TryUpdatingCyclePhase(int64_t now_ms) {} -void BbrBweSender::TryEnteringProbeRtt(int64_t now) {} -void BbrBweSender::TryExitingProbeRtt(int64_t now) {} +void BbrBweSender::TryEnteringProbeRtt(int64_t now_ms) {} +void BbrBweSender::TryExitingProbeRtt(int64_t now_ms) {} int64_t BbrBweSender::TimeUntilNextProcess() { return 100; diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.h b/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.h index 06e403b2d3..a4d8d5ef63 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.h +++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.h @@ -57,12 +57,12 @@ class BbrBweSender : public BweSender { void EnterStartup(); bool UpdateBandwidthAndMinRtt(); void TryExitingStartup(); - void TryExitingDrain(int64_t now); - void EnterProbeBw(int64_t now); - void EnterProbeRtt(int64_t now); - void TryUpdatingCyclePhase(int64_t now); - void TryEnteringProbeRtt(int64_t now); - void TryExitingProbeRtt(int64_t now); + void TryExitingDrain(int64_t now_ms); + void EnterProbeBw(int64_t now_ms); + void EnterProbeRtt(int64_t now_ms); + void TryUpdatingCyclePhase(int64_t now_ms); + void TryEnteringProbeRtt(int64_t now_ms); + void TryExitingProbeRtt(int64_t now_ms); Clock* const clock_; Mode mode_; std::unique_ptr max_bandwidth_filter_; diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_window.cc b/webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_window.cc new file mode 100644 index 0000000000..a52d17d711 --- /dev/null +++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_window.cc @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2017 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. + * + */ + +#include "webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_window.h" + +#include + +#include "webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.h" + +namespace webrtc { +namespace testing { +namespace bwe { +namespace { +// kStartingCongestionWindow is used to set congestion window when bandwidth +// delay product is equal to zero, so that we don't set window to zero as well. +// Chosen randomly by me, because this value shouldn't make any significant +// difference, as bandwidth delay product is more than zero almost every time. +const int kStartingCongestionWindow = 6000; +// Size of congestion window while in PROBE_RTT mode, suggested by BBR's source +// code of QUIC's implementation. +const int kMinimumCongestionWindow = 5840; +} // namespace + +CongestionWindow::CongestionWindow() : data_inflight_bytes_(0) {} + +CongestionWindow::~CongestionWindow() {} + +int CongestionWindow::GetCongestionWindow( + BbrBweSender::Mode mode, + int64_t bandwidth_estimate_bytes_per_ms, + int64_t min_rtt_ms, + float gain) { + if (mode == BbrBweSender::PROBE_RTT) + return kMinimumCongestionWindow; + return GetTargetCongestionWindow(bandwidth_estimate_bytes_per_ms, min_rtt_ms, + gain); +} + +void CongestionWindow::PacketSent(size_t sent_packet_size_bytes) { + data_inflight_bytes_ += sent_packet_size_bytes; +} + +void CongestionWindow::AckReceived(size_t received_packet_size_bytes) { + data_inflight_bytes_ -= received_packet_size_bytes; +} + +int CongestionWindow::GetTargetCongestionWindow( + int64_t bandwidth_estimate_bytes_per_ms, + int64_t min_rtt_ms, + float gain) { + int bdp = min_rtt_ms * bandwidth_estimate_bytes_per_ms; + int congestion_window = bdp * gain; + // Congestion window could be zero in rare cases, when either no bandwidth + // estimate is available, or path's min_rtt value is zero. + if (!congestion_window) + congestion_window = gain * kStartingCongestionWindow; + return std::max(congestion_window, kMinimumCongestionWindow); +} +} // namespace bwe +} // namespace testing +} // namespace webrtc diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_window.h b/webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_window.h index 887e096004..4fc1a12548 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_window.h +++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_window.h @@ -12,22 +12,33 @@ #ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_CONGESTION_WINDOW_H_ #define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_CONGESTION_WINDOW_H_ +#include "webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.h" + namespace webrtc { namespace testing { namespace bwe { class CongestionWindow { public: - void set_gain(float gain); - size_t data_inflight(); - int64_t GetCongestionWindow(); + CongestionWindow(); + ~CongestionWindow(); + int GetCongestionWindow(BbrBweSender::Mode mode, + int64_t bandwidth_estimate, + int64_t min_rtt, + float gain); + int GetTargetCongestionWindow(int64_t bandwidth_estimate, + int64_t min_rtt, + float gain); + // Packet sent from sender, meaning it is inflight until we receive it and we + // should add packet's size to data_inflight. + void PacketSent(size_t sent_packet_size); - // Packet sent from sender, meaning it is inflight - // until we receive it and we should add packet's size to data_inflight. - void PacketSent(); + // Ack was received by sender, meaning packet is no longer inflight. + void AckReceived(size_t received_packet_size); - // Ack was received by sender, meaning - // packet is no longer inflight. - void AckReceived(); + size_t data_inflight() { return data_inflight_bytes_; } + + private: + size_t data_inflight_bytes_; }; } // namespace bwe } // namespace testing diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_window_unittest.cc b/webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_window_unittest.cc new file mode 100644 index 0000000000..bc0d370bca --- /dev/null +++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_window_unittest.cc @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2017 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. + */ + +#include "webrtc/modules/remote_bitrate_estimator/test/estimators/congestion_window.h" +#include "webrtc/modules/remote_bitrate_estimator/test/estimators/bbr.h" + +#include "webrtc/test/gtest.h" + +namespace webrtc { +namespace testing { +namespace bwe { +namespace { +// These are the same values used in CongestionWindow class. +const int64_t kStartingCongestionWindow = 6000; +const int64_t kMinimumCongestionWindow = 5840; +} // namespace + +TEST(CongestionWindowTest, InitializationCheck) { + CongestionWindow congestion_window; + congestion_window.PacketSent(0); + EXPECT_EQ(congestion_window.data_inflight(), 0u); + congestion_window.AckReceived(0); + EXPECT_EQ(congestion_window.data_inflight(), 0u); +} + +TEST(CongestionWindowTest, DataInflight) { + CongestionWindow congestion_window; + congestion_window.PacketSent(13); + EXPECT_EQ(congestion_window.data_inflight(), 13u); + congestion_window.AckReceived(12); + EXPECT_EQ(congestion_window.data_inflight(), 1u); + congestion_window.PacketSent(10); + congestion_window.PacketSent(9); + EXPECT_EQ(congestion_window.data_inflight(), 20u); + congestion_window.AckReceived(20); + EXPECT_EQ(congestion_window.data_inflight(), 0u); +} + +TEST(CongestionWindowTest, ZeroBandwidthDelayProduct) { + CongestionWindow congestion_window; + int64_t target_congestion_window = + congestion_window.GetTargetCongestionWindow(100, 0, 2.885f); + EXPECT_EQ(target_congestion_window, 2.885f * kStartingCongestionWindow); +} + +TEST(CongestionWindowTest, BelowMinimumTargetCongestionWindow) { + CongestionWindow congestion_window; + int64_t target_congestion_window = + congestion_window.GetTargetCongestionWindow(100, 2, 2.885f); + EXPECT_EQ(target_congestion_window, kMinimumCongestionWindow); +} + +TEST(CongestionWindowTest, AboveMinimumTargetCongestionWindow) { + CongestionWindow congestion_window; + int64_t target_congestion_window = + congestion_window.GetTargetCongestionWindow(100000, 2, 2.885f); + EXPECT_EQ(target_congestion_window, 577000); +} + +TEST(CongestionWindowTest, MinimumCongestionWindow) { + CongestionWindow congestion_window; + int64_t cwnd = congestion_window.GetCongestionWindow(BbrBweSender::PROBE_RTT, + 100, 100, 2.885f); + EXPECT_EQ(cwnd, kMinimumCongestionWindow); +} + +TEST(CongestionWindowTest, CalculateCongestionWindow) { + CongestionWindow congestion_window; + int64_t cwnd = congestion_window.GetCongestionWindow(BbrBweSender::STARTUP, + 100, 100, 2.885f); + EXPECT_EQ(cwnd, 28850); +} +} // namespace bwe +} // namespace testing +} // namespace webrtc diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.cc b/webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.cc index 91e99346bf..53fb59cbb0 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.cc +++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.cc @@ -14,24 +14,39 @@ namespace webrtc { namespace testing { namespace bwe { -MaxBandwidthFilter::MaxBandwidthFilter() {} +MaxBandwidthFilter::MaxBandwidthFilter() + : bandwidth_last_round_bytes_per_ms_(0), + round_bandwidth_updated_(0), + max_bandwidth_estimate_bytes_per_ms_(0), + rounds_without_growth_(0) {} MaxBandwidthFilter::~MaxBandwidthFilter() {} +// Rounds are units for packets rtt_time, after packet has been acknowledged, +// one round has passed from its send time. +void MaxBandwidthFilter::AddBandwidthSample(int64_t sample_bytes_per_ms, + int64_t round, + size_t filter_size_round) { + if (round - round_bandwidth_updated_ >= filter_size_round || + sample_bytes_per_ms >= max_bandwidth_estimate_bytes_per_ms_) { + max_bandwidth_estimate_bytes_per_ms_ = sample_bytes_per_ms; + round_bandwidth_updated_ = round; + } +} + bool MaxBandwidthFilter::FullBandwidthReached(float growth_target, int max_rounds_without_growth) { // Minimal bandwidth necessary to assume that better bandwidth can still be // found and full bandwidth is not reached. - int64_t minimal_bandwidth = bandwidth_last_round_ * growth_target; - if (max_bandwidth_estimate_ >= minimal_bandwidth) { - bandwidth_last_round_ = max_bandwidth_estimate_; + int64_t minimal_bandwidth = + bandwidth_last_round_bytes_per_ms_ * growth_target; + if (max_bandwidth_estimate_bytes_per_ms_ >= minimal_bandwidth) { + bandwidth_last_round_bytes_per_ms_ = max_bandwidth_estimate_bytes_per_ms_; rounds_without_growth_ = 0; return false; } rounds_without_growth_++; - if (rounds_without_growth_ >= max_rounds_without_growth) - return true; - return false; + return rounds_without_growth_ >= max_rounds_without_growth; } } // namespace bwe } // namespace testing diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.h b/webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.h index 01c367cab7..c873979573 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.h +++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.h @@ -12,6 +12,7 @@ #ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_MAX_BANDWIDTH_FILTER_H_ #define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_MAX_BANDWIDTH_FILTER_H_ +#include #include namespace webrtc { @@ -22,21 +23,22 @@ class MaxBandwidthFilter { MaxBandwidthFilter(); ~MaxBandwidthFilter(); - int64_t max_bandwidth_estimate() { return max_bandwidth_estimate_; } + int64_t max_bandwidth_estimate_bytes_per_ms() { + return max_bandwidth_estimate_bytes_per_ms_; + } - // Save bandwidth sample for the current round. - // We save bandwidth samples for past 10 rounds to - // provide better bandwidth estimate. - - void AddBandwidthSample(int64_t sample, int64_t round); + // Save bandwidth sample for the current round. We save bandwidth samples for + // past 10 rounds to provide better bandwidth estimate. + void AddBandwidthSample(int64_t sample, int64_t round, size_t filter_size); // Check if bandwidth has grown by certain multiplier for past x rounds, // to decide whether or not full bandwidth was reached. bool FullBandwidthReached(float growth_target, int max_rounds_without_growth); private: - int64_t bandwidth_last_round_; - int64_t max_bandwidth_estimate_; + int64_t bandwidth_last_round_bytes_per_ms_; + uint64_t round_bandwidth_updated_; + int64_t max_bandwidth_estimate_bytes_per_ms_; int64_t rounds_without_growth_; }; } // namespace bwe diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter_unittest.cc b/webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter_unittest.cc new file mode 100644 index 0000000000..36d72753a0 --- /dev/null +++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter_unittest.cc @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2017 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. + */ + +#include "webrtc/modules/remote_bitrate_estimator/test/estimators/max_bandwidth_filter.h" + +#include "webrtc/test/gtest.h" + +namespace webrtc { +namespace testing { +namespace bwe { +TEST(MaxBandwidthFilterTest, InitializationCheck) { + MaxBandwidthFilter max_bandwidth_filter; + EXPECT_EQ(max_bandwidth_filter.max_bandwidth_estimate_bytes_per_ms(), 0); +} + +TEST(MaxBandwidthFilterTest, AddOneBandwidthSample) { + MaxBandwidthFilter max_bandwidth_filter; + max_bandwidth_filter.AddBandwidthSample(13, 4, 10); + EXPECT_EQ(max_bandwidth_filter.max_bandwidth_estimate_bytes_per_ms(), 13); +} + +TEST(MaxBandwidthFilterTest, AddSeveralBandwidthSamples) { + MaxBandwidthFilter max_bandwidth_filter; + max_bandwidth_filter.AddBandwidthSample(10, 5, 10); + max_bandwidth_filter.AddBandwidthSample(13, 6, 10); + EXPECT_EQ(max_bandwidth_filter.max_bandwidth_estimate_bytes_per_ms(), 13); +} + +TEST(MaxBandwidthFilterTest, SampleTimeOut) { + MaxBandwidthFilter max_bandwidth_filter; + max_bandwidth_filter.AddBandwidthSample(13, 5, 10); + max_bandwidth_filter.AddBandwidthSample(10, 15, 10); + EXPECT_EQ(max_bandwidth_filter.max_bandwidth_estimate_bytes_per_ms(), 10); +} + +TEST(MaxBandwidthFilterTest, FullBandwidthReached) { + MaxBandwidthFilter max_bandwidth_filter; + max_bandwidth_filter.AddBandwidthSample(100, 1, 10); + EXPECT_EQ(max_bandwidth_filter.FullBandwidthReached(1.25f, 3), false); + max_bandwidth_filter.AddBandwidthSample(110, 2, 10); + EXPECT_EQ(max_bandwidth_filter.FullBandwidthReached(1.25f, 3), false); + max_bandwidth_filter.AddBandwidthSample(120, 3, 10); + EXPECT_EQ(max_bandwidth_filter.FullBandwidthReached(1.25f, 3), false); + max_bandwidth_filter.AddBandwidthSample(124, 4, 10); + EXPECT_EQ(max_bandwidth_filter.FullBandwidthReached(1.25f, 3), true); +} + +TEST(MaxBandwidthFilterTest, FullBandwidthNotReached) { + MaxBandwidthFilter max_bandwidth_filter; + max_bandwidth_filter.AddBandwidthSample(100, 1, 10); + EXPECT_EQ(max_bandwidth_filter.FullBandwidthReached(1.25f, 3), false); + max_bandwidth_filter.AddBandwidthSample(110, 2, 10); + EXPECT_EQ(max_bandwidth_filter.FullBandwidthReached(1.25f, 3), false); + max_bandwidth_filter.AddBandwidthSample(120, 3, 10); + EXPECT_EQ(max_bandwidth_filter.FullBandwidthReached(1.25f, 3), false); + max_bandwidth_filter.AddBandwidthSample(125, 4, 10); + EXPECT_EQ(max_bandwidth_filter.FullBandwidthReached(1.25f, 3), false); +} +} // namespace bwe +} // namespace testing +} // namespace webrtc diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter.h b/webrtc/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter.h index f41a4f0dad..8c9823c035 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter.h +++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter.h @@ -12,20 +12,37 @@ #ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_MIN_RTT_FILTER_H_ #define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_ESTIMATORS_MIN_RTT_FILTER_H_ +#include +#include + +#include "webrtc/rtc_base/optional.h" + namespace webrtc { namespace testing { namespace bwe { class MinRttFilter { public: - MinRttFilter(); - ~MinRttFilter(); - int64_t min_rtt(); - void UpdateMinRtt(int64_t min_rtt); + MinRttFilter() {} + ~MinRttFilter() {} + + rtc::Optional min_rtt_ms() { return min_rtt_ms_; } + void add_rtt_sample(int64_t rtt_ms, int64_t now_ms) { + if (!min_rtt_ms_ || rtt_ms <= *min_rtt_ms_) { + min_rtt_ms_.emplace(rtt_ms); + discovery_time_ms_ = now_ms; + } + } + int64_t discovery_time() { return discovery_time_ms_; } // Checks whether or not last discovered min_rtt value is older than x - // seconds. - bool MinRttExpired(int64_t now); - void set_min_rtt_discovery_time(int64_t discovery_time); + // milliseconds. + bool min_rtt_expired(int64_t now_ms, int64_t min_rtt_filter_window_size_ms) { + return now_ms - discovery_time_ms_ >= min_rtt_filter_window_size_ms; + } + + private: + rtc::Optional min_rtt_ms_; + int64_t discovery_time_ms_ = 0; }; } // namespace bwe } // namespace testing diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter_unittest.cc b/webrtc/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter_unittest.cc new file mode 100644 index 0000000000..2b7d5b59b8 --- /dev/null +++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter_unittest.cc @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017 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. + */ + +#include "webrtc/modules/remote_bitrate_estimator/test/estimators/min_rtt_filter.h" + +#include "webrtc/test/gtest.h" + +namespace webrtc { +namespace testing { +namespace bwe { +TEST(MinRttFilterTest, InitializationCheck) { + MinRttFilter min_rtt_filter; + EXPECT_FALSE(min_rtt_filter.min_rtt_ms()); + EXPECT_EQ(min_rtt_filter.discovery_time(), 0); +} + +TEST(MinRttFilterTest, AddRttSample) { + MinRttFilter min_rtt_filter; + min_rtt_filter.add_rtt_sample(120, 5); + EXPECT_EQ(min_rtt_filter.min_rtt_ms(), 120); + EXPECT_EQ(min_rtt_filter.discovery_time(), 5); + min_rtt_filter.add_rtt_sample(121, 6); + EXPECT_EQ(min_rtt_filter.discovery_time(), 5); + min_rtt_filter.add_rtt_sample(119, 7); + EXPECT_EQ(min_rtt_filter.discovery_time(), 7); +} + +TEST(MinRttFilterTest, MinRttExpired) { + MinRttFilter min_rtt_filter; + min_rtt_filter.add_rtt_sample(120, 5); + EXPECT_EQ(min_rtt_filter.min_rtt_expired(10, 5), true); + EXPECT_EQ(min_rtt_filter.min_rtt_expired(9, 5), false); +} +} // namespace bwe +} // namespace testing +} // namespace webrtc