1 /*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.h"
12
13 #include "api/rtc_event_log/rtc_event.h"
14 #include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h"
15 #include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
16 #include "test/explicit_key_value_config.h"
17 #include "test/gmock.h"
18 #include "test/gtest.h"
19
20 namespace webrtc {
21
22 MATCHER(LossBasedBweUpdateWithBitrateOnly, "") {
23 if (arg->GetType() != RtcEvent::Type::BweUpdateLossBased) {
24 return false;
25 }
26 auto bwe_event = static_cast<RtcEventBweUpdateLossBased*>(arg);
27 return bwe_event->bitrate_bps() > 0 && bwe_event->fraction_loss() == 0;
28 }
29
30 MATCHER(LossBasedBweUpdateWithBitrateAndLossFraction, "") {
31 if (arg->GetType() != RtcEvent::Type::BweUpdateLossBased) {
32 return false;
33 }
34 auto bwe_event = static_cast<RtcEventBweUpdateLossBased*>(arg);
35 return bwe_event->bitrate_bps() > 0 && bwe_event->fraction_loss() > 0;
36 }
37
TestProbing(bool use_delay_based)38 void TestProbing(bool use_delay_based) {
39 ::testing::NiceMock<MockRtcEventLog> event_log;
40 test::ExplicitKeyValueConfig key_value_config("");
41 SendSideBandwidthEstimation bwe(&key_value_config, &event_log);
42 int64_t now_ms = 0;
43 bwe.SetMinMaxBitrate(DataRate::BitsPerSec(100000),
44 DataRate::BitsPerSec(1500000));
45 bwe.SetSendBitrate(DataRate::BitsPerSec(200000), Timestamp::Millis(now_ms));
46
47 const int kRembBps = 1000000;
48 const int kSecondRembBps = kRembBps + 500000;
49
50 bwe.UpdatePacketsLost(/*packets_lost=*/0, /*number_of_packets=*/1,
51 Timestamp::Millis(now_ms));
52 bwe.UpdateRtt(TimeDelta::Millis(50), Timestamp::Millis(now_ms));
53
54 // Initial REMB applies immediately.
55 if (use_delay_based) {
56 bwe.UpdateDelayBasedEstimate(Timestamp::Millis(now_ms),
57 DataRate::BitsPerSec(kRembBps));
58 } else {
59 bwe.UpdateReceiverEstimate(Timestamp::Millis(now_ms),
60 DataRate::BitsPerSec(kRembBps));
61 }
62 bwe.UpdateEstimate(Timestamp::Millis(now_ms));
63 EXPECT_EQ(kRembBps, bwe.target_rate().bps());
64
65 // Second REMB doesn't apply immediately.
66 now_ms += 2001;
67 if (use_delay_based) {
68 bwe.UpdateDelayBasedEstimate(Timestamp::Millis(now_ms),
69 DataRate::BitsPerSec(kSecondRembBps));
70 } else {
71 bwe.UpdateReceiverEstimate(Timestamp::Millis(now_ms),
72 DataRate::BitsPerSec(kSecondRembBps));
73 }
74 bwe.UpdateEstimate(Timestamp::Millis(now_ms));
75 EXPECT_EQ(kRembBps, bwe.target_rate().bps());
76 }
77
TEST(SendSideBweTest,InitialRembWithProbing)78 TEST(SendSideBweTest, InitialRembWithProbing) {
79 TestProbing(false);
80 }
81
TEST(SendSideBweTest,InitialDelayBasedBweWithProbing)82 TEST(SendSideBweTest, InitialDelayBasedBweWithProbing) {
83 TestProbing(true);
84 }
85
TEST(SendSideBweTest,DoesntReapplyBitrateDecreaseWithoutFollowingRemb)86 TEST(SendSideBweTest, DoesntReapplyBitrateDecreaseWithoutFollowingRemb) {
87 MockRtcEventLog event_log;
88 EXPECT_CALL(event_log, LogProxy(LossBasedBweUpdateWithBitrateOnly()))
89 .Times(1);
90 EXPECT_CALL(event_log,
91 LogProxy(LossBasedBweUpdateWithBitrateAndLossFraction()))
92 .Times(1);
93 test::ExplicitKeyValueConfig key_value_config("");
94 SendSideBandwidthEstimation bwe(&key_value_config, &event_log);
95 static const int kMinBitrateBps = 100000;
96 static const int kInitialBitrateBps = 1000000;
97 int64_t now_ms = 1000;
98 bwe.SetMinMaxBitrate(DataRate::BitsPerSec(kMinBitrateBps),
99 DataRate::BitsPerSec(1500000));
100 bwe.SetSendBitrate(DataRate::BitsPerSec(kInitialBitrateBps),
101 Timestamp::Millis(now_ms));
102
103 static const uint8_t kFractionLoss = 128;
104 static const int64_t kRttMs = 50;
105 now_ms += 10000;
106
107 EXPECT_EQ(kInitialBitrateBps, bwe.target_rate().bps());
108 EXPECT_EQ(0, bwe.fraction_loss());
109 EXPECT_EQ(0, bwe.round_trip_time().ms());
110
111 // Signal heavy loss to go down in bitrate.
112 bwe.UpdatePacketsLost(/*packets_lost=*/50, /*number_of_packets=*/100,
113 Timestamp::Millis(now_ms));
114 bwe.UpdateRtt(TimeDelta::Millis(kRttMs), Timestamp::Millis(now_ms));
115
116 // Trigger an update 2 seconds later to not be rate limited.
117 now_ms += 1000;
118 bwe.UpdateEstimate(Timestamp::Millis(now_ms));
119 EXPECT_LT(bwe.target_rate().bps(), kInitialBitrateBps);
120 // Verify that the obtained bitrate isn't hitting the min bitrate, or this
121 // test doesn't make sense. If this ever happens, update the thresholds or
122 // loss rates so that it doesn't hit min bitrate after one bitrate update.
123 EXPECT_GT(bwe.target_rate().bps(), kMinBitrateBps);
124 EXPECT_EQ(kFractionLoss, bwe.fraction_loss());
125 EXPECT_EQ(kRttMs, bwe.round_trip_time().ms());
126
127 // Triggering an update shouldn't apply further downgrade nor upgrade since
128 // there's no intermediate receiver block received indicating whether this is
129 // currently good or not.
130 int last_bitrate_bps = bwe.target_rate().bps();
131 // Trigger an update 2 seconds later to not be rate limited (but it still
132 // shouldn't update).
133 now_ms += 1000;
134 bwe.UpdateEstimate(Timestamp::Millis(now_ms));
135
136 EXPECT_EQ(last_bitrate_bps, bwe.target_rate().bps());
137 // The old loss rate should still be applied though.
138 EXPECT_EQ(kFractionLoss, bwe.fraction_loss());
139 EXPECT_EQ(kRttMs, bwe.round_trip_time().ms());
140 }
141
TEST(SendSideBweTest,SettingSendBitrateOverridesDelayBasedEstimate)142 TEST(SendSideBweTest, SettingSendBitrateOverridesDelayBasedEstimate) {
143 ::testing::NiceMock<MockRtcEventLog> event_log;
144 test::ExplicitKeyValueConfig key_value_config("");
145 SendSideBandwidthEstimation bwe(&key_value_config, &event_log);
146 static const int kMinBitrateBps = 10000;
147 static const int kMaxBitrateBps = 10000000;
148 static const int kInitialBitrateBps = 300000;
149 static const int kDelayBasedBitrateBps = 350000;
150 static const int kForcedHighBitrate = 2500000;
151
152 int64_t now_ms = 0;
153
154 bwe.SetMinMaxBitrate(DataRate::BitsPerSec(kMinBitrateBps),
155 DataRate::BitsPerSec(kMaxBitrateBps));
156 bwe.SetSendBitrate(DataRate::BitsPerSec(kInitialBitrateBps),
157 Timestamp::Millis(now_ms));
158
159 bwe.UpdateDelayBasedEstimate(Timestamp::Millis(now_ms),
160 DataRate::BitsPerSec(kDelayBasedBitrateBps));
161 bwe.UpdateEstimate(Timestamp::Millis(now_ms));
162 EXPECT_GE(bwe.target_rate().bps(), kInitialBitrateBps);
163 EXPECT_LE(bwe.target_rate().bps(), kDelayBasedBitrateBps);
164
165 bwe.SetSendBitrate(DataRate::BitsPerSec(kForcedHighBitrate),
166 Timestamp::Millis(now_ms));
167 EXPECT_EQ(bwe.target_rate().bps(), kForcedHighBitrate);
168 }
169
TEST(RttBasedBackoff,DefaultEnabled)170 TEST(RttBasedBackoff, DefaultEnabled) {
171 test::ExplicitKeyValueConfig key_value_config("");
172 RttBasedBackoff rtt_backoff(&key_value_config);
173 EXPECT_TRUE(rtt_backoff.rtt_limit_.IsFinite());
174 }
175
TEST(RttBasedBackoff,CanBeDisabled)176 TEST(RttBasedBackoff, CanBeDisabled) {
177 test::ExplicitKeyValueConfig key_value_config(
178 "WebRTC-Bwe-MaxRttLimit/Disabled/");
179 RttBasedBackoff rtt_backoff(&key_value_config);
180 EXPECT_TRUE(rtt_backoff.rtt_limit_.IsPlusInfinity());
181 }
182
TEST(SendSideBweTest,FractionLossIsNotOverflowed)183 TEST(SendSideBweTest, FractionLossIsNotOverflowed) {
184 MockRtcEventLog event_log;
185 test::ExplicitKeyValueConfig key_value_config("");
186 SendSideBandwidthEstimation bwe(&key_value_config, &event_log);
187 static const int kMinBitrateBps = 100000;
188 static const int kInitialBitrateBps = 1000000;
189 int64_t now_ms = 1000;
190 bwe.SetMinMaxBitrate(DataRate::BitsPerSec(kMinBitrateBps),
191 DataRate::BitsPerSec(1500000));
192 bwe.SetSendBitrate(DataRate::BitsPerSec(kInitialBitrateBps),
193 Timestamp::Millis(now_ms));
194
195 now_ms += 10000;
196
197 EXPECT_EQ(kInitialBitrateBps, bwe.target_rate().bps());
198 EXPECT_EQ(0, bwe.fraction_loss());
199
200 // Signal negative loss.
201 bwe.UpdatePacketsLost(/*packets_lost=*/-1, /*number_of_packets=*/100,
202 Timestamp::Millis(now_ms));
203 EXPECT_EQ(0, bwe.fraction_loss());
204 }
205
206 } // namespace webrtc
207