• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2016 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/delay_based_bwe.h"
12 
13 #include <string>
14 
15 #include "api/transport/network_types.h"
16 #include "modules/congestion_controller/goog_cc/acknowledged_bitrate_estimator.h"
17 #include "modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.h"
18 #include "system_wrappers/include/clock.h"
19 #include "test/gtest.h"
20 
21 namespace webrtc {
22 
23 namespace {
24 constexpr int kNumProbesCluster0 = 5;
25 constexpr int kNumProbesCluster1 = 8;
26 const PacedPacketInfo kPacingInfo0(0, kNumProbesCluster0, 2000);
27 const PacedPacketInfo kPacingInfo1(1, kNumProbesCluster1, 4000);
28 constexpr float kTargetUtilizationFraction = 0.95f;
29 }  // namespace
30 
TEST_F(DelayBasedBweTest,ProbeDetection)31 TEST_F(DelayBasedBweTest, ProbeDetection) {
32   int64_t now_ms = clock_.TimeInMilliseconds();
33 
34   // First burst sent at 8 * 1000 / 10 = 800 kbps.
35   for (int i = 0; i < kNumProbesCluster0; ++i) {
36     clock_.AdvanceTimeMilliseconds(10);
37     now_ms = clock_.TimeInMilliseconds();
38     IncomingFeedback(now_ms, now_ms, 1000, kPacingInfo0);
39   }
40   EXPECT_TRUE(bitrate_observer_.updated());
41 
42   // Second burst sent at 8 * 1000 / 5 = 1600 kbps.
43   for (int i = 0; i < kNumProbesCluster1; ++i) {
44     clock_.AdvanceTimeMilliseconds(5);
45     now_ms = clock_.TimeInMilliseconds();
46     IncomingFeedback(now_ms, now_ms, 1000, kPacingInfo1);
47   }
48 
49   EXPECT_TRUE(bitrate_observer_.updated());
50   EXPECT_GT(bitrate_observer_.latest_bitrate(), 1500000u);
51 }
52 
TEST_F(DelayBasedBweTest,ProbeDetectionNonPacedPackets)53 TEST_F(DelayBasedBweTest, ProbeDetectionNonPacedPackets) {
54   int64_t now_ms = clock_.TimeInMilliseconds();
55   // First burst sent at 8 * 1000 / 10 = 800 kbps, but with every other packet
56   // not being paced which could mess things up.
57   for (int i = 0; i < kNumProbesCluster0; ++i) {
58     clock_.AdvanceTimeMilliseconds(5);
59     now_ms = clock_.TimeInMilliseconds();
60     IncomingFeedback(now_ms, now_ms, 1000, kPacingInfo0);
61     // Non-paced packet, arriving 5 ms after.
62     clock_.AdvanceTimeMilliseconds(5);
63     IncomingFeedback(now_ms, now_ms, 100, PacedPacketInfo());
64   }
65 
66   EXPECT_TRUE(bitrate_observer_.updated());
67   EXPECT_GT(bitrate_observer_.latest_bitrate(), 800000u);
68 }
69 
TEST_F(DelayBasedBweTest,ProbeDetectionFasterArrival)70 TEST_F(DelayBasedBweTest, ProbeDetectionFasterArrival) {
71   int64_t now_ms = clock_.TimeInMilliseconds();
72   // First burst sent at 8 * 1000 / 10 = 800 kbps.
73   // Arriving at 8 * 1000 / 5 = 1600 kbps.
74   int64_t send_time_ms = 0;
75   for (int i = 0; i < kNumProbesCluster0; ++i) {
76     clock_.AdvanceTimeMilliseconds(1);
77     send_time_ms += 10;
78     now_ms = clock_.TimeInMilliseconds();
79     IncomingFeedback(now_ms, send_time_ms, 1000, kPacingInfo0);
80   }
81 
82   EXPECT_FALSE(bitrate_observer_.updated());
83 }
84 
TEST_F(DelayBasedBweTest,ProbeDetectionSlowerArrival)85 TEST_F(DelayBasedBweTest, ProbeDetectionSlowerArrival) {
86   int64_t now_ms = clock_.TimeInMilliseconds();
87   // First burst sent at 8 * 1000 / 5 = 1600 kbps.
88   // Arriving at 8 * 1000 / 7 = 1142 kbps.
89   // Since the receive rate is significantly below the send rate, we expect to
90   // use 95% of the estimated capacity.
91   int64_t send_time_ms = 0;
92   for (int i = 0; i < kNumProbesCluster1; ++i) {
93     clock_.AdvanceTimeMilliseconds(7);
94     send_time_ms += 5;
95     now_ms = clock_.TimeInMilliseconds();
96     IncomingFeedback(now_ms, send_time_ms, 1000, kPacingInfo1);
97   }
98 
99   EXPECT_TRUE(bitrate_observer_.updated());
100   EXPECT_NEAR(bitrate_observer_.latest_bitrate(),
101               kTargetUtilizationFraction * 1140000u, 10000u);
102 }
103 
TEST_F(DelayBasedBweTest,ProbeDetectionSlowerArrivalHighBitrate)104 TEST_F(DelayBasedBweTest, ProbeDetectionSlowerArrivalHighBitrate) {
105   int64_t now_ms = clock_.TimeInMilliseconds();
106   // Burst sent at 8 * 1000 / 1 = 8000 kbps.
107   // Arriving at 8 * 1000 / 2 = 4000 kbps.
108   // Since the receive rate is significantly below the send rate, we expect to
109   // use 95% of the estimated capacity.
110   int64_t send_time_ms = 0;
111   for (int i = 0; i < kNumProbesCluster1; ++i) {
112     clock_.AdvanceTimeMilliseconds(2);
113     send_time_ms += 1;
114     now_ms = clock_.TimeInMilliseconds();
115     IncomingFeedback(now_ms, send_time_ms, 1000, kPacingInfo1);
116   }
117 
118   EXPECT_TRUE(bitrate_observer_.updated());
119   EXPECT_NEAR(bitrate_observer_.latest_bitrate(),
120               kTargetUtilizationFraction * 4000000u, 10000u);
121 }
122 
TEST_F(DelayBasedBweTest,GetExpectedBwePeriodMs)123 TEST_F(DelayBasedBweTest, GetExpectedBwePeriodMs) {
124   auto default_interval = bitrate_estimator_->GetExpectedBwePeriod();
125   EXPECT_GT(default_interval.ms(), 0);
126   CapacityDropTestHelper(1, true, 333, 0);
127   auto interval = bitrate_estimator_->GetExpectedBwePeriod();
128   EXPECT_GT(interval.ms(), 0);
129   EXPECT_NE(interval.ms(), default_interval.ms());
130 }
131 
TEST_F(DelayBasedBweTest,InitialBehavior)132 TEST_F(DelayBasedBweTest, InitialBehavior) {
133   InitialBehaviorTestHelper(730000);
134 }
135 
TEST_F(DelayBasedBweTest,RateIncreaseReordering)136 TEST_F(DelayBasedBweTest, RateIncreaseReordering) {
137   RateIncreaseReorderingTestHelper(730000);
138 }
TEST_F(DelayBasedBweTest,RateIncreaseRtpTimestamps)139 TEST_F(DelayBasedBweTest, RateIncreaseRtpTimestamps) {
140   RateIncreaseRtpTimestampsTestHelper(622);
141 }
142 
TEST_F(DelayBasedBweTest,CapacityDropOneStream)143 TEST_F(DelayBasedBweTest, CapacityDropOneStream) {
144   CapacityDropTestHelper(1, false, 300, 0);
145 }
146 
TEST_F(DelayBasedBweTest,CapacityDropPosOffsetChange)147 TEST_F(DelayBasedBweTest, CapacityDropPosOffsetChange) {
148   CapacityDropTestHelper(1, false, 867, 30000);
149 }
150 
TEST_F(DelayBasedBweTest,CapacityDropNegOffsetChange)151 TEST_F(DelayBasedBweTest, CapacityDropNegOffsetChange) {
152   CapacityDropTestHelper(1, false, 933, -30000);
153 }
154 
TEST_F(DelayBasedBweTest,CapacityDropOneStreamWrap)155 TEST_F(DelayBasedBweTest, CapacityDropOneStreamWrap) {
156   CapacityDropTestHelper(1, true, 333, 0);
157 }
158 
TEST_F(DelayBasedBweTest,TestTimestampGrouping)159 TEST_F(DelayBasedBweTest, TestTimestampGrouping) {
160   TestTimestampGroupingTestHelper();
161 }
162 
TEST_F(DelayBasedBweTest,TestShortTimeoutAndWrap)163 TEST_F(DelayBasedBweTest, TestShortTimeoutAndWrap) {
164   // Simulate a client leaving and rejoining the call after 35 seconds. This
165   // will make abs send time wrap, so if streams aren't timed out properly
166   // the next 30 seconds of packets will be out of order.
167   TestWrappingHelper(35);
168 }
169 
TEST_F(DelayBasedBweTest,TestLongTimeoutAndWrap)170 TEST_F(DelayBasedBweTest, TestLongTimeoutAndWrap) {
171   // Simulate a client leaving and rejoining the call after some multiple of
172   // 64 seconds later. This will cause a zero difference in abs send times due
173   // to the wrap, but a big difference in arrival time, if streams aren't
174   // properly timed out.
175   TestWrappingHelper(10 * 64);
176 }
177 
TEST_F(DelayBasedBweTest,TestInitialOveruse)178 TEST_F(DelayBasedBweTest, TestInitialOveruse) {
179   const DataRate kStartBitrate = DataRate::KilobitsPerSec(300);
180   const DataRate kInitialCapacity = DataRate::KilobitsPerSec(200);
181   const uint32_t kDummySsrc = 0;
182   // High FPS to ensure that we send a lot of packets in a short time.
183   const int kFps = 90;
184 
185   stream_generator_->AddStream(new test::RtpStream(kFps, kStartBitrate.bps()));
186   stream_generator_->set_capacity_bps(kInitialCapacity.bps());
187 
188   // Needed to initialize the AimdRateControl.
189   bitrate_estimator_->SetStartBitrate(kStartBitrate);
190 
191   // Produce 30 frames (in 1/3 second) and give them to the estimator.
192   int64_t bitrate_bps = kStartBitrate.bps();
193   bool seen_overuse = false;
194   for (int i = 0; i < 30; ++i) {
195     bool overuse = GenerateAndProcessFrame(kDummySsrc, bitrate_bps);
196     // The purpose of this test is to ensure that we back down even if we don't
197     // have any acknowledged bitrate estimate yet. Hence, if the test works
198     // as expected, we should not have a measured bitrate yet.
199     EXPECT_FALSE(acknowledged_bitrate_estimator_->bitrate().has_value());
200     if (overuse) {
201       EXPECT_TRUE(bitrate_observer_.updated());
202       EXPECT_NEAR(bitrate_observer_.latest_bitrate(), kStartBitrate.bps() / 2,
203                   15000);
204       bitrate_bps = bitrate_observer_.latest_bitrate();
205       seen_overuse = true;
206       break;
207     } else if (bitrate_observer_.updated()) {
208       bitrate_bps = bitrate_observer_.latest_bitrate();
209       bitrate_observer_.Reset();
210     }
211   }
212   EXPECT_TRUE(seen_overuse);
213   EXPECT_NEAR(bitrate_observer_.latest_bitrate(), kStartBitrate.bps() / 2,
214               15000);
215 }
216 
TEST_F(DelayBasedBweTest,TestTimestampPrecisionHandling)217 TEST_F(DelayBasedBweTest, TestTimestampPrecisionHandling) {
218   // This test does some basic checks to make sure that timestamps with higher
219   // than millisecond precision are handled properly and do not cause any
220   // problems in the estimator. Specifically, previously reported in
221   // webrtc:14023 and described in more details there, the rounding to the
222   // nearest milliseconds caused discrepancy in the accumulated delay. This lead
223   // to false-positive overuse detection.
224   // Technical details of the test:
225   // Send times(ms): 0.000,  9.725, 20.000, 29.725, 40.000, 49.725, ...
226   // Recv times(ms): 0.500, 10.000, 20.500, 30.000, 40.500, 50.000, ...
227   // Send deltas(ms):   9.750,  10.250,  9.750, 10.250,  9.750, ...
228   // Recv deltas(ms):   9.500,  10.500,  9.500, 10.500,  9.500, ...
229   // There is no delay building up between the send times and the receive times,
230   // therefore this case should never lead to an overuse detection. However, if
231   // the time deltas were accidentally rounded to the nearest milliseconds, then
232   // all the send deltas would be equal to 10ms while some recv deltas would
233   // round up to 11ms which would lead in a false illusion of delay build up.
234   uint32_t last_bitrate = bitrate_observer_.latest_bitrate();
235   for (int i = 0; i < 1000; ++i) {
236     clock_.AdvanceTimeMicroseconds(500);
237     IncomingFeedback(clock_.CurrentTime(),
238                      clock_.CurrentTime() - TimeDelta::Micros(500), 1000,
239                      PacedPacketInfo());
240     clock_.AdvanceTimeMicroseconds(9500);
241     IncomingFeedback(clock_.CurrentTime(),
242                      clock_.CurrentTime() - TimeDelta::Micros(250), 1000,
243                      PacedPacketInfo());
244     clock_.AdvanceTimeMicroseconds(10000);
245 
246     // The bitrate should never decrease in this test.
247     EXPECT_LE(last_bitrate, bitrate_observer_.latest_bitrate());
248     last_bitrate = bitrate_observer_.latest_bitrate();
249   }
250 }
251 
252 class DelayBasedBweTestWithBackoffTimeoutExperiment : public DelayBasedBweTest {
253  public:
DelayBasedBweTestWithBackoffTimeoutExperiment()254   DelayBasedBweTestWithBackoffTimeoutExperiment()
255       : DelayBasedBweTest(
256             "WebRTC-BweAimdRateControlConfig/initial_backoff_interval:200ms/") {
257   }
258 };
259 
260 // This test subsumes and improves DelayBasedBweTest.TestInitialOveruse above.
TEST_F(DelayBasedBweTestWithBackoffTimeoutExperiment,TestInitialOveruse)261 TEST_F(DelayBasedBweTestWithBackoffTimeoutExperiment, TestInitialOveruse) {
262   const DataRate kStartBitrate = DataRate::KilobitsPerSec(300);
263   const DataRate kInitialCapacity = DataRate::KilobitsPerSec(200);
264   const uint32_t kDummySsrc = 0;
265   // High FPS to ensure that we send a lot of packets in a short time.
266   const int kFps = 90;
267 
268   stream_generator_->AddStream(new test::RtpStream(kFps, kStartBitrate.bps()));
269   stream_generator_->set_capacity_bps(kInitialCapacity.bps());
270 
271   // Needed to initialize the AimdRateControl.
272   bitrate_estimator_->SetStartBitrate(kStartBitrate);
273 
274   // Produce 30 frames (in 1/3 second) and give them to the estimator.
275   int64_t bitrate_bps = kStartBitrate.bps();
276   bool seen_overuse = false;
277   for (int frames = 0; frames < 30 && !seen_overuse; ++frames) {
278     bool overuse = GenerateAndProcessFrame(kDummySsrc, bitrate_bps);
279     // The purpose of this test is to ensure that we back down even if we don't
280     // have any acknowledged bitrate estimate yet. Hence, if the test works
281     // as expected, we should not have a measured bitrate yet.
282     EXPECT_FALSE(acknowledged_bitrate_estimator_->bitrate().has_value());
283     if (overuse) {
284       EXPECT_TRUE(bitrate_observer_.updated());
285       EXPECT_NEAR(bitrate_observer_.latest_bitrate(), kStartBitrate.bps() / 2,
286                   15000);
287       bitrate_bps = bitrate_observer_.latest_bitrate();
288       seen_overuse = true;
289     } else if (bitrate_observer_.updated()) {
290       bitrate_bps = bitrate_observer_.latest_bitrate();
291       bitrate_observer_.Reset();
292     }
293   }
294   EXPECT_TRUE(seen_overuse);
295   // Continue generating an additional 15 frames (equivalent to 167 ms) and
296   // verify that we don't back down further.
297   for (int frames = 0; frames < 15 && seen_overuse; ++frames) {
298     bool overuse = GenerateAndProcessFrame(kDummySsrc, bitrate_bps);
299     EXPECT_FALSE(overuse);
300     if (bitrate_observer_.updated()) {
301       bitrate_bps = bitrate_observer_.latest_bitrate();
302       EXPECT_GE(bitrate_bps, kStartBitrate.bps() / 2 - 15000);
303       EXPECT_LE(bitrate_bps, kInitialCapacity.bps() + 15000);
304       bitrate_observer_.Reset();
305     }
306   }
307 }
308 
309 }  // namespace webrtc
310