blob: b36b16ddbf1d137d025e2a8a1886a950399ef753 [file] [log] [blame]
/*
* Copyright (c) 2016 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 <memory>
#include "webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h"
#include "webrtc/system_wrappers/include/clock.h"
#include "webrtc/test/gtest.h"
namespace webrtc {
namespace {
constexpr int64_t kClockInitialTime = 123456;
struct AimdRateControlStates {
std::unique_ptr<AimdRateControl> aimd_rate_control;
std::unique_ptr<SimulatedClock> simulated_clock;
};
AimdRateControlStates CreateAimdRateControlStates() {
AimdRateControlStates states;
states.aimd_rate_control.reset(new AimdRateControl());
states.simulated_clock.reset(new SimulatedClock(kClockInitialTime));
return states;
}
void InitBitrate(const AimdRateControlStates& states,
int bitrate,
int64_t now_ms) {
// Reduce the bitrate by 1000 to compensate for the Update after SetEstimate.
bitrate -= 1000;
states.aimd_rate_control->SetEstimate(bitrate, now_ms);
}
void UpdateRateControl(const AimdRateControlStates& states,
const BandwidthUsage& bandwidth_usage,
int bitrate,
int64_t now_ms) {
RateControlInput input(bandwidth_usage, rtc::Optional<uint32_t>(bitrate),
now_ms);
states.aimd_rate_control->Update(&input, now_ms);
states.aimd_rate_control->UpdateBandwidthEstimate(now_ms);
}
} // namespace
TEST(AimdRateControlTest, MinNearMaxIncreaseRateOnLowBandwith) {
auto states = CreateAimdRateControlStates();
constexpr int kBitrate = 30000;
InitBitrate(states, kBitrate, states.simulated_clock->TimeInMilliseconds());
EXPECT_EQ(4000, states.aimd_rate_control->GetNearMaxIncreaseRateBps());
}
TEST(AimdRateControlTest, NearMaxIncreaseRateIs5kbpsOn90kbpsAnd200msRtt) {
auto states = CreateAimdRateControlStates();
constexpr int kBitrate = 90000;
InitBitrate(states, kBitrate, states.simulated_clock->TimeInMilliseconds());
EXPECT_EQ(5000, states.aimd_rate_control->GetNearMaxIncreaseRateBps());
}
TEST(AimdRateControlTest, NearMaxIncreaseRateIs5kbpsOn60kbpsAnd100msRtt) {
auto states = CreateAimdRateControlStates();
constexpr int kBitrate = 60000;
InitBitrate(states, kBitrate, states.simulated_clock->TimeInMilliseconds());
states.aimd_rate_control->SetRtt(100);
EXPECT_EQ(5000, states.aimd_rate_control->GetNearMaxIncreaseRateBps());
}
TEST(AimdRateControlTest, UnknownBitrateDecreaseBeforeFirstOveruse) {
auto states = CreateAimdRateControlStates();
EXPECT_EQ(rtc::Optional<int>(),
states.aimd_rate_control->GetLastBitrateDecreaseBps());
}
TEST(AimdRateControlTest, GetLastBitrateDecrease) {
auto states = CreateAimdRateControlStates();
constexpr int kBitrate = 300000;
InitBitrate(states, kBitrate, states.simulated_clock->TimeInMilliseconds());
UpdateRateControl(states, kBwOverusing, kBitrate - 2000,
states.simulated_clock->TimeInMilliseconds());
EXPECT_EQ(rtc::Optional<int>(46700),
states.aimd_rate_control->GetLastBitrateDecreaseBps());
}
} // namespace webrtc