blob: e6dfe26834e9016235578a391a42c853ef7bb1ee [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>
Henrik Boström554bb392022-03-16 10:16:29 +010014#include <atomic>
Erik Språng4314a492019-11-26 17:48:49 +010015#include <list>
16#include <memory>
17#include <string>
18#include <utility>
19#include <vector>
20
Danil Chapovalov0be8eba2022-07-06 13:17:54 +020021#include "absl/functional/any_invocable.h"
Henrik Boström554bb392022-03-16 10:16:29 +010022#include "api/task_queue/task_queue_base.h"
Erik Språng7d0cde52020-07-19 12:48:16 +020023#include "api/transport/network_types.h"
Henrik Boström554bb392022-03-16 10:16:29 +010024#include "api/units/data_rate.h"
Erik Språng4314a492019-11-26 17:48:49 +010025#include "modules/pacing/packet_router.h"
Erik Språng4314a492019-11-26 17:48:49 +010026#include "test/gmock.h"
27#include "test/gtest.h"
Erik Språnge486a7b2022-03-15 15:13:25 +010028#include "test/scoped_key_value_config.h"
Erik Språng4314a492019-11-26 17:48:49 +010029#include "test/time_controller/simulated_time_controller.h"
30
31using ::testing::_;
Erik Språng4ab61cb2020-05-19 17:40:58 +020032using ::testing::AtLeast;
Erik Språng4314a492019-11-26 17:48:49 +010033using ::testing::Return;
34using ::testing::SaveArg;
35
36namespace webrtc {
37namespace {
38constexpr uint32_t kAudioSsrc = 12345;
39constexpr uint32_t kVideoSsrc = 234565;
40constexpr uint32_t kVideoRtxSsrc = 34567;
41constexpr uint32_t kFlexFecSsrc = 45678;
42constexpr size_t kDefaultPacketSize = 1234;
43
44class MockPacketRouter : public PacketRouter {
45 public:
Danil Chapovalov014197b2020-05-26 19:18:17 +020046 MOCK_METHOD(void,
47 SendPacket,
48 (std::unique_ptr<RtpPacketToSend> packet,
49 const PacedPacketInfo& cluster_info),
50 (override));
51 MOCK_METHOD(std::vector<std::unique_ptr<RtpPacketToSend>>,
Erik Språng1d50cb62020-07-02 17:41:32 +020052 FetchFec,
53 (),
54 (override));
55 MOCK_METHOD(std::vector<std::unique_ptr<RtpPacketToSend>>,
Danil Chapovalov014197b2020-05-26 19:18:17 +020056 GeneratePadding,
Erik Språnged1fb192020-06-30 11:53:37 +000057 (DataSize target_size),
Danil Chapovalov014197b2020-05-26 19:18:17 +020058 (override));
Erik Språng4314a492019-11-26 17:48:49 +010059};
Erik Språng998524a2020-05-29 16:13:32 +020060
Erik Språng7d0cde52020-07-19 12:48:16 +020061std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePadding(
62 DataSize target_size) {
63 // 224 bytes is the max padding size for plain padding packets generated by
64 // RTPSender::GeneratePadding().
65 const DataSize kMaxPaddingPacketSize = DataSize::Bytes(224);
66 DataSize padding_generated = DataSize::Zero();
67 std::vector<std::unique_ptr<RtpPacketToSend>> padding_packets;
68 while (padding_generated < target_size) {
69 DataSize packet_size =
70 std::min(target_size - padding_generated, kMaxPaddingPacketSize);
71 padding_generated += packet_size;
72 auto padding_packet =
73 std::make_unique<RtpPacketToSend>(/*extensions=*/nullptr);
74 padding_packet->set_packet_type(RtpPacketMediaType::kPadding);
75 padding_packet->SetPadding(packet_size.bytes());
76 padding_packets.push_back(std::move(padding_packet));
77 }
78 return padding_packets;
79}
80
Henrik Boström554bb392022-03-16 10:16:29 +010081class TaskQueueWithFakePrecisionFactory : public TaskQueueFactory {
82 public:
83 explicit TaskQueueWithFakePrecisionFactory(
84 TaskQueueFactory* task_queue_factory)
85 : task_queue_factory_(task_queue_factory) {}
86
87 std::unique_ptr<TaskQueueBase, TaskQueueDeleter> CreateTaskQueue(
88 absl::string_view name,
89 Priority priority) const override {
90 return std::unique_ptr<TaskQueueBase, TaskQueueDeleter>(
91 new TaskQueueWithFakePrecision(
92 const_cast<TaskQueueWithFakePrecisionFactory*>(this),
93 task_queue_factory_));
94 }
95
96 int delayed_low_precision_count() const {
97 return delayed_low_precision_count_;
98 }
99 int delayed_high_precision_count() const {
100 return delayed_high_precision_count_;
101 }
102
103 private:
104 friend class TaskQueueWithFakePrecision;
105
106 class TaskQueueWithFakePrecision : public TaskQueueBase {
107 public:
108 TaskQueueWithFakePrecision(
109 TaskQueueWithFakePrecisionFactory* parent_factory,
110 TaskQueueFactory* task_queue_factory)
111 : parent_factory_(parent_factory),
112 task_queue_(task_queue_factory->CreateTaskQueue(
113 "TaskQueueWithFakePrecision",
114 TaskQueueFactory::Priority::NORMAL)) {}
115 ~TaskQueueWithFakePrecision() override {}
116
117 void Delete() override {
118 // `task_queue_->Delete()` is implicitly called in the destructor due to
119 // TaskQueueDeleter.
120 delete this;
121 }
Danil Chapovalov0be8eba2022-07-06 13:17:54 +0200122 void PostTask(absl::AnyInvocable<void() &&> task) override {
123 task_queue_->PostTask(WrapTask(std::move(task)));
Henrik Boström554bb392022-03-16 10:16:29 +0100124 }
Danil Chapovalov0be8eba2022-07-06 13:17:54 +0200125 void PostDelayedTask(absl::AnyInvocable<void() &&> task,
126 TimeDelta delay) override {
Henrik Boström554bb392022-03-16 10:16:29 +0100127 ++parent_factory_->delayed_low_precision_count_;
Danil Chapovalov0be8eba2022-07-06 13:17:54 +0200128 task_queue_->PostDelayedTask(WrapTask(std::move(task)), delay);
Henrik Boström554bb392022-03-16 10:16:29 +0100129 }
Danil Chapovalov0be8eba2022-07-06 13:17:54 +0200130 void PostDelayedHighPrecisionTask(absl::AnyInvocable<void() &&> task,
131 TimeDelta delay) override {
Henrik Boström554bb392022-03-16 10:16:29 +0100132 ++parent_factory_->delayed_high_precision_count_;
Danil Chapovalov0be8eba2022-07-06 13:17:54 +0200133 task_queue_->PostDelayedHighPrecisionTask(WrapTask(std::move(task)),
134 delay);
Henrik Boström554bb392022-03-16 10:16:29 +0100135 }
136
137 private:
Danil Chapovalov0be8eba2022-07-06 13:17:54 +0200138 absl::AnyInvocable<void() &&> WrapTask(absl::AnyInvocable<void() &&> task) {
139 return [this, task = std::move(task)]() mutable {
140 CurrentTaskQueueSetter set_current(this);
141 std::move(task)();
142 };
Henrik Boström554bb392022-03-16 10:16:29 +0100143 }
144
145 TaskQueueWithFakePrecisionFactory* parent_factory_;
146 std::unique_ptr<TaskQueueBase, TaskQueueDeleter> task_queue_;
147 };
148
149 TaskQueueFactory* task_queue_factory_;
150 std::atomic<int> delayed_low_precision_count_ = 0u;
151 std::atomic<int> delayed_high_precision_count_ = 0u;
152};
153
Erik Språng4314a492019-11-26 17:48:49 +0100154} // namespace
155
156namespace test {
157
Erik Språng0f86c1f2021-10-26 16:19:03 +0200158std::unique_ptr<RtpPacketToSend> BuildRtpPacket(RtpPacketMediaType type) {
159 auto packet = std::make_unique<RtpPacketToSend>(nullptr);
160 packet->set_packet_type(type);
161 switch (type) {
162 case RtpPacketMediaType::kAudio:
163 packet->SetSsrc(kAudioSsrc);
164 break;
165 case RtpPacketMediaType::kVideo:
166 packet->SetSsrc(kVideoSsrc);
167 break;
168 case RtpPacketMediaType::kRetransmission:
169 case RtpPacketMediaType::kPadding:
170 packet->SetSsrc(kVideoRtxSsrc);
171 break;
172 case RtpPacketMediaType::kForwardErrorCorrection:
173 packet->SetSsrc(kFlexFecSsrc);
174 break;
Erik Språng4314a492019-11-26 17:48:49 +0100175 }
176
Erik Språng0f86c1f2021-10-26 16:19:03 +0200177 packet->SetPayloadSize(kDefaultPacketSize);
178 return packet;
179}
180
181std::vector<std::unique_ptr<RtpPacketToSend>> GeneratePackets(
182 RtpPacketMediaType type,
183 size_t num_packets) {
184 std::vector<std::unique_ptr<RtpPacketToSend>> packets;
185 for (size_t i = 0; i < num_packets; ++i) {
186 packets.push_back(BuildRtpPacket(type));
Erik Språng4314a492019-11-26 17:48:49 +0100187 }
Erik Språng0f86c1f2021-10-26 16:19:03 +0200188 return packets;
189}
Erik Språng4314a492019-11-26 17:48:49 +0100190
Erik Språng0f86c1f2021-10-26 16:19:03 +0200191TEST(TaskQueuePacedSenderTest, PacesPackets) {
192 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
193 MockPacketRouter packet_router;
Erik Språnge486a7b2022-03-15 15:13:25 +0100194 ScopedKeyValueConfig trials;
Erik Språng1a080962022-03-17 15:16:59 +0100195 TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials,
196 time_controller.GetTaskQueueFactory(),
197 PacingController::kMinSleepTime,
Jianhui Daidf59e532022-03-19 15:38:51 +0800198 TaskQueuePacedSender::kNoPacketHoldback);
Erik Språng4314a492019-11-26 17:48:49 +0100199
Erik Språng0f86c1f2021-10-26 16:19:03 +0200200 // Insert a number of packets, covering one second.
201 static constexpr size_t kPacketsToSend = 42;
202 pacer.SetPacingRates(
203 DataRate::BitsPerSec(kDefaultPacketSize * 8 * kPacketsToSend),
204 DataRate::Zero());
205 pacer.EnsureStarted();
206 pacer.EnqueuePackets(
207 GeneratePackets(RtpPacketMediaType::kVideo, kPacketsToSend));
Erik Språng4314a492019-11-26 17:48:49 +0100208
Erik Språng0f86c1f2021-10-26 16:19:03 +0200209 // Expect all of them to be sent.
210 size_t packets_sent = 0;
211 Timestamp end_time = Timestamp::PlusInfinity();
212 EXPECT_CALL(packet_router, SendPacket)
213 .WillRepeatedly([&](std::unique_ptr<RtpPacketToSend> packet,
214 const PacedPacketInfo& cluster_info) {
215 ++packets_sent;
216 if (packets_sent == kPacketsToSend) {
217 end_time = time_controller.GetClock()->CurrentTime();
218 }
219 });
Erik Språng4314a492019-11-26 17:48:49 +0100220
Erik Språng0f86c1f2021-10-26 16:19:03 +0200221 const Timestamp start_time = time_controller.GetClock()->CurrentTime();
Erik Språng4314a492019-11-26 17:48:49 +0100222
Erik Språng0f86c1f2021-10-26 16:19:03 +0200223 // Packets should be sent over a period of close to 1s. Expect a little
224 // lower than this since initial probing is a bit quicker.
225 time_controller.AdvanceTime(TimeDelta::Seconds(1));
226 EXPECT_EQ(packets_sent, kPacketsToSend);
227 ASSERT_TRUE(end_time.IsFinite());
228 EXPECT_NEAR((end_time - start_time).ms<double>(), 1000.0, 50.0);
229}
Erik Språng4314a492019-11-26 17:48:49 +0100230
Erik Språng0f86c1f2021-10-26 16:19:03 +0200231TEST(TaskQueuePacedSenderTest, ReschedulesProcessOnRateChange) {
232 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
233 MockPacketRouter packet_router;
Erik Språnge486a7b2022-03-15 15:13:25 +0100234 ScopedKeyValueConfig trials;
Erik Språng1a080962022-03-17 15:16:59 +0100235 TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials,
236 time_controller.GetTaskQueueFactory(),
237 PacingController::kMinSleepTime,
Jianhui Daidf59e532022-03-19 15:38:51 +0800238 TaskQueuePacedSender::kNoPacketHoldback);
Erik Språng4314a492019-11-26 17:48:49 +0100239
Erik Språng0f86c1f2021-10-26 16:19:03 +0200240 // Insert a number of packets to be sent 200ms apart.
241 const size_t kPacketsPerSecond = 5;
242 const DataRate kPacingRate =
243 DataRate::BitsPerSec(kDefaultPacketSize * 8 * kPacketsPerSecond);
244 pacer.SetPacingRates(kPacingRate, DataRate::Zero());
245 pacer.EnsureStarted();
Erik Språng4314a492019-11-26 17:48:49 +0100246
Erik Språng0f86c1f2021-10-26 16:19:03 +0200247 // Send some initial packets to be rid of any probes.
248 EXPECT_CALL(packet_router, SendPacket).Times(kPacketsPerSecond);
249 pacer.EnqueuePackets(
250 GeneratePackets(RtpPacketMediaType::kVideo, kPacketsPerSecond));
251 time_controller.AdvanceTime(TimeDelta::Seconds(1));
Erik Språng4314a492019-11-26 17:48:49 +0100252
Erik Språng0f86c1f2021-10-26 16:19:03 +0200253 // Insert three packets, and record send time of each of them.
254 // After the second packet is sent, double the send rate so we can
255 // check the third packets is sent after half the wait time.
256 Timestamp first_packet_time = Timestamp::MinusInfinity();
257 Timestamp second_packet_time = Timestamp::MinusInfinity();
258 Timestamp third_packet_time = Timestamp::MinusInfinity();
Erik Språng4314a492019-11-26 17:48:49 +0100259
Erik Språng0f86c1f2021-10-26 16:19:03 +0200260 EXPECT_CALL(packet_router, SendPacket)
261 .Times(3)
262 .WillRepeatedly([&](std::unique_ptr<RtpPacketToSend> packet,
263 const PacedPacketInfo& cluster_info) {
264 if (first_packet_time.IsInfinite()) {
265 first_packet_time = time_controller.GetClock()->CurrentTime();
266 } else if (second_packet_time.IsInfinite()) {
267 second_packet_time = time_controller.GetClock()->CurrentTime();
268 pacer.SetPacingRates(2 * kPacingRate, DataRate::Zero());
269 } else {
270 third_packet_time = time_controller.GetClock()->CurrentTime();
271 }
272 });
Erik Språng4314a492019-11-26 17:48:49 +0100273
Erik Språng0f86c1f2021-10-26 16:19:03 +0200274 pacer.EnqueuePackets(GeneratePackets(RtpPacketMediaType::kVideo, 3));
275 time_controller.AdvanceTime(TimeDelta::Millis(500));
276 ASSERT_TRUE(third_packet_time.IsFinite());
277 EXPECT_NEAR((second_packet_time - first_packet_time).ms<double>(), 200.0,
278 1.0);
279 EXPECT_NEAR((third_packet_time - second_packet_time).ms<double>(), 100.0,
280 1.0);
281}
Erik Språng4314a492019-11-26 17:48:49 +0100282
Erik Språng0f86c1f2021-10-26 16:19:03 +0200283TEST(TaskQueuePacedSenderTest, SendsAudioImmediately) {
284 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
285 MockPacketRouter packet_router;
Erik Språnge486a7b2022-03-15 15:13:25 +0100286 ScopedKeyValueConfig trials;
Erik Språng1a080962022-03-17 15:16:59 +0100287 TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials,
288 time_controller.GetTaskQueueFactory(),
289 PacingController::kMinSleepTime,
Jianhui Daidf59e532022-03-19 15:38:51 +0800290 TaskQueuePacedSender::kNoPacketHoldback);
Erik Språngbe152f52020-04-06 16:30:23 +0200291
Erik Språng0f86c1f2021-10-26 16:19:03 +0200292 const DataRate kPacingDataRate = DataRate::KilobitsPerSec(125);
293 const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize);
294 const TimeDelta kPacketPacingTime = kPacketSize / kPacingDataRate;
Erik Språngbe152f52020-04-06 16:30:23 +0200295
Erik Språng0f86c1f2021-10-26 16:19:03 +0200296 pacer.SetPacingRates(kPacingDataRate, DataRate::Zero());
297 pacer.EnsureStarted();
Erik Språngbe152f52020-04-06 16:30:23 +0200298
Erik Språng0f86c1f2021-10-26 16:19:03 +0200299 // Add some initial video packets, only one should be sent.
300 EXPECT_CALL(packet_router, SendPacket);
301 pacer.EnqueuePackets(GeneratePackets(RtpPacketMediaType::kVideo, 10));
302 time_controller.AdvanceTime(TimeDelta::Zero());
303 ::testing::Mock::VerifyAndClearExpectations(&packet_router);
304
305 // Advance time, but still before next packet should be sent.
306 time_controller.AdvanceTime(kPacketPacingTime / 2);
307
308 // Insert an audio packet, it should be sent immediately.
309 EXPECT_CALL(packet_router, SendPacket);
310 pacer.EnqueuePackets(GeneratePackets(RtpPacketMediaType::kAudio, 1));
311 time_controller.AdvanceTime(TimeDelta::Zero());
312 ::testing::Mock::VerifyAndClearExpectations(&packet_router);
313}
314
315TEST(TaskQueuePacedSenderTest, SleepsDuringCoalscingWindow) {
316 const TimeDelta kCoalescingWindow = TimeDelta::Millis(5);
317 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
318 MockPacketRouter packet_router;
Erik Språnge486a7b2022-03-15 15:13:25 +0100319 ScopedKeyValueConfig trials;
Erik Språng1a080962022-03-17 15:16:59 +0100320 TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials,
Mirko Bonadeid8543de2022-03-14 09:13:41 +0000321 time_controller.GetTaskQueueFactory(),
Jianhui Daidf59e532022-03-19 15:38:51 +0800322 kCoalescingWindow,
323 TaskQueuePacedSender::kNoPacketHoldback);
Erik Språng0f86c1f2021-10-26 16:19:03 +0200324
325 // Set rates so one packet adds one ms of buffer level.
326 const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize);
327 const TimeDelta kPacketPacingTime = TimeDelta::Millis(1);
328 const DataRate kPacingDataRate = kPacketSize / kPacketPacingTime;
329
330 pacer.SetPacingRates(kPacingDataRate, DataRate::Zero());
331 pacer.EnsureStarted();
332
333 // Add 10 packets. The first should be sent immediately since the buffers
334 // are clear.
335 EXPECT_CALL(packet_router, SendPacket);
336 pacer.EnqueuePackets(GeneratePackets(RtpPacketMediaType::kVideo, 10));
337 time_controller.AdvanceTime(TimeDelta::Zero());
338 ::testing::Mock::VerifyAndClearExpectations(&packet_router);
339
340 // Advance time to 1ms before the coalescing window ends. No packets should
341 // be sent.
342 EXPECT_CALL(packet_router, SendPacket).Times(0);
343 time_controller.AdvanceTime(kCoalescingWindow - TimeDelta::Millis(1));
344
345 // Advance time to where coalescing window ends. All packets that should
346 // have been sent up til now will be sent.
347 EXPECT_CALL(packet_router, SendPacket).Times(5);
348 time_controller.AdvanceTime(TimeDelta::Millis(1));
349 ::testing::Mock::VerifyAndClearExpectations(&packet_router);
350}
351
352TEST(TaskQueuePacedSenderTest, ProbingOverridesCoalescingWindow) {
353 const TimeDelta kCoalescingWindow = TimeDelta::Millis(5);
354 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
355 MockPacketRouter packet_router;
Erik Språnge486a7b2022-03-15 15:13:25 +0100356 ScopedKeyValueConfig trials;
Erik Språng1a080962022-03-17 15:16:59 +0100357 TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials,
Mirko Bonadeid8543de2022-03-14 09:13:41 +0000358 time_controller.GetTaskQueueFactory(),
Jianhui Daidf59e532022-03-19 15:38:51 +0800359 kCoalescingWindow,
360 TaskQueuePacedSender::kNoPacketHoldback);
Erik Språng0f86c1f2021-10-26 16:19:03 +0200361
362 // Set rates so one packet adds one ms of buffer level.
363 const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize);
364 const TimeDelta kPacketPacingTime = TimeDelta::Millis(1);
365 const DataRate kPacingDataRate = kPacketSize / kPacketPacingTime;
366
367 pacer.SetPacingRates(kPacingDataRate, DataRate::Zero());
368 pacer.EnsureStarted();
369
370 // Add 10 packets. The first should be sent immediately since the buffers
371 // are clear. This will also trigger the probe to start.
372 EXPECT_CALL(packet_router, SendPacket).Times(AtLeast(1));
Per Kjellander88af2032022-05-16 19:58:40 +0200373 pacer.CreateProbeClusters(
374 {{.at_time = time_controller.GetClock()->CurrentTime(),
375 .target_data_rate = kPacingDataRate * 2,
376 .target_duration = TimeDelta::Millis(15),
377 .target_probe_count = 5,
378 .id = 17}});
Erik Språng0f86c1f2021-10-26 16:19:03 +0200379 pacer.EnqueuePackets(GeneratePackets(RtpPacketMediaType::kVideo, 10));
380 time_controller.AdvanceTime(TimeDelta::Zero());
381 ::testing::Mock::VerifyAndClearExpectations(&packet_router);
382
383 // Advance time to 1ms before the coalescing window ends. Packets should be
384 // flying.
385 EXPECT_CALL(packet_router, SendPacket).Times(AtLeast(1));
386 time_controller.AdvanceTime(kCoalescingWindow - TimeDelta::Millis(1));
387}
388
Jianhui Daidf59e532022-03-19 15:38:51 +0800389TEST(TaskQueuePacedSenderTest, SchedulesProbeAtSentTime) {
Erik Språnge486a7b2022-03-15 15:13:25 +0100390 ScopedKeyValueConfig trials(
391 "WebRTC-Bwe-ProbingBehavior/min_probe_delta:1ms/");
Erik Språng0f86c1f2021-10-26 16:19:03 +0200392 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
393 MockPacketRouter packet_router;
Erik Språng1a080962022-03-17 15:16:59 +0100394 TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials,
395 time_controller.GetTaskQueueFactory(),
396 PacingController::kMinSleepTime,
Jianhui Daidf59e532022-03-19 15:38:51 +0800397 TaskQueuePacedSender::kNoPacketHoldback);
Erik Språng7d0cde52020-07-19 12:48:16 +0200398
Erik Språng0f86c1f2021-10-26 16:19:03 +0200399 // Set rates so one packet adds 4ms of buffer level.
400 const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize);
401 const TimeDelta kPacketPacingTime = TimeDelta::Millis(4);
402 const DataRate kPacingDataRate = kPacketSize / kPacketPacingTime;
403 pacer.SetPacingRates(kPacingDataRate, /*padding_rate=*/DataRate::Zero());
404 pacer.EnsureStarted();
405 EXPECT_CALL(packet_router, FetchFec).WillRepeatedly([]() {
406 return std::vector<std::unique_ptr<RtpPacketToSend>>();
407 });
408 EXPECT_CALL(packet_router, GeneratePadding(_))
409 .WillRepeatedly(
410 [](DataSize target_size) { return GeneratePadding(target_size); });
Erik Språng7d0cde52020-07-19 12:48:16 +0200411
Erik Språng0f86c1f2021-10-26 16:19:03 +0200412 // Enqueue two packets, only the first is sent immediately and the next
413 // will be scheduled for sending in 4ms.
414 pacer.EnqueuePackets(GeneratePackets(RtpPacketMediaType::kVideo, 2));
415 const int kNotAProbe = PacedPacketInfo::kNotAProbe;
416 EXPECT_CALL(packet_router,
417 SendPacket(_, ::testing::Field(&PacedPacketInfo::probe_cluster_id,
418 kNotAProbe)));
419 // Advance to less than 3ms before next packet send time.
420 time_controller.AdvanceTime(TimeDelta::Micros(1001));
Erik Språng7d0cde52020-07-19 12:48:16 +0200421
Jianhui Daidf59e532022-03-19 15:38:51 +0800422 // Trigger a probe at 2x the current pacing rate and insert the number of
Erik Språng0f86c1f2021-10-26 16:19:03 +0200423 // packets the probe needs.
424 const DataRate kProbeRate = 2 * kPacingDataRate;
425 const int kProbeClusterId = 1;
Per Kjellander88af2032022-05-16 19:58:40 +0200426 pacer.CreateProbeClusters(
427 {{.at_time = time_controller.GetClock()->CurrentTime(),
428 .target_data_rate = kProbeRate,
429 .target_duration = TimeDelta::Millis(15),
430 .target_probe_count = 4,
431 .id = kProbeClusterId}});
Erik Språng7d0cde52020-07-19 12:48:16 +0200432
Jianhui Daidf59e532022-03-19 15:38:51 +0800433 // Expected size for each probe in a cluster is twice the expected bits sent
434 // during min_probe_delta.
435 // Expect one additional call since probe always starts with a small (1 byte)
436 // padding packet that's not counted into the probe rate here.
Erik Språng0f86c1f2021-10-26 16:19:03 +0200437 const TimeDelta kProbeTimeDelta = TimeDelta::Millis(2);
438 const DataSize kProbeSize = kProbeRate * kProbeTimeDelta;
439 const size_t kNumPacketsInProbe =
440 (kProbeSize + kPacketSize - DataSize::Bytes(1)) / kPacketSize;
441 EXPECT_CALL(packet_router,
442 SendPacket(_, ::testing::Field(&PacedPacketInfo::probe_cluster_id,
443 kProbeClusterId)))
444 .Times(kNumPacketsInProbe + 1);
Erik Språng7d0cde52020-07-19 12:48:16 +0200445
Erik Språng0f86c1f2021-10-26 16:19:03 +0200446 pacer.EnqueuePackets(
447 GeneratePackets(RtpPacketMediaType::kVideo, kNumPacketsInProbe));
448 time_controller.AdvanceTime(TimeDelta::Zero());
Erik Språng7d0cde52020-07-19 12:48:16 +0200449
Erik Språng0f86c1f2021-10-26 16:19:03 +0200450 // The pacer should have scheduled the next probe to be sent in
451 // kProbeTimeDelta. That there was existing scheduled call less than
452 // PacingController::kMinSleepTime before this should not matter.
Erik Språng0f86c1f2021-10-26 16:19:03 +0200453 EXPECT_CALL(packet_router,
454 SendPacket(_, ::testing::Field(&PacedPacketInfo::probe_cluster_id,
455 kProbeClusterId)))
456 .Times(AtLeast(1));
457 time_controller.AdvanceTime(TimeDelta::Millis(2));
458}
Erik Språng7d0cde52020-07-19 12:48:16 +0200459
Erik Språng0f86c1f2021-10-26 16:19:03 +0200460TEST(TaskQueuePacedSenderTest, NoMinSleepTimeWhenProbing) {
461 // Set min_probe_delta to be less than kMinSleepTime (1ms).
462 const TimeDelta kMinProbeDelta = TimeDelta::Micros(100);
Erik Språnge486a7b2022-03-15 15:13:25 +0100463 ScopedKeyValueConfig trials(
464 "WebRTC-Bwe-ProbingBehavior/min_probe_delta:100us/");
Erik Språng0f86c1f2021-10-26 16:19:03 +0200465 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
466 MockPacketRouter packet_router;
Erik Språng1a080962022-03-17 15:16:59 +0100467 TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials,
468 time_controller.GetTaskQueueFactory(),
469 PacingController::kMinSleepTime,
Jianhui Daidf59e532022-03-19 15:38:51 +0800470 TaskQueuePacedSender::kNoPacketHoldback);
Erik Språng7d0cde52020-07-19 12:48:16 +0200471
Erik Språng0f86c1f2021-10-26 16:19:03 +0200472 // Set rates so one packet adds 4ms of buffer level.
473 const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize);
474 const TimeDelta kPacketPacingTime = TimeDelta::Millis(4);
475 const DataRate kPacingDataRate = kPacketSize / kPacketPacingTime;
476 pacer.SetPacingRates(kPacingDataRate, /*padding_rate=*/DataRate::Zero());
477 pacer.EnsureStarted();
478 EXPECT_CALL(packet_router, FetchFec).WillRepeatedly([]() {
479 return std::vector<std::unique_ptr<RtpPacketToSend>>();
480 });
481 EXPECT_CALL(packet_router, GeneratePadding)
482 .WillRepeatedly(
483 [](DataSize target_size) { return GeneratePadding(target_size); });
Erik Språng7d0cde52020-07-19 12:48:16 +0200484
Erik Språng0f86c1f2021-10-26 16:19:03 +0200485 // Set a high probe rate.
486 const int kProbeClusterId = 1;
487 DataRate kProbingRate = kPacingDataRate * 10;
Per Kjellander88af2032022-05-16 19:58:40 +0200488
489 pacer.CreateProbeClusters(
490 {{.at_time = time_controller.GetClock()->CurrentTime(),
491 .target_data_rate = kProbingRate,
492 .target_duration = TimeDelta::Millis(15),
493 .target_probe_count = 5,
494 .id = kProbeClusterId}});
Erik Språng7d0cde52020-07-19 12:48:16 +0200495
Erik Språng0f86c1f2021-10-26 16:19:03 +0200496 // Advance time less than PacingController::kMinSleepTime, probing packets
497 // for the first millisecond should be sent immediately. Min delta between
498 // probes is 2x 100us, meaning 4 times per ms we will get least one call to
499 // SendPacket().
500 DataSize data_sent = DataSize::Zero();
501 EXPECT_CALL(packet_router,
502 SendPacket(_, ::testing::Field(&PacedPacketInfo::probe_cluster_id,
503 kProbeClusterId)))
504 .Times(AtLeast(4))
505 .WillRepeatedly([&](std::unique_ptr<RtpPacketToSend> packet,
506 const PacedPacketInfo&) {
507 data_sent +=
508 DataSize::Bytes(packet->payload_size() + packet->padding_size());
509 });
Etienne Pierre-doray03bce3f2021-03-29 17:36:15 +0000510
Erik Språng0f86c1f2021-10-26 16:19:03 +0200511 // Add one packet to kickstart probing, the rest will be padding packets.
512 pacer.EnqueuePackets(GeneratePackets(RtpPacketMediaType::kVideo, 1));
513 time_controller.AdvanceTime(kMinProbeDelta);
Etienne Pierre-doray03bce3f2021-03-29 17:36:15 +0000514
Erik Språng0f86c1f2021-10-26 16:19:03 +0200515 // Verify the amount of probing data sent.
516 // Probe always starts with a small (1 byte) padding packet that's not
517 // counted into the probe rate here.
Jianhui Daidf59e532022-03-19 15:38:51 +0800518 const DataSize kMinProbeSize = 2 * kMinProbeDelta * kProbingRate;
519 EXPECT_EQ(data_sent, DataSize::Bytes(1) + kPacketSize + 4 * kMinProbeSize);
Erik Språng0f86c1f2021-10-26 16:19:03 +0200520}
Etienne Pierre-doray03bce3f2021-03-29 17:36:15 +0000521
Erik Språng0f86c1f2021-10-26 16:19:03 +0200522TEST(TaskQueuePacedSenderTest, PacketBasedCoalescing) {
523 const TimeDelta kFixedCoalescingWindow = TimeDelta::Millis(10);
524 const int kPacketBasedHoldback = 5;
525
526 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
527 MockPacketRouter packet_router;
Erik Språnge486a7b2022-03-15 15:13:25 +0100528 ScopedKeyValueConfig trials;
Erik Språng1a080962022-03-17 15:16:59 +0100529 TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials,
Jianhui Dai94457792021-12-07 19:34:36 +0800530 time_controller.GetTaskQueueFactory(),
531 kFixedCoalescingWindow, kPacketBasedHoldback);
Erik Språng0f86c1f2021-10-26 16:19:03 +0200532
533 // Set rates so one packet adds one ms of buffer level.
534 const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize);
535 const TimeDelta kPacketPacingTime = TimeDelta::Millis(1);
536 const DataRate kPacingDataRate = kPacketSize / kPacketPacingTime;
537 const TimeDelta kExpectedHoldbackWindow =
538 kPacketPacingTime * kPacketBasedHoldback;
539 // `kFixedCoalescingWindow` sets the upper bound for the window.
540 ASSERT_GE(kFixedCoalescingWindow, kExpectedHoldbackWindow);
541
542 pacer.SetPacingRates(kPacingDataRate, DataRate::Zero());
543 EXPECT_CALL(packet_router, FetchFec).WillRepeatedly([]() {
544 return std::vector<std::unique_ptr<RtpPacketToSend>>();
545 });
546 pacer.EnsureStarted();
547
548 // Add some packets and wait till all have been sent, so that the pacer
549 // has a valid estimate of packet size.
550 const int kNumWarmupPackets = 40;
551 EXPECT_CALL(packet_router, SendPacket).Times(kNumWarmupPackets);
552 pacer.EnqueuePackets(
553 GeneratePackets(RtpPacketMediaType::kVideo, kNumWarmupPackets));
554 // Wait until all packes have been sent, with a 2x margin.
555 time_controller.AdvanceTime(kPacketPacingTime * (kNumWarmupPackets * 2));
556
557 // Enqueue packets. Expect only the first one to be sent immediately.
558 EXPECT_CALL(packet_router, SendPacket).Times(1);
559 pacer.EnqueuePackets(
560 GeneratePackets(RtpPacketMediaType::kVideo, kPacketBasedHoldback));
561 time_controller.AdvanceTime(TimeDelta::Zero());
562
563 // Advance time to 1ms before the coalescing window ends.
564 EXPECT_CALL(packet_router, SendPacket).Times(0);
565 time_controller.AdvanceTime(kExpectedHoldbackWindow - TimeDelta::Millis(1));
566
567 // Advance past where the coalescing window should end.
568 EXPECT_CALL(packet_router, SendPacket).Times(kPacketBasedHoldback - 1);
569 time_controller.AdvanceTime(TimeDelta::Millis(1));
570}
571
572TEST(TaskQueuePacedSenderTest, FixedHoldBackHasPriorityOverPackets) {
573 const TimeDelta kFixedCoalescingWindow = TimeDelta::Millis(2);
574 const int kPacketBasedHoldback = 5;
575
576 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
577 MockPacketRouter packet_router;
Erik Språnge486a7b2022-03-15 15:13:25 +0100578 ScopedKeyValueConfig trials;
Erik Språng1a080962022-03-17 15:16:59 +0100579 TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials,
Jianhui Dai94457792021-12-07 19:34:36 +0800580 time_controller.GetTaskQueueFactory(),
581 kFixedCoalescingWindow, kPacketBasedHoldback);
Erik Språng0f86c1f2021-10-26 16:19:03 +0200582
583 // Set rates so one packet adds one ms of buffer level.
584 const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize);
585 const TimeDelta kPacketPacingTime = TimeDelta::Millis(1);
586 const DataRate kPacingDataRate = kPacketSize / kPacketPacingTime;
587 const TimeDelta kExpectedPacketHoldbackWindow =
588 kPacketPacingTime * kPacketBasedHoldback;
589 // |kFixedCoalescingWindow| sets the upper bound for the window.
590 ASSERT_LT(kFixedCoalescingWindow, kExpectedPacketHoldbackWindow);
591
592 pacer.SetPacingRates(kPacingDataRate, DataRate::Zero());
593 EXPECT_CALL(packet_router, FetchFec).WillRepeatedly([]() {
594 return std::vector<std::unique_ptr<RtpPacketToSend>>();
595 });
596 pacer.EnsureStarted();
597
598 // Add some packets and wait till all have been sent, so that the pacer
599 // has a valid estimate of packet size.
600 const int kNumWarmupPackets = 40;
601 EXPECT_CALL(packet_router, SendPacket).Times(kNumWarmupPackets);
602 pacer.EnqueuePackets(
603 GeneratePackets(RtpPacketMediaType::kVideo, kNumWarmupPackets));
604 // Wait until all packes have been sent, with a 2x margin.
605 time_controller.AdvanceTime(kPacketPacingTime * (kNumWarmupPackets * 2));
606
607 // Enqueue packets. Expect onlt the first one to be sent immediately.
608 EXPECT_CALL(packet_router, SendPacket).Times(1);
609 pacer.EnqueuePackets(
610 GeneratePackets(RtpPacketMediaType::kVideo, kPacketBasedHoldback));
611 time_controller.AdvanceTime(TimeDelta::Zero());
612
613 // Advance time to the fixed coalescing window, that should take presedence so
614 // at least some of the packets should be sent.
615 EXPECT_CALL(packet_router, SendPacket).Times(AtLeast(1));
616 time_controller.AdvanceTime(kFixedCoalescingWindow);
617}
618
Jianhui Daidf59e532022-03-19 15:38:51 +0800619TEST(TaskQueuePacedSenderTest, ProbingStopDuringSendLoop) {
620 // Set a low `min_probe_delta` to let probing finish during send loop.
621 ScopedKeyValueConfig trials(
622 "WebRTC-Bwe-ProbingBehavior/min_probe_delta:100us/");
623
624 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
625 MockPacketRouter packet_router;
626 TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials,
627 time_controller.GetTaskQueueFactory(),
628 PacingController::kMinSleepTime,
629 TaskQueuePacedSender::kNoPacketHoldback);
630
631 // Set rates so 2 packets adds 1ms of buffer level.
632 const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize);
633 const TimeDelta kPacketPacingTime = TimeDelta::Millis(1);
634 const DataRate kPacingDataRate = 2 * kPacketSize / kPacketPacingTime;
635
636 pacer.SetPacingRates(kPacingDataRate, DataRate::Zero());
637 pacer.EnsureStarted();
638
639 EXPECT_CALL(packet_router, FetchFec).WillRepeatedly([]() {
640 return std::vector<std::unique_ptr<RtpPacketToSend>>();
641 });
642 EXPECT_CALL(packet_router, GeneratePadding(_))
643 .WillRepeatedly(
644 [](DataSize target_size) { return GeneratePadding(target_size); });
645
646 // Set probe rate.
647 const int kProbeClusterId = 1;
648 const DataRate kProbingRate = kPacingDataRate;
Per Kjellander88af2032022-05-16 19:58:40 +0200649
650 pacer.CreateProbeClusters(
651 {{.at_time = time_controller.GetClock()->CurrentTime(),
652 .target_data_rate = kProbingRate,
653 .target_duration = TimeDelta::Millis(15),
654 .target_probe_count = 4,
655 .id = kProbeClusterId}});
Jianhui Daidf59e532022-03-19 15:38:51 +0800656
657 const int kPacketsToSend = 100;
658 const TimeDelta kPacketsPacedTime =
659 std::max(kPacketsToSend * kPacketSize / kPacingDataRate,
660 kPacketsToSend * kPacketSize / kProbingRate);
661
662 // Expect all packets and one padding packet sent.
663 EXPECT_CALL(packet_router, SendPacket).Times(kPacketsToSend + 1);
664 pacer.EnqueuePackets(
665 GeneratePackets(RtpPacketMediaType::kVideo, kPacketsToSend));
666 time_controller.AdvanceTime(kPacketsPacedTime + TimeDelta::Millis(1));
667}
668
Jianhui Dai94457792021-12-07 19:34:36 +0800669TEST(TaskQueuePacedSenderTest, Stats) {
670 static constexpr Timestamp kStartTime = Timestamp::Millis(1234);
671 GlobalSimulatedTimeController time_controller(kStartTime);
672 MockPacketRouter packet_router;
Erik Språnge486a7b2022-03-15 15:13:25 +0100673 ScopedKeyValueConfig trials;
Erik Språng1a080962022-03-17 15:16:59 +0100674 TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials,
675 time_controller.GetTaskQueueFactory(),
676 PacingController::kMinSleepTime,
Jianhui Daidf59e532022-03-19 15:38:51 +0800677 TaskQueuePacedSender::kNoPacketHoldback);
Jianhui Dai94457792021-12-07 19:34:36 +0800678
679 // Simulate ~2mbps video stream, covering one second.
680 static constexpr size_t kPacketsToSend = 200;
681 static constexpr DataRate kPacingRate =
682 DataRate::BytesPerSec(kDefaultPacketSize * kPacketsToSend);
683 pacer.SetPacingRates(kPacingRate, DataRate::Zero());
684 pacer.EnsureStarted();
685
686 // Allowed `QueueSizeData` and `ExpectedQueueTime` deviation.
687 static constexpr size_t kAllowedPacketsDeviation = 1;
688 static constexpr DataSize kAllowedQueueSizeDeviation =
689 DataSize::Bytes(kDefaultPacketSize * kAllowedPacketsDeviation);
690 static constexpr TimeDelta kAllowedQueueTimeDeviation =
691 kAllowedQueueSizeDeviation / kPacingRate;
692
693 DataSize expected_queue_size = DataSize::MinusInfinity();
694 TimeDelta expected_queue_time = TimeDelta::MinusInfinity();
695
696 EXPECT_CALL(packet_router, SendPacket).Times(kPacketsToSend);
697
698 // Stats before insert any packets.
699 EXPECT_TRUE(pacer.OldestPacketWaitTime().IsZero());
700 EXPECT_FALSE(pacer.FirstSentPacketTime().has_value());
701 EXPECT_TRUE(pacer.QueueSizeData().IsZero());
702 EXPECT_TRUE(pacer.ExpectedQueueTime().IsZero());
703
704 pacer.EnqueuePackets(
705 GeneratePackets(RtpPacketMediaType::kVideo, kPacketsToSend));
706
707 // Advance to 200ms.
708 time_controller.AdvanceTime(TimeDelta::Millis(200));
709 EXPECT_EQ(pacer.OldestPacketWaitTime(), TimeDelta::Millis(200));
710 EXPECT_EQ(pacer.FirstSentPacketTime(), kStartTime);
711
712 expected_queue_size = kPacingRate * TimeDelta::Millis(800);
713 expected_queue_time = expected_queue_size / kPacingRate;
714 EXPECT_NEAR(pacer.QueueSizeData().bytes(), expected_queue_size.bytes(),
715 kAllowedQueueSizeDeviation.bytes());
716 EXPECT_NEAR(pacer.ExpectedQueueTime().ms(), expected_queue_time.ms(),
717 kAllowedQueueTimeDeviation.ms());
718
719 // Advance to 500ms.
720 time_controller.AdvanceTime(TimeDelta::Millis(300));
721 EXPECT_EQ(pacer.OldestPacketWaitTime(), TimeDelta::Millis(500));
722 EXPECT_EQ(pacer.FirstSentPacketTime(), kStartTime);
723
724 expected_queue_size = kPacingRate * TimeDelta::Millis(500);
725 expected_queue_time = expected_queue_size / kPacingRate;
726 EXPECT_NEAR(pacer.QueueSizeData().bytes(), expected_queue_size.bytes(),
727 kAllowedQueueSizeDeviation.bytes());
728 EXPECT_NEAR(pacer.ExpectedQueueTime().ms(), expected_queue_time.ms(),
729 kAllowedQueueTimeDeviation.ms());
730
731 // Advance to 1000ms+, expect all packets to be sent.
732 time_controller.AdvanceTime(TimeDelta::Millis(500) +
733 kAllowedQueueTimeDeviation);
734 EXPECT_TRUE(pacer.OldestPacketWaitTime().IsZero());
735 EXPECT_EQ(pacer.FirstSentPacketTime(), kStartTime);
736 EXPECT_TRUE(pacer.QueueSizeData().IsZero());
737 EXPECT_TRUE(pacer.ExpectedQueueTime().IsZero());
738}
739
Henrik Boström554bb392022-03-16 10:16:29 +0100740TEST(TaskQueuePacedSenderTest, HighPrecisionPacingWhenSlackIsDisabled) {
741 test::ScopedKeyValueConfig experiments(
742 "WebRTC-SlackedTaskQueuePacedSender/Disabled/");
743
744 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
745 TaskQueueWithFakePrecisionFactory task_queue_factory(
746 time_controller.GetTaskQueueFactory());
747
748 MockPacketRouter packet_router;
Jianhui Daidf59e532022-03-19 15:38:51 +0800749 TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router,
750 experiments, &task_queue_factory,
751 PacingController::kMinSleepTime,
752 TaskQueuePacedSender::kNoPacketHoldback);
Henrik Boström554bb392022-03-16 10:16:29 +0100753
754 // Send enough packets (covering one second) that pacing is triggered, i.e.
755 // delayed tasks being scheduled.
756 static constexpr size_t kPacketsToSend = 42;
757 static constexpr DataRate kPacingRate =
758 DataRate::BitsPerSec(kDefaultPacketSize * 8 * kPacketsToSend);
759 pacer.SetPacingRates(kPacingRate, DataRate::Zero());
760 pacer.EnsureStarted();
761 pacer.EnqueuePackets(
762 GeneratePackets(RtpPacketMediaType::kVideo, kPacketsToSend));
763 // Expect all of them to be sent.
764 size_t packets_sent = 0;
765 EXPECT_CALL(packet_router, SendPacket)
766 .WillRepeatedly(
767 [&](std::unique_ptr<RtpPacketToSend> packet,
768 const PacedPacketInfo& cluster_info) { ++packets_sent; });
769 time_controller.AdvanceTime(TimeDelta::Seconds(1));
770 EXPECT_EQ(packets_sent, kPacketsToSend);
771
772 // Expect pacing to make use of high precision.
773 EXPECT_EQ(task_queue_factory.delayed_low_precision_count(), 0);
774 EXPECT_GT(task_queue_factory.delayed_high_precision_count(), 0);
775
776 // Create probe cluster which is also high precision.
Per Kjellander88af2032022-05-16 19:58:40 +0200777 pacer.CreateProbeClusters(
778 {{.at_time = time_controller.GetClock()->CurrentTime(),
779 .target_data_rate = kPacingRate,
780 .target_duration = TimeDelta::Millis(15),
781 .target_probe_count = 4,
782 .id = 123}});
Henrik Boström554bb392022-03-16 10:16:29 +0100783 pacer.EnqueuePackets(GeneratePackets(RtpPacketMediaType::kVideo, 1));
784 time_controller.AdvanceTime(TimeDelta::Seconds(1));
785 EXPECT_EQ(task_queue_factory.delayed_low_precision_count(), 0);
786 EXPECT_GT(task_queue_factory.delayed_high_precision_count(), 0);
787}
788
789TEST(TaskQueuePacedSenderTest, LowPrecisionPacingWhenSlackIsEnabled) {
790 test::ScopedKeyValueConfig experiments(
791 "WebRTC-SlackedTaskQueuePacedSender/Enabled/");
792
793 GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234));
794 TaskQueueWithFakePrecisionFactory task_queue_factory(
795 time_controller.GetTaskQueueFactory());
796
797 MockPacketRouter packet_router;
Jianhui Daidf59e532022-03-19 15:38:51 +0800798 TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router,
799 experiments, &task_queue_factory,
800 PacingController::kMinSleepTime,
801 TaskQueuePacedSender::kNoPacketHoldback);
Henrik Boström554bb392022-03-16 10:16:29 +0100802
803 // Send enough packets (covering one second) that pacing is triggered, i.e.
804 // delayed tasks being scheduled.
805 static constexpr size_t kPacketsToSend = 42;
806 static constexpr DataRate kPacingRate =
807 DataRate::BitsPerSec(kDefaultPacketSize * 8 * kPacketsToSend);
808 pacer.SetPacingRates(kPacingRate, DataRate::Zero());
809 pacer.EnsureStarted();
810 pacer.EnqueuePackets(
811 GeneratePackets(RtpPacketMediaType::kVideo, kPacketsToSend));
812 // Expect all of them to be sent.
813 size_t packets_sent = 0;
814 EXPECT_CALL(packet_router, SendPacket)
815 .WillRepeatedly(
816 [&](std::unique_ptr<RtpPacketToSend> packet,
817 const PacedPacketInfo& cluster_info) { ++packets_sent; });
818 time_controller.AdvanceTime(TimeDelta::Seconds(1));
819 EXPECT_EQ(packets_sent, kPacketsToSend);
820
821 // Expect pacing to make use of low precision.
822 EXPECT_GT(task_queue_factory.delayed_low_precision_count(), 0);
823 EXPECT_EQ(task_queue_factory.delayed_high_precision_count(), 0);
824
825 // Create probe cluster, which uses high precision despite regular pacing
826 // being low precision.
Per Kjellander88af2032022-05-16 19:58:40 +0200827 pacer.CreateProbeClusters(
828 {{.at_time = time_controller.GetClock()->CurrentTime(),
829 .target_data_rate = kPacingRate,
830 .target_duration = TimeDelta::Millis(15),
831 .target_probe_count = 4,
832 .id = 123}});
Henrik Boström554bb392022-03-16 10:16:29 +0100833 pacer.EnqueuePackets(GeneratePackets(RtpPacketMediaType::kVideo, 1));
834 time_controller.AdvanceTime(TimeDelta::Seconds(1));
835 EXPECT_GT(task_queue_factory.delayed_high_precision_count(), 0);
836}
837
Erik Språng4314a492019-11-26 17:48:49 +0100838} // namespace test
839} // namespace webrtc