blob: a22ff6d16463e1d9f45803b894054e80362bf296 [file] [log] [blame]
Erik Språng4314a492019-11-26 17:48:49 +01001/*
2 * Copyright (c) 2019 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/pacing/task_queue_paced_sender.h"
12
Erik Språng7d0cde52020-07-19 12:48:16 +020013#include <algorithm>
Erik Språng4314a492019-11-26 17:48:49 +010014#include <list>
15#include <memory>
16#include <string>
17#include <utility>
18#include <vector>
19
Erik Språng7d0cde52020-07-19 12:48:16 +020020#include "api/transport/network_types.h"
Erik Språng4314a492019-11-26 17:48:49 +010021#include "modules/pacing/packet_router.h"
22#include "modules/utility/include/mock/mock_process_thread.h"
Erik Språng4314a492019-11-26 17:48:49 +010023#include "test/gmock.h"
24#include "test/gtest.h"
Erik Språnge486a7b2022-03-15 15:13:25 +010025#include "test/scoped_key_value_config.h"
Erik Språng4314a492019-11-26 17:48:49 +010026#include "test/time_controller/simulated_time_controller.h"
27
28using ::testing::_;
Erik Språng4ab61cb2020-05-19 17:40:58 +020029using ::testing::AtLeast;
Erik Språng4314a492019-11-26 17:48:49 +010030using ::testing::Return;
31using ::testing::SaveArg;
32
33namespace webrtc {
34namespace {
35constexpr uint32_t kAudioSsrc = 12345;
36constexpr uint32_t kVideoSsrc = 234565;
37constexpr uint32_t kVideoRtxSsrc = 34567;
38constexpr uint32_t kFlexFecSsrc = 45678;
39constexpr size_t kDefaultPacketSize = 1234;
Mirko Bonadeid8543de2022-03-14 09:13:41 +000040constexpr int kNoPacketHoldback = -1;
Erik Språng4314a492019-11-26 17:48:49 +010041
42class MockPacketRouter : public PacketRouter {
43 public:
Danil Chapovalov014197b2020-05-26 19:18:17 +020044 MOCK_METHOD(void,
45 SendPacket,
46 (std::unique_ptr<RtpPacketToSend> packet,
47 const PacedPacketInfo& cluster_info),
48 (override));
49 MOCK_METHOD(std::vector<std::unique_ptr<RtpPacketToSend>>,
Erik Språng1d50cb62020-07-02 17:41:32 +020050 FetchFec,
51 (),
52 (override));
53 MOCK_METHOD(std::vector<std::unique_ptr<RtpPacketToSend>>,
Danil Chapovalov014197b2020-05-26 19:18:17 +020054 GeneratePadding,
Erik Språnged1fb192020-06-30 11:53:37 +000055 (DataSize target_size),
Danil Chapovalov014197b2020-05-26 19:18:17 +020056 (override));
Erik Språng4314a492019-11-26 17:48:49 +010057};
Erik Språng998524a2020-05-29 16:13:32 +020058
Erik Språng7d0cde52020-07-19 12:48:16 +020059std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePadding(
60 DataSize target_size) {
61 // 224 bytes is the max padding size for plain padding packets generated by
62 // RTPSender::GeneratePadding().
63 const DataSize kMaxPaddingPacketSize = DataSize::Bytes(224);
64 DataSize padding_generated = DataSize::Zero();
65 std::vector<std::unique_ptr<RtpPacketToSend>> padding_packets;
66 while (padding_generated < target_size) {
67 DataSize packet_size =
68 std::min(target_size - padding_generated, kMaxPaddingPacketSize);
69 padding_generated += packet_size;
70 auto padding_packet =
71 std::make_unique<RtpPacketToSend>(/*extensions=*/nullptr);
72 padding_packet->set_packet_type(RtpPacketMediaType::kPadding);
73 padding_packet->SetPadding(packet_size.bytes());
74 padding_packets.push_back(std::move(padding_packet));
75 }
76 return padding_packets;
77}
78
Erik Språng4314a492019-11-26 17:48:49 +010079} // namespace
80
81namespace test {
82
Erik Språng0f86c1f2021-10-26 16:19:03 +020083std::unique_ptr<RtpPacketToSend> BuildRtpPacket(RtpPacketMediaType type) {
84 auto packet = std::make_unique<RtpPacketToSend>(nullptr);
85 packet->set_packet_type(type);
86 switch (type) {
87 case RtpPacketMediaType::kAudio:
88 packet->SetSsrc(kAudioSsrc);
89 break;
90 case RtpPacketMediaType::kVideo:
91 packet->SetSsrc(kVideoSsrc);
92 break;
93 case RtpPacketMediaType::kRetransmission:
94 case RtpPacketMediaType::kPadding:
95 packet->SetSsrc(kVideoRtxSsrc);
96 break;
97 case RtpPacketMediaType::kForwardErrorCorrection:
98 packet->SetSsrc(kFlexFecSsrc);
99 break;
Erik Språng4314a492019-11-26 17:48:49 +0100100 }
101
Erik Språng0f86c1f2021-10-26 16:19:03 +0200102 packet->SetPayloadSize(kDefaultPacketSize);
103 return packet;
104}
105
106std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePackets(
107 RtpPacketMediaType type,
108 size_t num_packets) {
109 std::vector<std::unique_ptr<RtpPacketToSend>> packets;
110 for (size_t i = 0; i < num_packets; ++i) {
111 packets.push_back(BuildRtpPacket(type));
Erik Språng4314a492019-11-26 17:48:49 +0100112 }
Erik Språng0f86c1f2021-10-26 16:19:03 +0200113 return packets;
114}
Erik Språng4314a492019-11-26 17:48:49 +0100115
Erik Språng0f86c1f2021-10-26 16:19:03 +0200116TEST(TaskQueuePacedSenderTest, PacesPackets) {
117 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
118 MockPacketRouter packet_router;
Erik Språnge486a7b2022-03-15 15:13:25 +0100119 ScopedKeyValueConfig trials;
Jianhui Dai94457792021-12-07 19:34:36 +0800120 TaskQueuePacedSender pacer(
Erik Språng0f86c1f2021-10-26 16:19:03 +0200121 time_controller.GetClock(), &packet_router,
Erik Språnge486a7b2022-03-15 15:13:25 +0100122 /*event_log=*/nullptr, trials, time_controller.GetTaskQueueFactory(),
Mirko Bonadeid8543de2022-03-14 09:13:41 +0000123 PacingController::kMinSleepTime, kNoPacketHoldback);
Erik Språng4314a492019-11-26 17:48:49 +0100124
Erik Språng0f86c1f2021-10-26 16:19:03 +0200125 // Insert a number of packets, covering one second.
126 static constexpr size_t kPacketsToSend = 42;
127 pacer.SetPacingRates(
128 DataRate::BitsPerSec(kDefaultPacketSize * 8 * kPacketsToSend),
129 DataRate::Zero());
130 pacer.EnsureStarted();
131 pacer.EnqueuePackets(
132 GeneratePackets(RtpPacketMediaType::kVideo, kPacketsToSend));
Erik Språng4314a492019-11-26 17:48:49 +0100133
Erik Språng0f86c1f2021-10-26 16:19:03 +0200134 // Expect all of them to be sent.
135 size_t packets_sent = 0;
136 Timestamp end_time = Timestamp::PlusInfinity();
137 EXPECT_CALL(packet_router, SendPacket)
138 .WillRepeatedly([&](std::unique_ptr<RtpPacketToSend> packet,
139 const PacedPacketInfo& cluster_info) {
140 ++packets_sent;
141 if (packets_sent == kPacketsToSend) {
142 end_time = time_controller.GetClock()->CurrentTime();
143 }
144 });
Erik Språng4314a492019-11-26 17:48:49 +0100145
Erik Språng0f86c1f2021-10-26 16:19:03 +0200146 const Timestamp start_time = time_controller.GetClock()->CurrentTime();
Erik Språng4314a492019-11-26 17:48:49 +0100147
Erik Språng0f86c1f2021-10-26 16:19:03 +0200148 // Packets should be sent over a period of close to 1s. Expect a little
149 // lower than this since initial probing is a bit quicker.
150 time_controller.AdvanceTime(TimeDelta::Seconds(1));
151 EXPECT_EQ(packets_sent, kPacketsToSend);
152 ASSERT_TRUE(end_time.IsFinite());
153 EXPECT_NEAR((end_time - start_time).ms<double>(), 1000.0, 50.0);
154}
Erik Språng4314a492019-11-26 17:48:49 +0100155
Erik Språng0f86c1f2021-10-26 16:19:03 +0200156TEST(TaskQueuePacedSenderTest, ReschedulesProcessOnRateChange) {
157 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
158 MockPacketRouter packet_router;
Erik Språnge486a7b2022-03-15 15:13:25 +0100159 ScopedKeyValueConfig trials;
Jianhui Dai94457792021-12-07 19:34:36 +0800160 TaskQueuePacedSender pacer(
Erik Språng0f86c1f2021-10-26 16:19:03 +0200161 time_controller.GetClock(), &packet_router,
Erik Språnge486a7b2022-03-15 15:13:25 +0100162 /*event_log=*/nullptr, trials, time_controller.GetTaskQueueFactory(),
Mirko Bonadeid8543de2022-03-14 09:13:41 +0000163 PacingController::kMinSleepTime, kNoPacketHoldback);
Erik Språng4314a492019-11-26 17:48:49 +0100164
Erik Språng0f86c1f2021-10-26 16:19:03 +0200165 // Insert a number of packets to be sent 200ms apart.
166 const size_t kPacketsPerSecond = 5;
167 const DataRate kPacingRate =
168 DataRate::BitsPerSec(kDefaultPacketSize * 8 * kPacketsPerSecond);
169 pacer.SetPacingRates(kPacingRate, DataRate::Zero());
170 pacer.EnsureStarted();
Erik Språng4314a492019-11-26 17:48:49 +0100171
Erik Språng0f86c1f2021-10-26 16:19:03 +0200172 // Send some initial packets to be rid of any probes.
173 EXPECT_CALL(packet_router, SendPacket).Times(kPacketsPerSecond);
174 pacer.EnqueuePackets(
175 GeneratePackets(RtpPacketMediaType::kVideo, kPacketsPerSecond));
176 time_controller.AdvanceTime(TimeDelta::Seconds(1));
Erik Språng4314a492019-11-26 17:48:49 +0100177
Erik Språng0f86c1f2021-10-26 16:19:03 +0200178 // Insert three packets, and record send time of each of them.
179 // After the second packet is sent, double the send rate so we can
180 // check the third packets is sent after half the wait time.
181 Timestamp first_packet_time = Timestamp::MinusInfinity();
182 Timestamp second_packet_time = Timestamp::MinusInfinity();
183 Timestamp third_packet_time = Timestamp::MinusInfinity();
Erik Språng4314a492019-11-26 17:48:49 +0100184
Erik Språng0f86c1f2021-10-26 16:19:03 +0200185 EXPECT_CALL(packet_router, SendPacket)
186 .Times(3)
187 .WillRepeatedly([&](std::unique_ptr<RtpPacketToSend> packet,
188 const PacedPacketInfo& cluster_info) {
189 if (first_packet_time.IsInfinite()) {
190 first_packet_time = time_controller.GetClock()->CurrentTime();
191 } else if (second_packet_time.IsInfinite()) {
192 second_packet_time = time_controller.GetClock()->CurrentTime();
193 pacer.SetPacingRates(2 * kPacingRate, DataRate::Zero());
194 } else {
195 third_packet_time = time_controller.GetClock()->CurrentTime();
196 }
197 });
Erik Språng4314a492019-11-26 17:48:49 +0100198
Erik Språng0f86c1f2021-10-26 16:19:03 +0200199 pacer.EnqueuePackets(GeneratePackets(RtpPacketMediaType::kVideo, 3));
200 time_controller.AdvanceTime(TimeDelta::Millis(500));
201 ASSERT_TRUE(third_packet_time.IsFinite());
202 EXPECT_NEAR((second_packet_time - first_packet_time).ms<double>(), 200.0,
203 1.0);
204 EXPECT_NEAR((third_packet_time - second_packet_time).ms<double>(), 100.0,
205 1.0);
206}
Erik Språng4314a492019-11-26 17:48:49 +0100207
Erik Språng0f86c1f2021-10-26 16:19:03 +0200208TEST(TaskQueuePacedSenderTest, SendsAudioImmediately) {
209 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
210 MockPacketRouter packet_router;
Erik Språnge486a7b2022-03-15 15:13:25 +0100211 ScopedKeyValueConfig trials;
Jianhui Dai94457792021-12-07 19:34:36 +0800212 TaskQueuePacedSender pacer(
Erik Språng0f86c1f2021-10-26 16:19:03 +0200213 time_controller.GetClock(), &packet_router,
Erik Språnge486a7b2022-03-15 15:13:25 +0100214 /*event_log=*/nullptr, trials, time_controller.GetTaskQueueFactory(),
Mirko Bonadeid8543de2022-03-14 09:13:41 +0000215 PacingController::kMinSleepTime, kNoPacketHoldback);
Erik Språngbe152f52020-04-06 16:30:23 +0200216
Erik Språng0f86c1f2021-10-26 16:19:03 +0200217 const DataRate kPacingDataRate = DataRate::KilobitsPerSec(125);
218 const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize);
219 const TimeDelta kPacketPacingTime = kPacketSize / kPacingDataRate;
Erik Språngbe152f52020-04-06 16:30:23 +0200220
Erik Språng0f86c1f2021-10-26 16:19:03 +0200221 pacer.SetPacingRates(kPacingDataRate, DataRate::Zero());
222 pacer.EnsureStarted();
Erik Språngbe152f52020-04-06 16:30:23 +0200223
Erik Språng0f86c1f2021-10-26 16:19:03 +0200224 // Add some initial video packets, only one should be sent.
225 EXPECT_CALL(packet_router, SendPacket);
226 pacer.EnqueuePackets(GeneratePackets(RtpPacketMediaType::kVideo, 10));
227 time_controller.AdvanceTime(TimeDelta::Zero());
228 ::testing::Mock::VerifyAndClearExpectations(&packet_router);
229
230 // Advance time, but still before next packet should be sent.
231 time_controller.AdvanceTime(kPacketPacingTime / 2);
232
233 // Insert an audio packet, it should be sent immediately.
234 EXPECT_CALL(packet_router, SendPacket);
235 pacer.EnqueuePackets(GeneratePackets(RtpPacketMediaType::kAudio, 1));
236 time_controller.AdvanceTime(TimeDelta::Zero());
237 ::testing::Mock::VerifyAndClearExpectations(&packet_router);
238}
239
240TEST(TaskQueuePacedSenderTest, SleepsDuringCoalscingWindow) {
241 const TimeDelta kCoalescingWindow = TimeDelta::Millis(5);
242 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
243 MockPacketRouter packet_router;
Erik Språnge486a7b2022-03-15 15:13:25 +0100244 ScopedKeyValueConfig trials;
Mirko Bonadeid8543de2022-03-14 09:13:41 +0000245 TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router,
Erik Språnge486a7b2022-03-15 15:13:25 +0100246 /*event_log=*/nullptr, trials,
Mirko Bonadeid8543de2022-03-14 09:13:41 +0000247 time_controller.GetTaskQueueFactory(),
248 kCoalescingWindow, kNoPacketHoldback);
Erik Språng0f86c1f2021-10-26 16:19:03 +0200249
250 // Set rates so one packet adds one ms of buffer level.
251 const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize);
252 const TimeDelta kPacketPacingTime = TimeDelta::Millis(1);
253 const DataRate kPacingDataRate = kPacketSize / kPacketPacingTime;
254
255 pacer.SetPacingRates(kPacingDataRate, DataRate::Zero());
256 pacer.EnsureStarted();
257
258 // Add 10 packets. The first should be sent immediately since the buffers
259 // are clear.
260 EXPECT_CALL(packet_router, SendPacket);
261 pacer.EnqueuePackets(GeneratePackets(RtpPacketMediaType::kVideo, 10));
262 time_controller.AdvanceTime(TimeDelta::Zero());
263 ::testing::Mock::VerifyAndClearExpectations(&packet_router);
264
265 // Advance time to 1ms before the coalescing window ends. No packets should
266 // be sent.
267 EXPECT_CALL(packet_router, SendPacket).Times(0);
268 time_controller.AdvanceTime(kCoalescingWindow - TimeDelta::Millis(1));
269
270 // Advance time to where coalescing window ends. All packets that should
271 // have been sent up til now will be sent.
272 EXPECT_CALL(packet_router, SendPacket).Times(5);
273 time_controller.AdvanceTime(TimeDelta::Millis(1));
274 ::testing::Mock::VerifyAndClearExpectations(&packet_router);
275}
276
277TEST(TaskQueuePacedSenderTest, ProbingOverridesCoalescingWindow) {
278 const TimeDelta kCoalescingWindow = TimeDelta::Millis(5);
279 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
280 MockPacketRouter packet_router;
Erik Språnge486a7b2022-03-15 15:13:25 +0100281 ScopedKeyValueConfig trials;
Mirko Bonadeid8543de2022-03-14 09:13:41 +0000282 TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router,
Erik Språnge486a7b2022-03-15 15:13:25 +0100283 /*event_log=*/nullptr, trials,
Mirko Bonadeid8543de2022-03-14 09:13:41 +0000284 time_controller.GetTaskQueueFactory(),
285 kCoalescingWindow, kNoPacketHoldback);
Erik Språng0f86c1f2021-10-26 16:19:03 +0200286
287 // Set rates so one packet adds one ms of buffer level.
288 const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize);
289 const TimeDelta kPacketPacingTime = TimeDelta::Millis(1);
290 const DataRate kPacingDataRate = kPacketSize / kPacketPacingTime;
291
292 pacer.SetPacingRates(kPacingDataRate, DataRate::Zero());
293 pacer.EnsureStarted();
294
295 // Add 10 packets. The first should be sent immediately since the buffers
296 // are clear. This will also trigger the probe to start.
297 EXPECT_CALL(packet_router, SendPacket).Times(AtLeast(1));
298 pacer.CreateProbeCluster(kPacingDataRate * 2, 17);
299 pacer.EnqueuePackets(GeneratePackets(RtpPacketMediaType::kVideo, 10));
300 time_controller.AdvanceTime(TimeDelta::Zero());
301 ::testing::Mock::VerifyAndClearExpectations(&packet_router);
302
303 // Advance time to 1ms before the coalescing window ends. Packets should be
304 // flying.
305 EXPECT_CALL(packet_router, SendPacket).Times(AtLeast(1));
306 time_controller.AdvanceTime(kCoalescingWindow - TimeDelta::Millis(1));
307}
308
Mirko Bonadeid8543de2022-03-14 09:13:41 +0000309TEST(TaskQueuePacedSenderTest, SchedulesProbeAtSetTime) {
Erik Språnge486a7b2022-03-15 15:13:25 +0100310 ScopedKeyValueConfig trials(
311 "WebRTC-Bwe-ProbingBehavior/min_probe_delta:1ms/");
Erik Språng0f86c1f2021-10-26 16:19:03 +0200312 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
313 MockPacketRouter packet_router;
Jianhui Dai94457792021-12-07 19:34:36 +0800314 TaskQueuePacedSender pacer(
Erik Språng0f86c1f2021-10-26 16:19:03 +0200315 time_controller.GetClock(), &packet_router,
Erik Språnge486a7b2022-03-15 15:13:25 +0100316 /*event_log=*/nullptr, trials, time_controller.GetTaskQueueFactory(),
Mirko Bonadeid8543de2022-03-14 09:13:41 +0000317 PacingController::kMinSleepTime, kNoPacketHoldback);
Erik Språng7d0cde52020-07-19 12:48:16 +0200318
Erik Språng0f86c1f2021-10-26 16:19:03 +0200319 // Set rates so one packet adds 4ms of buffer level.
320 const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize);
321 const TimeDelta kPacketPacingTime = TimeDelta::Millis(4);
322 const DataRate kPacingDataRate = kPacketSize / kPacketPacingTime;
323 pacer.SetPacingRates(kPacingDataRate, /*padding_rate=*/DataRate::Zero());
324 pacer.EnsureStarted();
325 EXPECT_CALL(packet_router, FetchFec).WillRepeatedly([]() {
326 return std::vector<std::unique_ptr<RtpPacketToSend>>();
327 });
328 EXPECT_CALL(packet_router, GeneratePadding(_))
329 .WillRepeatedly(
330 [](DataSize target_size) { return GeneratePadding(target_size); });
Erik Språng7d0cde52020-07-19 12:48:16 +0200331
Erik Språng0f86c1f2021-10-26 16:19:03 +0200332 // Enqueue two packets, only the first is sent immediately and the next
333 // will be scheduled for sending in 4ms.
334 pacer.EnqueuePackets(GeneratePackets(RtpPacketMediaType::kVideo, 2));
335 const int kNotAProbe = PacedPacketInfo::kNotAProbe;
336 EXPECT_CALL(packet_router,
337 SendPacket(_, ::testing::Field(&PacedPacketInfo::probe_cluster_id,
338 kNotAProbe)));
339 // Advance to less than 3ms before next packet send time.
340 time_controller.AdvanceTime(TimeDelta::Micros(1001));
Erik Språng7d0cde52020-07-19 12:48:16 +0200341
Mirko Bonadeid8543de2022-03-14 09:13:41 +0000342 // Trigger a probe at 4x the current pacing rate and insert the number of
Erik Språng0f86c1f2021-10-26 16:19:03 +0200343 // packets the probe needs.
344 const DataRate kProbeRate = 2 * kPacingDataRate;
345 const int kProbeClusterId = 1;
346 pacer.CreateProbeCluster(kProbeRate, kProbeClusterId);
Erik Språng7d0cde52020-07-19 12:48:16 +0200347
Mirko Bonadeid8543de2022-03-14 09:13:41 +0000348 // Expected size for each probe in a cluster is twice the expected bits
349 // sent during min_probe_delta.
350 // Expect one additional call since probe always starts with a small
Erik Språng0f86c1f2021-10-26 16:19:03 +0200351 const TimeDelta kProbeTimeDelta = TimeDelta::Millis(2);
352 const DataSize kProbeSize = kProbeRate * kProbeTimeDelta;
353 const size_t kNumPacketsInProbe =
354 (kProbeSize + kPacketSize - DataSize::Bytes(1)) / kPacketSize;
355 EXPECT_CALL(packet_router,
356 SendPacket(_, ::testing::Field(&PacedPacketInfo::probe_cluster_id,
357 kProbeClusterId)))
358 .Times(kNumPacketsInProbe + 1);
Erik Språng7d0cde52020-07-19 12:48:16 +0200359
Erik Språng0f86c1f2021-10-26 16:19:03 +0200360 pacer.EnqueuePackets(
361 GeneratePackets(RtpPacketMediaType::kVideo, kNumPacketsInProbe));
362 time_controller.AdvanceTime(TimeDelta::Zero());
Erik Språng7d0cde52020-07-19 12:48:16 +0200363
Erik Språng0f86c1f2021-10-26 16:19:03 +0200364 // The pacer should have scheduled the next probe to be sent in
365 // kProbeTimeDelta. That there was existing scheduled call less than
366 // PacingController::kMinSleepTime before this should not matter.
Erik Språng0f86c1f2021-10-26 16:19:03 +0200367 EXPECT_CALL(packet_router,
368 SendPacket(_, ::testing::Field(&PacedPacketInfo::probe_cluster_id,
369 kProbeClusterId)))
370 .Times(AtLeast(1));
371 time_controller.AdvanceTime(TimeDelta::Millis(2));
372}
Erik Språng7d0cde52020-07-19 12:48:16 +0200373
Erik Språng0f86c1f2021-10-26 16:19:03 +0200374TEST(TaskQueuePacedSenderTest, NoMinSleepTimeWhenProbing) {
375 // Set min_probe_delta to be less than kMinSleepTime (1ms).
376 const TimeDelta kMinProbeDelta = TimeDelta::Micros(100);
Erik Språnge486a7b2022-03-15 15:13:25 +0100377 ScopedKeyValueConfig trials(
378 "WebRTC-Bwe-ProbingBehavior/min_probe_delta:100us/");
Erik Språng0f86c1f2021-10-26 16:19:03 +0200379 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
380 MockPacketRouter packet_router;
Jianhui Dai94457792021-12-07 19:34:36 +0800381 TaskQueuePacedSender pacer(
Erik Språng0f86c1f2021-10-26 16:19:03 +0200382 time_controller.GetClock(), &packet_router,
Erik Språnge486a7b2022-03-15 15:13:25 +0100383 /*event_log=*/nullptr, trials, time_controller.GetTaskQueueFactory(),
Mirko Bonadeid8543de2022-03-14 09:13:41 +0000384 PacingController::kMinSleepTime, kNoPacketHoldback);
Erik Språng7d0cde52020-07-19 12:48:16 +0200385
Erik Språng0f86c1f2021-10-26 16:19:03 +0200386 // Set rates so one packet adds 4ms of buffer level.
387 const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize);
388 const TimeDelta kPacketPacingTime = TimeDelta::Millis(4);
389 const DataRate kPacingDataRate = kPacketSize / kPacketPacingTime;
390 pacer.SetPacingRates(kPacingDataRate, /*padding_rate=*/DataRate::Zero());
391 pacer.EnsureStarted();
392 EXPECT_CALL(packet_router, FetchFec).WillRepeatedly([]() {
393 return std::vector<std::unique_ptr<RtpPacketToSend>>();
394 });
395 EXPECT_CALL(packet_router, GeneratePadding)
396 .WillRepeatedly(
397 [](DataSize target_size) { return GeneratePadding(target_size); });
Erik Språng7d0cde52020-07-19 12:48:16 +0200398
Erik Språng0f86c1f2021-10-26 16:19:03 +0200399 // Set a high probe rate.
400 const int kProbeClusterId = 1;
401 DataRate kProbingRate = kPacingDataRate * 10;
402 pacer.CreateProbeCluster(kProbingRate, kProbeClusterId);
Erik Språng7d0cde52020-07-19 12:48:16 +0200403
Erik Språng0f86c1f2021-10-26 16:19:03 +0200404 // Advance time less than PacingController::kMinSleepTime, probing packets
405 // for the first millisecond should be sent immediately. Min delta between
406 // probes is 2x 100us, meaning 4 times per ms we will get least one call to
407 // SendPacket().
408 DataSize data_sent = DataSize::Zero();
409 EXPECT_CALL(packet_router,
410 SendPacket(_, ::testing::Field(&PacedPacketInfo::probe_cluster_id,
411 kProbeClusterId)))
412 .Times(AtLeast(4))
413 .WillRepeatedly([&](std::unique_ptr<RtpPacketToSend> packet,
414 const PacedPacketInfo&) {
415 data_sent +=
416 DataSize::Bytes(packet->payload_size() + packet->padding_size());
417 });
Etienne Pierre-doray03bce3f2021-03-29 17:36:15 +0000418
Erik Språng0f86c1f2021-10-26 16:19:03 +0200419 // Add one packet to kickstart probing, the rest will be padding packets.
420 pacer.EnqueuePackets(GeneratePackets(RtpPacketMediaType::kVideo, 1));
421 time_controller.AdvanceTime(kMinProbeDelta);
Etienne Pierre-doray03bce3f2021-03-29 17:36:15 +0000422
Erik Språng0f86c1f2021-10-26 16:19:03 +0200423 // Verify the amount of probing data sent.
424 // Probe always starts with a small (1 byte) padding packet that's not
425 // counted into the probe rate here.
Mirko Bonadeid8543de2022-03-14 09:13:41 +0000426 EXPECT_EQ(data_sent,
427 kProbingRate * TimeDelta::Millis(1) + DataSize::Bytes(1));
Erik Språng0f86c1f2021-10-26 16:19:03 +0200428}
Etienne Pierre-doray03bce3f2021-03-29 17:36:15 +0000429
Erik Språng0f86c1f2021-10-26 16:19:03 +0200430TEST(TaskQueuePacedSenderTest, PacketBasedCoalescing) {
431 const TimeDelta kFixedCoalescingWindow = TimeDelta::Millis(10);
432 const int kPacketBasedHoldback = 5;
433
434 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
435 MockPacketRouter packet_router;
Erik Språnge486a7b2022-03-15 15:13:25 +0100436 ScopedKeyValueConfig trials;
Jianhui Dai94457792021-12-07 19:34:36 +0800437 TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router,
Erik Språnge486a7b2022-03-15 15:13:25 +0100438 /*event_log=*/nullptr, trials,
Jianhui Dai94457792021-12-07 19:34:36 +0800439 time_controller.GetTaskQueueFactory(),
440 kFixedCoalescingWindow, kPacketBasedHoldback);
Erik Språng0f86c1f2021-10-26 16:19:03 +0200441
442 // Set rates so one packet adds one ms of buffer level.
443 const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize);
444 const TimeDelta kPacketPacingTime = TimeDelta::Millis(1);
445 const DataRate kPacingDataRate = kPacketSize / kPacketPacingTime;
446 const TimeDelta kExpectedHoldbackWindow =
447 kPacketPacingTime * kPacketBasedHoldback;
448 // `kFixedCoalescingWindow` sets the upper bound for the window.
449 ASSERT_GE(kFixedCoalescingWindow, kExpectedHoldbackWindow);
450
451 pacer.SetPacingRates(kPacingDataRate, DataRate::Zero());
452 EXPECT_CALL(packet_router, FetchFec).WillRepeatedly([]() {
453 return std::vector<std::unique_ptr<RtpPacketToSend>>();
454 });
455 pacer.EnsureStarted();
456
457 // Add some packets and wait till all have been sent, so that the pacer
458 // has a valid estimate of packet size.
459 const int kNumWarmupPackets = 40;
460 EXPECT_CALL(packet_router, SendPacket).Times(kNumWarmupPackets);
461 pacer.EnqueuePackets(
462 GeneratePackets(RtpPacketMediaType::kVideo, kNumWarmupPackets));
463 // Wait until all packes have been sent, with a 2x margin.
464 time_controller.AdvanceTime(kPacketPacingTime * (kNumWarmupPackets * 2));
465
466 // Enqueue packets. Expect only the first one to be sent immediately.
467 EXPECT_CALL(packet_router, SendPacket).Times(1);
468 pacer.EnqueuePackets(
469 GeneratePackets(RtpPacketMediaType::kVideo, kPacketBasedHoldback));
470 time_controller.AdvanceTime(TimeDelta::Zero());
471
472 // Advance time to 1ms before the coalescing window ends.
473 EXPECT_CALL(packet_router, SendPacket).Times(0);
474 time_controller.AdvanceTime(kExpectedHoldbackWindow - TimeDelta::Millis(1));
475
476 // Advance past where the coalescing window should end.
477 EXPECT_CALL(packet_router, SendPacket).Times(kPacketBasedHoldback - 1);
478 time_controller.AdvanceTime(TimeDelta::Millis(1));
479}
480
481TEST(TaskQueuePacedSenderTest, FixedHoldBackHasPriorityOverPackets) {
482 const TimeDelta kFixedCoalescingWindow = TimeDelta::Millis(2);
483 const int kPacketBasedHoldback = 5;
484
485 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
486 MockPacketRouter packet_router;
Erik Språnge486a7b2022-03-15 15:13:25 +0100487 ScopedKeyValueConfig trials;
Jianhui Dai94457792021-12-07 19:34:36 +0800488 TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router,
Erik Språnge486a7b2022-03-15 15:13:25 +0100489 /*event_log=*/nullptr, trials,
Jianhui Dai94457792021-12-07 19:34:36 +0800490 time_controller.GetTaskQueueFactory(),
491 kFixedCoalescingWindow, kPacketBasedHoldback);
Erik Språng0f86c1f2021-10-26 16:19:03 +0200492
493 // Set rates so one packet adds one ms of buffer level.
494 const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize);
495 const TimeDelta kPacketPacingTime = TimeDelta::Millis(1);
496 const DataRate kPacingDataRate = kPacketSize / kPacketPacingTime;
497 const TimeDelta kExpectedPacketHoldbackWindow =
498 kPacketPacingTime * kPacketBasedHoldback;
499 // |kFixedCoalescingWindow| sets the upper bound for the window.
500 ASSERT_LT(kFixedCoalescingWindow, kExpectedPacketHoldbackWindow);
501
502 pacer.SetPacingRates(kPacingDataRate, DataRate::Zero());
503 EXPECT_CALL(packet_router, FetchFec).WillRepeatedly([]() {
504 return std::vector<std::unique_ptr<RtpPacketToSend>>();
505 });
506 pacer.EnsureStarted();
507
508 // Add some packets and wait till all have been sent, so that the pacer
509 // has a valid estimate of packet size.
510 const int kNumWarmupPackets = 40;
511 EXPECT_CALL(packet_router, SendPacket).Times(kNumWarmupPackets);
512 pacer.EnqueuePackets(
513 GeneratePackets(RtpPacketMediaType::kVideo, kNumWarmupPackets));
514 // Wait until all packes have been sent, with a 2x margin.
515 time_controller.AdvanceTime(kPacketPacingTime * (kNumWarmupPackets * 2));
516
517 // Enqueue packets. Expect onlt the first one to be sent immediately.
518 EXPECT_CALL(packet_router, SendPacket).Times(1);
519 pacer.EnqueuePackets(
520 GeneratePackets(RtpPacketMediaType::kVideo, kPacketBasedHoldback));
521 time_controller.AdvanceTime(TimeDelta::Zero());
522
523 // Advance time to the fixed coalescing window, that should take presedence so
524 // at least some of the packets should be sent.
525 EXPECT_CALL(packet_router, SendPacket).Times(AtLeast(1));
526 time_controller.AdvanceTime(kFixedCoalescingWindow);
527}
528
Jianhui Dai94457792021-12-07 19:34:36 +0800529TEST(TaskQueuePacedSenderTest, Stats) {
530 static constexpr Timestamp kStartTime = Timestamp::Millis(1234);
531 GlobalSimulatedTimeController time_controller(kStartTime);
532 MockPacketRouter packet_router;
Erik Språnge486a7b2022-03-15 15:13:25 +0100533 ScopedKeyValueConfig trials;
Jianhui Dai94457792021-12-07 19:34:36 +0800534 TaskQueuePacedSender pacer(
535 time_controller.GetClock(), &packet_router,
Erik Språnge486a7b2022-03-15 15:13:25 +0100536 /*event_log=*/nullptr, trials, time_controller.GetTaskQueueFactory(),
Mirko Bonadeid8543de2022-03-14 09:13:41 +0000537 PacingController::kMinSleepTime, kNoPacketHoldback);
Jianhui Dai94457792021-12-07 19:34:36 +0800538
539 // Simulate ~2mbps video stream, covering one second.
540 static constexpr size_t kPacketsToSend = 200;
541 static constexpr DataRate kPacingRate =
542 DataRate::BytesPerSec(kDefaultPacketSize * kPacketsToSend);
543 pacer.SetPacingRates(kPacingRate, DataRate::Zero());
544 pacer.EnsureStarted();
545
546 // Allowed `QueueSizeData` and `ExpectedQueueTime` deviation.
547 static constexpr size_t kAllowedPacketsDeviation = 1;
548 static constexpr DataSize kAllowedQueueSizeDeviation =
549 DataSize::Bytes(kDefaultPacketSize * kAllowedPacketsDeviation);
550 static constexpr TimeDelta kAllowedQueueTimeDeviation =
551 kAllowedQueueSizeDeviation / kPacingRate;
552
553 DataSize expected_queue_size = DataSize::MinusInfinity();
554 TimeDelta expected_queue_time = TimeDelta::MinusInfinity();
555
556 EXPECT_CALL(packet_router, SendPacket).Times(kPacketsToSend);
557
558 // Stats before insert any packets.
559 EXPECT_TRUE(pacer.OldestPacketWaitTime().IsZero());
560 EXPECT_FALSE(pacer.FirstSentPacketTime().has_value());
561 EXPECT_TRUE(pacer.QueueSizeData().IsZero());
562 EXPECT_TRUE(pacer.ExpectedQueueTime().IsZero());
563
564 pacer.EnqueuePackets(
565 GeneratePackets(RtpPacketMediaType::kVideo, kPacketsToSend));
566
567 // Advance to 200ms.
568 time_controller.AdvanceTime(TimeDelta::Millis(200));
569 EXPECT_EQ(pacer.OldestPacketWaitTime(), TimeDelta::Millis(200));
570 EXPECT_EQ(pacer.FirstSentPacketTime(), kStartTime);
571
572 expected_queue_size = kPacingRate * TimeDelta::Millis(800);
573 expected_queue_time = expected_queue_size / kPacingRate;
574 EXPECT_NEAR(pacer.QueueSizeData().bytes(), expected_queue_size.bytes(),
575 kAllowedQueueSizeDeviation.bytes());
576 EXPECT_NEAR(pacer.ExpectedQueueTime().ms(), expected_queue_time.ms(),
577 kAllowedQueueTimeDeviation.ms());
578
579 // Advance to 500ms.
580 time_controller.AdvanceTime(TimeDelta::Millis(300));
581 EXPECT_EQ(pacer.OldestPacketWaitTime(), TimeDelta::Millis(500));
582 EXPECT_EQ(pacer.FirstSentPacketTime(), kStartTime);
583
584 expected_queue_size = kPacingRate * TimeDelta::Millis(500);
585 expected_queue_time = expected_queue_size / kPacingRate;
586 EXPECT_NEAR(pacer.QueueSizeData().bytes(), expected_queue_size.bytes(),
587 kAllowedQueueSizeDeviation.bytes());
588 EXPECT_NEAR(pacer.ExpectedQueueTime().ms(), expected_queue_time.ms(),
589 kAllowedQueueTimeDeviation.ms());
590
591 // Advance to 1000ms+, expect all packets to be sent.
592 time_controller.AdvanceTime(TimeDelta::Millis(500) +
593 kAllowedQueueTimeDeviation);
594 EXPECT_TRUE(pacer.OldestPacketWaitTime().IsZero());
595 EXPECT_EQ(pacer.FirstSentPacketTime(), kStartTime);
596 EXPECT_TRUE(pacer.QueueSizeData().IsZero());
597 EXPECT_TRUE(pacer.ExpectedQueueTime().IsZero());
598}
599
Erik Språng4314a492019-11-26 17:48:49 +0100600} // namespace test
601} // namespace webrtc