| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 #include <memory> | 10 #include <memory> |
| 11 | 11 |
| 12 #include "webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h" | 12 #include "webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h" |
| 13 #include "webrtc/system_wrappers/include/clock.h" | 13 #include "webrtc/system_wrappers/include/clock.h" |
| 14 #include "webrtc/test/gtest.h" | 14 #include "webrtc/test/gtest.h" |
| 15 | 15 |
| 16 namespace webrtc { | 16 namespace webrtc { |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 constexpr int64_t kClockInitialTime = 123456; | 19 constexpr int64_t kClockInitialTime = 123456; |
| 20 | 20 |
| 21 constexpr int kMinBwePeriodMs = 2000; |
| 22 constexpr int kMaxBwePeriodMs = 50000; |
| 23 constexpr int kDefaultPeriodMs = 3000; |
| 24 |
| 25 // After an overuse, we back off to 85% to the received bitrate. |
| 26 constexpr double kFractionAfterOveruse = 0.85; |
| 27 |
| 21 struct AimdRateControlStates { | 28 struct AimdRateControlStates { |
| 22 std::unique_ptr<AimdRateControl> aimd_rate_control; | 29 std::unique_ptr<AimdRateControl> aimd_rate_control; |
| 23 std::unique_ptr<SimulatedClock> simulated_clock; | 30 std::unique_ptr<SimulatedClock> simulated_clock; |
| 24 }; | 31 }; |
| 25 | 32 |
| 26 AimdRateControlStates CreateAimdRateControlStates() { | 33 AimdRateControlStates CreateAimdRateControlStates() { |
| 27 AimdRateControlStates states; | 34 AimdRateControlStates states; |
| 28 states.aimd_rate_control.reset(new AimdRateControl()); | 35 states.aimd_rate_control.reset(new AimdRateControl()); |
| 29 states.simulated_clock.reset(new SimulatedClock(kClockInitialTime)); | 36 states.simulated_clock.reset(new SimulatedClock(kClockInitialTime)); |
| 30 return states; | 37 return states; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 59 | 66 |
| 60 TEST(AimdRateControlTest, NearMaxIncreaseRateIs5kbpsOn60kbpsAnd100msRtt) { | 67 TEST(AimdRateControlTest, NearMaxIncreaseRateIs5kbpsOn60kbpsAnd100msRtt) { |
| 61 auto states = CreateAimdRateControlStates(); | 68 auto states = CreateAimdRateControlStates(); |
| 62 constexpr int kBitrate = 60000; | 69 constexpr int kBitrate = 60000; |
| 63 states.aimd_rate_control->SetEstimate( | 70 states.aimd_rate_control->SetEstimate( |
| 64 kBitrate, states.simulated_clock->TimeInMilliseconds()); | 71 kBitrate, states.simulated_clock->TimeInMilliseconds()); |
| 65 states.aimd_rate_control->SetRtt(100); | 72 states.aimd_rate_control->SetRtt(100); |
| 66 EXPECT_EQ(5000, states.aimd_rate_control->GetNearMaxIncreaseRateBps()); | 73 EXPECT_EQ(5000, states.aimd_rate_control->GetNearMaxIncreaseRateBps()); |
| 67 } | 74 } |
| 68 | 75 |
| 69 TEST(AimdRateControlTest, UnknownBitrateDecreaseBeforeFirstOveruse) { | 76 TEST(AimdRateControlTest, GetIncreaseRateAndBandwidthPeriod) { |
| 70 auto states = CreateAimdRateControlStates(); | |
| 71 EXPECT_EQ(rtc::Optional<int>(), | |
| 72 states.aimd_rate_control->GetLastBitrateDecreaseBps()); | |
| 73 } | |
| 74 | |
| 75 TEST(AimdRateControlTest, GetLastBitrateDecrease) { | |
| 76 auto states = CreateAimdRateControlStates(); | 77 auto states = CreateAimdRateControlStates(); |
| 77 constexpr int kBitrate = 300000; | 78 constexpr int kBitrate = 300000; |
| 78 states.aimd_rate_control->SetEstimate( | 79 states.aimd_rate_control->SetEstimate( |
| 79 kBitrate, states.simulated_clock->TimeInMilliseconds()); | 80 kBitrate, states.simulated_clock->TimeInMilliseconds()); |
| 80 UpdateRateControl(states, BandwidthUsage::kBwOverusing, kBitrate - 2000, | 81 UpdateRateControl(states, BandwidthUsage::kBwOverusing, kBitrate, |
| 81 states.simulated_clock->TimeInMilliseconds()); | 82 states.simulated_clock->TimeInMilliseconds()); |
| 82 EXPECT_EQ(rtc::Optional<int>(46700), | 83 EXPECT_NEAR(14000, states.aimd_rate_control->GetNearMaxIncreaseRateBps(), |
| 83 states.aimd_rate_control->GetLastBitrateDecreaseBps()); | 84 1000); |
| 85 EXPECT_EQ(3000, states.aimd_rate_control->GetExpectedBandwidthPeriodMs()); |
| 84 } | 86 } |
| 85 | 87 |
| 86 TEST(AimdRateControlTest, BweLimitedByAckedBitrate) { | 88 TEST(AimdRateControlTest, BweLimitedByAckedBitrate) { |
| 87 auto states = CreateAimdRateControlStates(); | 89 auto states = CreateAimdRateControlStates(); |
| 88 constexpr int kAckedBitrate = 10000; | 90 constexpr int kAckedBitrate = 10000; |
| 89 states.aimd_rate_control->SetEstimate( | 91 states.aimd_rate_control->SetEstimate( |
| 90 kAckedBitrate, states.simulated_clock->TimeInMilliseconds()); | 92 kAckedBitrate, states.simulated_clock->TimeInMilliseconds()); |
| 91 while (states.simulated_clock->TimeInMilliseconds() - kClockInitialTime < | 93 while (states.simulated_clock->TimeInMilliseconds() - kClockInitialTime < |
| 92 20000) { | 94 20000) { |
| 93 UpdateRateControl(states, BandwidthUsage::kBwNormal, kAckedBitrate, | 95 UpdateRateControl(states, BandwidthUsage::kBwNormal, kAckedBitrate, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 114 // If the acked bitrate decreases the BWE shouldn't be reduced to 1.5x | 116 // If the acked bitrate decreases the BWE shouldn't be reduced to 1.5x |
| 115 // what's being acked, but also shouldn't get to increase more. | 117 // what's being acked, but also shouldn't get to increase more. |
| 116 uint32_t prev_estimate = states.aimd_rate_control->LatestEstimate(); | 118 uint32_t prev_estimate = states.aimd_rate_control->LatestEstimate(); |
| 117 UpdateRateControl(states, BandwidthUsage::kBwNormal, kAckedBitrate / 2, | 119 UpdateRateControl(states, BandwidthUsage::kBwNormal, kAckedBitrate / 2, |
| 118 states.simulated_clock->TimeInMilliseconds()); | 120 states.simulated_clock->TimeInMilliseconds()); |
| 119 uint32_t new_estimate = states.aimd_rate_control->LatestEstimate(); | 121 uint32_t new_estimate = states.aimd_rate_control->LatestEstimate(); |
| 120 EXPECT_NEAR(new_estimate, static_cast<uint32_t>(1.5 * kAckedBitrate + 10000), | 122 EXPECT_NEAR(new_estimate, static_cast<uint32_t>(1.5 * kAckedBitrate + 10000), |
| 121 2000); | 123 2000); |
| 122 EXPECT_EQ(new_estimate, prev_estimate); | 124 EXPECT_EQ(new_estimate, prev_estimate); |
| 123 } | 125 } |
| 126 |
| 127 TEST(AimdRateControlTest, DefaultPeriodUntilFirstOveruse) { |
| 128 auto states = CreateAimdRateControlStates(); |
| 129 states.aimd_rate_control->SetStartBitrate(300000); |
| 130 EXPECT_EQ(kDefaultPeriodMs, |
| 131 states.aimd_rate_control->GetExpectedBandwidthPeriodMs()); |
| 132 states.simulated_clock->AdvanceTimeMilliseconds(100); |
| 133 UpdateRateControl(states, BandwidthUsage::kBwOverusing, 100000, |
| 134 states.simulated_clock->TimeInMilliseconds()); |
| 135 EXPECT_NE(kDefaultPeriodMs, |
| 136 states.aimd_rate_control->GetExpectedBandwidthPeriodMs()); |
| 137 } |
| 138 |
| 139 TEST(AimdRateControlTest, ExpectedPeriodAfter20kbpsDropAnd5kbpsIncrease) { |
| 140 auto states = CreateAimdRateControlStates(); |
| 141 constexpr int kInitialBitrate = 110000; |
| 142 states.aimd_rate_control->SetEstimate( |
| 143 kInitialBitrate, states.simulated_clock->TimeInMilliseconds()); |
| 144 states.simulated_clock->AdvanceTimeMilliseconds(100); |
| 145 // Make the bitrate drop by 20 kbps to get to 90 kbps. |
| 146 // The rate increase at 90 kbps should be 5 kbps, so the period should be 4 s. |
| 147 constexpr int kAckedBitrate = |
| 148 (kInitialBitrate - 20000) / kFractionAfterOveruse; |
| 149 UpdateRateControl(states, BandwidthUsage::kBwOverusing, kAckedBitrate, |
| 150 states.simulated_clock->TimeInMilliseconds()); |
| 151 EXPECT_EQ(5000, states.aimd_rate_control->GetNearMaxIncreaseRateBps()); |
| 152 EXPECT_EQ(4000, states.aimd_rate_control->GetExpectedBandwidthPeriodMs()); |
| 153 } |
| 154 |
| 155 TEST(AimdRateControlTest, BandwidthPeriodIsNotBelowMin) { |
| 156 auto states = CreateAimdRateControlStates(); |
| 157 constexpr int kInitialBitrate = 10000; |
| 158 states.aimd_rate_control->SetEstimate( |
| 159 kInitialBitrate, states.simulated_clock->TimeInMilliseconds()); |
| 160 states.simulated_clock->AdvanceTimeMilliseconds(100); |
| 161 // Make a small (1.5 kbps) bitrate drop to 8.5 kbps. |
| 162 UpdateRateControl(states, BandwidthUsage::kBwOverusing, kInitialBitrate - 1, |
| 163 states.simulated_clock->TimeInMilliseconds()); |
| 164 EXPECT_EQ(kMinBwePeriodMs, |
| 165 states.aimd_rate_control->GetExpectedBandwidthPeriodMs()); |
| 166 } |
| 167 |
| 168 TEST(AimdRateControlTest, BandwidthPeriodIsNotAboveMax) { |
| 169 auto states = CreateAimdRateControlStates(); |
| 170 constexpr int kInitialBitrate = 10010000; |
| 171 states.aimd_rate_control->SetEstimate( |
| 172 kInitialBitrate, states.simulated_clock->TimeInMilliseconds()); |
| 173 states.simulated_clock->AdvanceTimeMilliseconds(100); |
| 174 // Make a large (10 Mbps) bitrate drop to 10 kbps. |
| 175 constexpr int kAckedBitrate = 10000 / kFractionAfterOveruse; |
| 176 UpdateRateControl(states, BandwidthUsage::kBwOverusing, kAckedBitrate, |
| 177 states.simulated_clock->TimeInMilliseconds()); |
| 178 EXPECT_EQ(kMaxBwePeriodMs, |
| 179 states.aimd_rate_control->GetExpectedBandwidthPeriodMs()); |
| 180 } |
| 181 |
| 124 } // namespace webrtc | 182 } // namespace webrtc |
| OLD | NEW |