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}
This commit is contained in:
@ -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",
|
||||
]
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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<MaxBandwidthFilter> max_bandwidth_filter_;
|
||||
|
||||
@ -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 <algorithm>
|
||||
|
||||
#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
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
@ -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 <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
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
|
||||
|
||||
@ -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
|
||||
@ -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 <cstdint>
|
||||
#include <limits>
|
||||
|
||||
#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<int64_t> 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<int64_t> min_rtt_ms_;
|
||||
int64_t discovery_time_ms_ = 0;
|
||||
};
|
||||
} // namespace bwe
|
||||
} // namespace testing
|
||||
|
||||
@ -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
|
||||
Reference in New Issue
Block a user