blob: fb79ebcbaf5f2c39994dd0e25491ec301626e2e1 [file] [log] [blame]
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +00001/*
2 * Copyright (c) 2012 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
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000011#include <list>
kwiberg22feaa32016-03-17 09:17:43 -070012#include <memory>
philipelccdfcca2017-10-23 12:42:17 +020013#include <string>
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000014
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "modules/pacing/paced_sender.h"
16#include "system_wrappers/include/clock.h"
philipelccdfcca2017-10-23 12:42:17 +020017#include "system_wrappers/include/field_trial.h"
18#include "test/field_trial.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "test/gmock.h"
20#include "test/gtest.h"
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000021
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +000022using testing::_;
philipelc7bf32a2017-02-17 03:59:43 -080023using testing::Field;
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000024using testing::Return;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000025
isheriffcc5903e2016-10-04 08:29:38 -070026namespace {
27constexpr unsigned kFirstClusterBps = 900000;
isheriffcc5903e2016-10-04 08:29:38 -070028constexpr unsigned kSecondClusterBps = 1800000;
isheriffcc5903e2016-10-04 08:29:38 -070029
30// The error stems from truncating the time interval of probe packets to integer
31// values. This results in probing slightly higher than the target bitrate.
32// For 1.8 Mbps, this comes to be about 120 kbps with 1200 probe packets.
33constexpr int kBitrateProbingError = 150000;
Sebastian Jansson439f0bc2018-02-20 10:46:39 +010034
35const float kPaceMultiplier = 2.5f;
isheriffcc5903e2016-10-04 08:29:38 -070036} // namespace
37
Danil Chapovalov74a369c2018-02-14 10:48:49 +000038namespace webrtc {
39namespace test {
40
41static const int kTargetBitrateBps = 800000;
42
perkjec81bcd2016-05-11 06:01:13 -070043class MockPacedSenderCallback : public PacedSender::PacketSender {
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000044 public:
philipel29dca2c2016-05-13 11:13:05 +020045 MOCK_METHOD5(TimeToSendPacket,
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000046 bool(uint32_t ssrc,
47 uint16_t sequence_number,
48 int64_t capture_time_ms,
philipel29dca2c2016-05-13 11:13:05 +020049 bool retransmission,
philipelc7bf32a2017-02-17 03:59:43 -080050 const PacedPacketInfo& pacing_info));
51 MOCK_METHOD2(TimeToSendPadding,
52 size_t(size_t bytes, const PacedPacketInfo& pacing_info));
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000053};
54
perkjec81bcd2016-05-11 06:01:13 -070055class PacedSenderPadding : public PacedSender::PacketSender {
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000056 public:
57 PacedSenderPadding() : padding_sent_(0) {}
58
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000059 bool TimeToSendPacket(uint32_t ssrc,
60 uint16_t sequence_number,
61 int64_t capture_time_ms,
philipel29dca2c2016-05-13 11:13:05 +020062 bool retransmission,
philipelc7bf32a2017-02-17 03:59:43 -080063 const PacedPacketInfo& pacing_info) override {
hclam@chromium.org2e402ce2013-06-20 20:18:31 +000064 return true;
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000065 }
66
philipelc7bf32a2017-02-17 03:59:43 -080067 size_t TimeToSendPadding(size_t bytes,
68 const PacedPacketInfo& pacing_info) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000069 const size_t kPaddingPacketSize = 224;
70 size_t num_packets = (bytes + kPaddingPacketSize - 1) / kPaddingPacketSize;
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000071 padding_sent_ += kPaddingPacketSize * num_packets;
72 return kPaddingPacketSize * num_packets;
73 }
74
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000075 size_t padding_sent() { return padding_sent_; }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000076
77 private:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000078 size_t padding_sent_;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000079};
80
perkjec81bcd2016-05-11 06:01:13 -070081class PacedSenderProbing : public PacedSender::PacketSender {
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000082 public:
isheriffcc5903e2016-10-04 08:29:38 -070083 PacedSenderProbing() : packets_sent_(0), padding_sent_(0) {}
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000084
85 bool TimeToSendPacket(uint32_t ssrc,
86 uint16_t sequence_number,
87 int64_t capture_time_ms,
philipel29dca2c2016-05-13 11:13:05 +020088 bool retransmission,
philipelc7bf32a2017-02-17 03:59:43 -080089 const PacedPacketInfo& pacing_info) override {
isheriffcc5903e2016-10-04 08:29:38 -070090 packets_sent_++;
Stefan Holmer01b48882015-05-05 10:21:24 +020091 return true;
92 }
93
philipelc7bf32a2017-02-17 03:59:43 -080094 size_t TimeToSendPadding(size_t bytes,
95 const PacedPacketInfo& pacing_info) override {
isheriffcc5903e2016-10-04 08:29:38 -070096 padding_sent_ += bytes;
97 return padding_sent_;
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000098 }
99
100 int packets_sent() const { return packets_sent_; }
101
isheriffcc5903e2016-10-04 08:29:38 -0700102 int padding_sent() const { return padding_sent_; }
103
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000104 private:
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000105 int packets_sent_;
isheriffcc5903e2016-10-04 08:29:38 -0700106 int padding_sent_;
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000107};
108
philipelccdfcca2017-10-23 12:42:17 +0200109class PacedSenderTest : public testing::TestWithParam<std::string> {
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000110 protected:
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +0100111 PacedSenderTest() : clock_(123456) {
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000112 srand(0);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000113 // Need to initialize PacedSender after we initialize clock.
philipelc3b3f7a2017-03-29 01:23:13 -0700114 send_bucket_.reset(new PacedSender(&clock_, &callback_, nullptr));
philipelfd58b612017-01-04 07:05:25 -0800115 send_bucket_->CreateProbeCluster(kFirstClusterBps);
116 send_bucket_->CreateProbeCluster(kSecondClusterBps);
stefan@webrtc.orge9f0f592015-02-16 15:47:51 +0000117 // Default to bitrate probing disabled for testing purposes. Probing tests
118 // have to enable probing, either by creating a new PacedSender instance or
119 // by calling SetProbingEnabled(true).
120 send_bucket_->SetProbingEnabled(false);
Sebastian Jansson439f0bc2018-02-20 10:46:39 +0100121 send_bucket_->SetPacingRates(kTargetBitrateBps * kPaceMultiplier, 0);
perkjec81bcd2016-05-11 06:01:13 -0700122
123 clock_.AdvanceTimeMilliseconds(send_bucket_->TimeUntilNextProcess());
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000124 }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000125
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000126 void SendAndExpectPacket(PacedSender::Priority priority,
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000127 uint32_t ssrc,
128 uint16_t sequence_number,
129 int64_t capture_time_ms,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000130 size_t size,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000131 bool retransmission) {
Peter Boströme23e7372015-10-08 11:44:14 +0200132 send_bucket_->InsertPacket(priority, ssrc, sequence_number, capture_time_ms,
133 size, retransmission);
philipel29dca2c2016-05-13 11:13:05 +0200134 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number,
tereliusf39f7d92016-07-20 03:36:19 -0700135 capture_time_ms, retransmission, _))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000136 .Times(1)
137 .WillRepeatedly(Return(true));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000138 }
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000139 SimulatedClock clock_;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000140 MockPacedSenderCallback callback_;
kwiberg22feaa32016-03-17 09:17:43 -0700141 std::unique_ptr<PacedSender> send_bucket_;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000142};
143
Sebastian Janssonc235a8d2018-06-15 14:46:11 +0200144class PacedSenderFieldTrialTest : public testing::Test {
145 protected:
146 struct MediaStream {
147 const RtpPacketSender::Priority priority;
148 const uint32_t ssrc;
149 const size_t packet_size;
150 uint16_t seq_num;
151 };
152
153 const int kProcessIntervalsPerSecond = 1000 / 5;
154
155 PacedSenderFieldTrialTest() : clock_(123456) {}
156 void InsertPacket(PacedSender* pacer, MediaStream* stream) {
157 pacer->InsertPacket(stream->priority, stream->ssrc, stream->seq_num++,
158 clock_.TimeInMilliseconds(), stream->packet_size,
159 false);
160 }
161 void ProcessNext(PacedSender* pacer) {
162 clock_.AdvanceTimeMilliseconds(5);
163 pacer->Process();
164 }
165 MediaStream audio{/*priority*/ PacedSender::kHighPriority,
166 /*ssrc*/ 3333, /*packet_size*/ 100, /*seq_num*/ 1000};
167 MediaStream video{/*priority*/ PacedSender::kNormalPriority,
168 /*ssrc*/ 4444, /*packet_size*/ 1000, /*seq_num*/ 1000};
169 SimulatedClock clock_;
170 MockPacedSenderCallback callback_;
171};
172
173TEST_F(PacedSenderFieldTrialTest, DefaultNoPaddingInSilence) {
174 PacedSender pacer(&clock_, &callback_, nullptr);
175 pacer.SetPacingRates(kTargetBitrateBps, 0);
176 // Video packet to reset last send time and provide padding data.
177 InsertPacket(&pacer, &video);
178 EXPECT_CALL(callback_, TimeToSendPacket).WillOnce(Return(true));
179 clock_.AdvanceTimeMilliseconds(5);
180 pacer.Process();
181 EXPECT_CALL(callback_, TimeToSendPadding).Times(0);
182 // Waiting 500 ms should not trigger sending of padding.
183 clock_.AdvanceTimeMilliseconds(500);
184 pacer.Process();
185}
186
187TEST_F(PacedSenderFieldTrialTest, PaddingInSilenceWithTrial) {
188 ScopedFieldTrials trial("WebRTC-Pacer-PadInSilence/Enabled/");
189 PacedSender pacer(&clock_, &callback_, nullptr);
190 pacer.SetPacingRates(kTargetBitrateBps, 0);
191 // Video packet to reset last send time and provide padding data.
192 InsertPacket(&pacer, &video);
193 EXPECT_CALL(callback_, TimeToSendPacket).WillOnce(Return(true));
194 clock_.AdvanceTimeMilliseconds(5);
195 pacer.Process();
196 EXPECT_CALL(callback_, TimeToSendPadding).WillOnce(Return(1000));
197 // Waiting 500 ms should trigger sending of padding.
198 clock_.AdvanceTimeMilliseconds(500);
199 pacer.Process();
200}
201
Sebastian Janssonce4829a2018-06-15 14:47:35 +0200202TEST_F(PacedSenderFieldTrialTest, DefaultCongestionWindowAffectsAudio) {
203 EXPECT_CALL(callback_, TimeToSendPadding).Times(0);
204 PacedSender pacer(&clock_, &callback_, nullptr);
205 pacer.SetPacingRates(10000000, 0);
206 pacer.SetCongestionWindow(800);
207 pacer.UpdateOutstandingData(0);
208 // Video packet fills congestion window.
209 InsertPacket(&pacer, &video);
210 EXPECT_CALL(callback_, TimeToSendPacket).WillOnce(Return(true));
211 ProcessNext(&pacer);
212 // Audio packet blocked due to congestion.
213 InsertPacket(&pacer, &audio);
214 EXPECT_CALL(callback_, TimeToSendPacket).Times(0);
215 ProcessNext(&pacer);
216 ProcessNext(&pacer);
217 // Audio packet unblocked when congestion window clear.
218 testing::Mock::VerifyAndClearExpectations(&callback_);
219 pacer.UpdateOutstandingData(0);
220 EXPECT_CALL(callback_, TimeToSendPacket).WillOnce(Return(true));
221 ProcessNext(&pacer);
222}
223
224TEST_F(PacedSenderFieldTrialTest, CongestionWindowDoesNotAffectAudioInTrial) {
225 ScopedFieldTrials trial("WebRTC-Pacer-BlockAudio/Disabled/");
226 EXPECT_CALL(callback_, TimeToSendPadding).Times(0);
227 PacedSender pacer(&clock_, &callback_, nullptr);
228 pacer.SetPacingRates(10000000, 0);
229 pacer.SetCongestionWindow(800);
230 pacer.UpdateOutstandingData(0);
231 // Video packet fills congestion window.
232 InsertPacket(&pacer, &video);
233 EXPECT_CALL(callback_, TimeToSendPacket).WillOnce(Return(true));
234 ProcessNext(&pacer);
235 // Audio not blocked due to congestion.
236 InsertPacket(&pacer, &audio);
237 EXPECT_CALL(callback_, TimeToSendPacket).WillOnce(Return(true));
238 ProcessNext(&pacer);
239}
240
241TEST_F(PacedSenderFieldTrialTest, DefaultBudgetAffectsAudio) {
242 PacedSender pacer(&clock_, &callback_, nullptr);
243 pacer.SetPacingRates(video.packet_size / 3 * 8 * kProcessIntervalsPerSecond,
244 0);
245 // Video fills budget for following process periods.
246 InsertPacket(&pacer, &video);
247 EXPECT_CALL(callback_, TimeToSendPacket).WillOnce(Return(true));
248 ProcessNext(&pacer);
249 // Audio packet blocked due to budget limit.
250 EXPECT_CALL(callback_, TimeToSendPacket).Times(0);
251 InsertPacket(&pacer, &audio);
252 ProcessNext(&pacer);
253 ProcessNext(&pacer);
254 testing::Mock::VerifyAndClearExpectations(&callback_);
255 // Audio packet unblocked when the budget has recovered.
256 EXPECT_CALL(callback_, TimeToSendPacket).WillOnce(Return(true));
257 ProcessNext(&pacer);
258 ProcessNext(&pacer);
259}
260
261TEST_F(PacedSenderFieldTrialTest, BudgetDoesNotAffectAudioInTrial) {
262 ScopedFieldTrials trial("WebRTC-Pacer-BlockAudio/Disabled/");
263 EXPECT_CALL(callback_, TimeToSendPadding).Times(0);
264 PacedSender pacer(&clock_, &callback_, nullptr);
265 pacer.SetPacingRates(video.packet_size / 3 * 8 * kProcessIntervalsPerSecond,
266 0);
267 // Video fills budget for following process periods.
268 InsertPacket(&pacer, &video);
269 EXPECT_CALL(callback_, TimeToSendPacket).WillOnce(Return(true));
270 ProcessNext(&pacer);
271 // Audio packet not blocked due to budget limit.
272 EXPECT_CALL(callback_, TimeToSendPacket).WillOnce(Return(true));
273 InsertPacket(&pacer, &audio);
274 ProcessNext(&pacer);
275}
276
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +0100277TEST_F(PacedSenderTest, FirstSentPacketTimeIsSet) {
asaperssonfc5e81c2017-04-19 23:28:53 -0700278 uint16_t sequence_number = 1234;
279 const uint32_t kSsrc = 12345;
280 const size_t kSizeBytes = 250;
281 const size_t kPacketToSend = 3;
282 const int64_t kStartMs = clock_.TimeInMilliseconds();
283
284 // No packet sent.
285 EXPECT_EQ(-1, send_bucket_->FirstSentPacketTimeMs());
286
287 for (size_t i = 0; i < kPacketToSend; ++i) {
288 SendAndExpectPacket(PacedSender::kNormalPriority, kSsrc, sequence_number++,
289 clock_.TimeInMilliseconds(), kSizeBytes, false);
290 send_bucket_->Process();
291 clock_.AdvanceTimeMilliseconds(send_bucket_->TimeUntilNextProcess());
292 }
293 EXPECT_EQ(kStartMs, send_bucket_->FirstSentPacketTimeMs());
294}
295
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +0100296TEST_F(PacedSenderTest, QueuePacket) {
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000297 uint32_t ssrc = 12345;
298 uint16_t sequence_number = 1234;
Danil Chapovalov74a369c2018-02-14 10:48:49 +0000299 // Due to the multiplicative factor we can send 5 packets during a send
300 // interval. (network capacity * multiplier / (8 bits per byte *
301 // (packet size * #send intervals per second)
302 const size_t packets_to_send =
Sebastian Jansson439f0bc2018-02-20 10:46:39 +0100303 kTargetBitrateBps * kPaceMultiplier / (8 * 250 * 200);
perkjec81bcd2016-05-11 06:01:13 -0700304 for (size_t i = 0; i < packets_to_send; ++i) {
305 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
306 clock_.TimeInMilliseconds(), 250, false);
307 }
308
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000309 int64_t queued_packet_timestamp = clock_.TimeInMilliseconds();
Peter Boströme23e7372015-10-08 11:44:14 +0200310 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
311 sequence_number, queued_packet_timestamp, 250,
312 false);
perkjec81bcd2016-05-11 06:01:13 -0700313 EXPECT_EQ(packets_to_send + 1, send_bucket_->QueueSizePackets());
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000314 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000315 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
philipela1ed0b32016-06-01 06:31:17 -0700316 EXPECT_CALL(callback_, TimeToSendPadding(_, _)).Times(0);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000317 clock_.AdvanceTimeMilliseconds(4);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000318 EXPECT_EQ(1, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000319 clock_.AdvanceTimeMilliseconds(1);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000320 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
perkjec81bcd2016-05-11 06:01:13 -0700321 EXPECT_EQ(1u, send_bucket_->QueueSizePackets());
philipel29dca2c2016-05-13 11:13:05 +0200322 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number++,
323 queued_packet_timestamp, false, _))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000324 .Times(1)
325 .WillRepeatedly(Return(true));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000326 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000327 sequence_number++;
perkjec81bcd2016-05-11 06:01:13 -0700328 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
329
330 // We can send packets_to_send -1 packets of size 250 during the current
331 // interval since one packet has already been sent.
332 for (size_t i = 0; i < packets_to_send - 1; ++i) {
333 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
334 clock_.TimeInMilliseconds(), 250, false);
335 }
Peter Boströme23e7372015-10-08 11:44:14 +0200336 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
337 sequence_number++, clock_.TimeInMilliseconds(),
338 250, false);
perkjec81bcd2016-05-11 06:01:13 -0700339 EXPECT_EQ(packets_to_send, send_bucket_->QueueSizePackets());
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000340 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700341 EXPECT_EQ(1u, send_bucket_->QueueSizePackets());
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000342}
343
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +0100344TEST_F(PacedSenderTest, PaceQueuedPackets) {
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000345 uint32_t ssrc = 12345;
346 uint16_t sequence_number = 1234;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000347
Danil Chapovalov74a369c2018-02-14 10:48:49 +0000348 // Due to the multiplicative factor we can send 5 packets during a send
349 // interval. (network capacity * multiplier / (8 bits per byte *
350 // (packet size * #send intervals per second)
351 const size_t packets_to_send_per_interval =
Sebastian Jansson439f0bc2018-02-20 10:46:39 +0100352 kTargetBitrateBps * kPaceMultiplier / (8 * 250 * 200);
perkjec81bcd2016-05-11 06:01:13 -0700353 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
354 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
355 clock_.TimeInMilliseconds(), 250, false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000356 }
perkjec81bcd2016-05-11 06:01:13 -0700357
358 for (size_t j = 0; j < packets_to_send_per_interval * 10; ++j) {
Peter Boströme23e7372015-10-08 11:44:14 +0200359 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
360 sequence_number++, clock_.TimeInMilliseconds(),
361 250, false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000362 }
perkjec81bcd2016-05-11 06:01:13 -0700363 EXPECT_EQ(packets_to_send_per_interval + packets_to_send_per_interval * 10,
364 send_bucket_->QueueSizePackets());
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000365 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700366 EXPECT_EQ(packets_to_send_per_interval * 10,
367 send_bucket_->QueueSizePackets());
philipela1ed0b32016-06-01 06:31:17 -0700368 EXPECT_CALL(callback_, TimeToSendPadding(_, _)).Times(0);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000369 for (int k = 0; k < 10; ++k) {
370 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000371 clock_.AdvanceTimeMilliseconds(5);
philipel29dca2c2016-05-13 11:13:05 +0200372 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, _, _, false, _))
perkjec81bcd2016-05-11 06:01:13 -0700373 .Times(packets_to_send_per_interval)
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000374 .WillRepeatedly(Return(true));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000375 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800376 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000377 }
perkjec81bcd2016-05-11 06:01:13 -0700378 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000379 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000380 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000381 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
perkjec81bcd2016-05-11 06:01:13 -0700382 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
pbosa26ac922016-02-25 04:50:01 -0800383 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700384
385 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
386 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
387 clock_.TimeInMilliseconds(), 250, false);
388 }
Peter Boströme23e7372015-10-08 11:44:14 +0200389 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
390 sequence_number, clock_.TimeInMilliseconds(), 250,
391 false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000392 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700393 EXPECT_EQ(1u, send_bucket_->QueueSizePackets());
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000394}
395
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +0100396TEST_F(PacedSenderTest, RepeatedRetransmissionsAllowed) {
philipel7dc719a2017-09-29 16:15:25 +0200397 // Send one packet, then two retransmissions of that packet.
398 for (size_t i = 0; i < 3; i++) {
399 constexpr uint32_t ssrc = 333;
400 constexpr uint16_t sequence_number = 444;
401 constexpr size_t bytes = 250;
402 bool is_retransmission = (i != 0); // Original followed by retransmissions.
403 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number,
404 clock_.TimeInMilliseconds(), bytes, is_retransmission);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000405 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000406 }
pbosa26ac922016-02-25 04:50:01 -0800407 send_bucket_->Process();
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000408}
409
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +0100410TEST_F(PacedSenderTest, CanQueuePacketsWithSameSequenceNumberOnDifferentSsrcs) {
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000411 uint32_t ssrc = 12345;
412 uint16_t sequence_number = 1234;
413
Yves Gerey665174f2018-06-19 15:03:05 +0200414 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number,
415 clock_.TimeInMilliseconds(), 250, false);
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000416
417 // Expect packet on second ssrc to be queued and sent as well.
Yves Gerey665174f2018-06-19 15:03:05 +0200418 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc + 1, sequence_number,
419 clock_.TimeInMilliseconds(), 250, false);
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000420
421 clock_.AdvanceTimeMilliseconds(1000);
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000422 send_bucket_->Process();
423}
424
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +0100425TEST_F(PacedSenderTest, Padding) {
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000426 uint32_t ssrc = 12345;
427 uint16_t sequence_number = 1234;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000428
Sebastian Jansson439f0bc2018-02-20 10:46:39 +0100429 send_bucket_->SetPacingRates(kTargetBitrateBps * kPaceMultiplier,
430 kTargetBitrateBps);
perkjec81bcd2016-05-11 06:01:13 -0700431
Danil Chapovalov74a369c2018-02-14 10:48:49 +0000432 // Due to the multiplicative factor we can send 5 packets during a send
433 // interval. (network capacity * multiplier / (8 bits per byte *
434 // (packet size * #send intervals per second)
435 const size_t packets_to_send_per_interval =
Sebastian Jansson439f0bc2018-02-20 10:46:39 +0100436 kTargetBitrateBps * kPaceMultiplier / (8 * 250 * 200);
perkjec81bcd2016-05-11 06:01:13 -0700437 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
438 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
439 clock_.TimeInMilliseconds(), 250, false);
440 }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000441 // No padding is expected since we have sent too much already.
philipela1ed0b32016-06-01 06:31:17 -0700442 EXPECT_CALL(callback_, TimeToSendPadding(_, _)).Times(0);
perkjec81bcd2016-05-11 06:01:13 -0700443 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
444 send_bucket_->Process();
445 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
446
447 // 5 milliseconds later should not send padding since we filled the buffers
448 // initially.
philipela1ed0b32016-06-01 06:31:17 -0700449 EXPECT_CALL(callback_, TimeToSendPadding(250, _)).Times(0);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000450 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000451 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000452 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800453 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000454
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000455 // 5 milliseconds later we have enough budget to send some padding.
philipela1ed0b32016-06-01 06:31:17 -0700456 EXPECT_CALL(callback_, TimeToSendPadding(250, _))
457 .Times(1)
458 .WillOnce(Return(250));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000459 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000460 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000461 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800462 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000463}
464
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +0100465TEST_F(PacedSenderTest, NoPaddingBeforeNormalPacket) {
Sebastian Jansson439f0bc2018-02-20 10:46:39 +0100466 send_bucket_->SetPacingRates(kTargetBitrateBps * kPaceMultiplier,
467 kTargetBitrateBps);
perkj71ee44c2016-06-15 00:47:53 -0700468
469 EXPECT_CALL(callback_, TimeToSendPadding(_, _)).Times(0);
470 send_bucket_->Process();
471 clock_.AdvanceTimeMilliseconds(send_bucket_->TimeUntilNextProcess());
472
473 send_bucket_->Process();
474 clock_.AdvanceTimeMilliseconds(send_bucket_->TimeUntilNextProcess());
475
476 uint32_t ssrc = 12345;
477 uint16_t sequence_number = 1234;
478 int64_t capture_time_ms = 56789;
479
480 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
481 capture_time_ms, 250, false);
482 EXPECT_CALL(callback_, TimeToSendPadding(250, _))
483 .Times(1)
484 .WillOnce(Return(250));
485 send_bucket_->Process();
486}
487
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +0100488TEST_F(PacedSenderTest, VerifyPaddingUpToBitrate) {
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000489 uint32_t ssrc = 12345;
490 uint16_t sequence_number = 1234;
491 int64_t capture_time_ms = 56789;
492 const int kTimeStep = 5;
493 const int64_t kBitrateWindow = 100;
Sebastian Jansson439f0bc2018-02-20 10:46:39 +0100494 send_bucket_->SetPacingRates(kTargetBitrateBps * kPaceMultiplier,
495 kTargetBitrateBps);
perkjec81bcd2016-05-11 06:01:13 -0700496
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000497 int64_t start_time = clock_.TimeInMilliseconds();
498 while (clock_.TimeInMilliseconds() - start_time < kBitrateWindow) {
Yves Gerey665174f2018-06-19 15:03:05 +0200499 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
500 capture_time_ms, 250, false);
philipela1ed0b32016-06-01 06:31:17 -0700501 EXPECT_CALL(callback_, TimeToSendPadding(250, _))
502 .Times(1)
503 .WillOnce(Return(250));
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000504 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700505 clock_.AdvanceTimeMilliseconds(kTimeStep);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000506 }
507}
508
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +0100509TEST_F(PacedSenderTest, VerifyAverageBitrateVaryingMediaPayload) {
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000510 uint32_t ssrc = 12345;
511 uint16_t sequence_number = 1234;
512 int64_t capture_time_ms = 56789;
513 const int kTimeStep = 5;
514 const int64_t kBitrateWindow = 10000;
515 PacedSenderPadding callback;
philipelc3b3f7a2017-03-29 01:23:13 -0700516 send_bucket_.reset(new PacedSender(&clock_, &callback, nullptr));
stefan@webrtc.orge9f0f592015-02-16 15:47:51 +0000517 send_bucket_->SetProbingEnabled(false);
Sebastian Jansson439f0bc2018-02-20 10:46:39 +0100518 send_bucket_->SetPacingRates(kTargetBitrateBps * kPaceMultiplier,
519 kTargetBitrateBps);
perkjec81bcd2016-05-11 06:01:13 -0700520
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000521 int64_t start_time = clock_.TimeInMilliseconds();
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000522 size_t media_bytes = 0;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000523 while (clock_.TimeInMilliseconds() - start_time < kBitrateWindow) {
jbauchd2a22962016-02-08 23:18:25 -0800524 int rand_value = rand(); // NOLINT (rand_r instead of rand)
525 size_t media_payload = rand_value % 100 + 200; // [200, 300] bytes.
Peter Boströme23e7372015-10-08 11:44:14 +0200526 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
527 sequence_number++, capture_time_ms,
528 media_payload, false);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000529 media_bytes += media_payload;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000530 clock_.AdvanceTimeMilliseconds(kTimeStep);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000531 send_bucket_->Process();
532 }
Danil Chapovalov74a369c2018-02-14 10:48:49 +0000533 EXPECT_NEAR(kTargetBitrateBps / 1000,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000534 static_cast<int>(8 * (media_bytes + callback.padding_sent()) /
perkjec81bcd2016-05-11 06:01:13 -0700535 kBitrateWindow),
536 1);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000537}
538
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +0100539TEST_F(PacedSenderTest, Priority) {
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000540 uint32_t ssrc_low_priority = 12345;
541 uint32_t ssrc = 12346;
542 uint16_t sequence_number = 1234;
543 int64_t capture_time_ms = 56789;
544 int64_t capture_time_ms_low_priority = 1234567;
545
Danil Chapovalov74a369c2018-02-14 10:48:49 +0000546 // Due to the multiplicative factor we can send 5 packets during a send
547 // interval. (network capacity * multiplier / (8 bits per byte *
548 // (packet size * #send intervals per second)
549 const size_t packets_to_send_per_interval =
Sebastian Jansson439f0bc2018-02-20 10:46:39 +0100550 kTargetBitrateBps * kPaceMultiplier / (8 * 250 * 200);
perkjec81bcd2016-05-11 06:01:13 -0700551 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
552 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
553 clock_.TimeInMilliseconds(), 250, false);
554 }
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000555 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700556 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000557
558 // Expect normal and low priority to be queued and high to pass through.
Peter Boströme23e7372015-10-08 11:44:14 +0200559 send_bucket_->InsertPacket(PacedSender::kLowPriority, ssrc_low_priority,
560 sequence_number++, capture_time_ms_low_priority,
561 250, false);
perkjec81bcd2016-05-11 06:01:13 -0700562
563 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
564 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
565 sequence_number++, capture_time_ms, 250, false);
566 }
Peter Boströme23e7372015-10-08 11:44:14 +0200567 send_bucket_->InsertPacket(PacedSender::kHighPriority, ssrc,
568 sequence_number++, capture_time_ms, 250, false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000569
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000570 // Expect all high and normal priority to be sent out first.
philipela1ed0b32016-06-01 06:31:17 -0700571 EXPECT_CALL(callback_, TimeToSendPadding(_, _)).Times(0);
philipel29dca2c2016-05-13 11:13:05 +0200572 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, _, capture_time_ms, false, _))
perkjec81bcd2016-05-11 06:01:13 -0700573 .Times(packets_to_send_per_interval + 1)
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000574 .WillRepeatedly(Return(true));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000575
576 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000577 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000578 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800579 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700580 EXPECT_EQ(1u, send_bucket_->QueueSizePackets());
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000581
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000582 EXPECT_CALL(callback_,
philipel29dca2c2016-05-13 11:13:05 +0200583 TimeToSendPacket(ssrc_low_priority, _,
584 capture_time_ms_low_priority, false, _))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000585 .Times(1)
586 .WillRepeatedly(Return(true));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000587
588 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000589 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000590 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800591 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000592}
593
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +0100594TEST_F(PacedSenderTest, RetransmissionPriority) {
tereliusf39f7d92016-07-20 03:36:19 -0700595 uint32_t ssrc = 12345;
596 uint16_t sequence_number = 1234;
597 int64_t capture_time_ms = 45678;
598 int64_t capture_time_ms_retransmission = 56789;
599
Danil Chapovalov74a369c2018-02-14 10:48:49 +0000600 // Due to the multiplicative factor we can send 5 packets during a send
601 // interval. (network capacity * multiplier / (8 bits per byte *
602 // (packet size * #send intervals per second)
603 const size_t packets_to_send_per_interval =
Sebastian Jansson439f0bc2018-02-20 10:46:39 +0100604 kTargetBitrateBps * kPaceMultiplier / (8 * 250 * 200);
tereliusf39f7d92016-07-20 03:36:19 -0700605 send_bucket_->Process();
606 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
607
608 // Alternate retransmissions and normal packets.
609 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
610 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
611 sequence_number++,
612 capture_time_ms_retransmission, 250, true);
613 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
614 sequence_number++, capture_time_ms, 250, false);
615 }
616 EXPECT_EQ(2 * packets_to_send_per_interval, send_bucket_->QueueSizePackets());
617
618 // Expect all retransmissions to be sent out first despite having a later
619 // capture time.
620 EXPECT_CALL(callback_, TimeToSendPadding(_, _)).Times(0);
621 EXPECT_CALL(callback_, TimeToSendPacket(_, _, _, false, _)).Times(0);
622 EXPECT_CALL(callback_, TimeToSendPacket(
623 ssrc, _, capture_time_ms_retransmission, true, _))
624 .Times(packets_to_send_per_interval)
625 .WillRepeatedly(Return(true));
626
627 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
628 clock_.AdvanceTimeMilliseconds(5);
629 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
630 send_bucket_->Process();
631 EXPECT_EQ(packets_to_send_per_interval, send_bucket_->QueueSizePackets());
632
633 // Expect the remaining (non-retransmission) packets to be sent.
634 EXPECT_CALL(callback_, TimeToSendPadding(_, _)).Times(0);
635 EXPECT_CALL(callback_, TimeToSendPacket(_, _, _, true, _)).Times(0);
636 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, _, capture_time_ms, false, _))
637 .Times(packets_to_send_per_interval)
638 .WillRepeatedly(Return(true));
639
640 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
641 clock_.AdvanceTimeMilliseconds(5);
642 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
643 send_bucket_->Process();
644
645 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
646}
647
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +0100648TEST_F(PacedSenderTest, HighPrioDoesntAffectBudget) {
Stefan Holmerc482eb32015-12-16 16:55:03 +0100649 uint32_t ssrc = 12346;
650 uint16_t sequence_number = 1234;
651 int64_t capture_time_ms = 56789;
652
653 // As high prio packets doesn't affect the budget, we should be able to send
654 // a high number of them at once.
655 for (int i = 0; i < 25; ++i) {
656 SendAndExpectPacket(PacedSender::kHighPriority, ssrc, sequence_number++,
657 capture_time_ms, 250, false);
658 }
659 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700660 // Low prio packets does affect the budget.
Danil Chapovalov74a369c2018-02-14 10:48:49 +0000661 // Due to the multiplicative factor we can send 5 packets during a send
662 // interval. (network capacity * multiplier / (8 bits per byte *
663 // (packet size * #send intervals per second)
664 const size_t packets_to_send_per_interval =
Sebastian Jansson439f0bc2018-02-20 10:46:39 +0100665 kTargetBitrateBps * kPaceMultiplier / (8 * 250 * 200);
perkjec81bcd2016-05-11 06:01:13 -0700666 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
Stefan Holmerc482eb32015-12-16 16:55:03 +0100667 SendAndExpectPacket(PacedSender::kLowPriority, ssrc, sequence_number++,
perkjec81bcd2016-05-11 06:01:13 -0700668 clock_.TimeInMilliseconds(), 250, false);
Stefan Holmerc482eb32015-12-16 16:55:03 +0100669 }
670 send_bucket_->InsertPacket(PacedSender::kLowPriority, ssrc, sequence_number,
671 capture_time_ms, 250, false);
672 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
673 clock_.AdvanceTimeMilliseconds(5);
674 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700675 EXPECT_EQ(1u, send_bucket_->QueueSizePackets());
philipel29dca2c2016-05-13 11:13:05 +0200676 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number++,
677 capture_time_ms, false, _))
perkjec81bcd2016-05-11 06:01:13 -0700678 .Times(1)
679 .WillRepeatedly(Return(true));
Stefan Holmerc482eb32015-12-16 16:55:03 +0100680 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
681 clock_.AdvanceTimeMilliseconds(5);
682 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700683 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
Stefan Holmerc482eb32015-12-16 16:55:03 +0100684}
685
Sebastian Jansson45d9c1d2018-03-09 12:48:01 +0100686TEST_F(PacedSenderTest, SendsOnlyPaddingWhenCongested) {
687 uint32_t ssrc = 202020;
688 uint16_t sequence_number = 1000;
689 int kPacketSize = 250;
690 int kCongestionWindow = kPacketSize * 10;
691
692 send_bucket_->UpdateOutstandingData(0);
693 send_bucket_->SetCongestionWindow(kCongestionWindow);
694 int sent_data = 0;
695 while (sent_data < kCongestionWindow) {
696 sent_data += kPacketSize;
697 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
698 clock_.TimeInMilliseconds(), kPacketSize, false);
699 clock_.AdvanceTimeMilliseconds(5);
700 send_bucket_->Process();
701 }
702 testing::Mock::VerifyAndClearExpectations(&callback_);
703 EXPECT_CALL(callback_, TimeToSendPacket(_, _, _, _, _)).Times(0);
704 EXPECT_CALL(callback_, TimeToSendPadding(_, _)).Times(0);
705
706 size_t blocked_packets = 0;
707 int64_t expected_time_until_padding = 500;
708 while (expected_time_until_padding > 5) {
709 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
710 sequence_number++, clock_.TimeInMilliseconds(),
711 kPacketSize, false);
712 blocked_packets++;
713 clock_.AdvanceTimeMilliseconds(5);
714 send_bucket_->Process();
715 expected_time_until_padding -= 5;
716 }
717 testing::Mock::VerifyAndClearExpectations(&callback_);
718 EXPECT_CALL(callback_, TimeToSendPadding(1, _)).Times(1);
719 clock_.AdvanceTimeMilliseconds(5);
720 send_bucket_->Process();
721 EXPECT_EQ(blocked_packets, send_bucket_->QueueSizePackets());
722}
723
Sebastian Janssonb544f6c2018-06-04 19:02:41 +0200724TEST_F(PacedSenderTest, DoesNotAllowOveruseAfterCongestion) {
725 uint32_t ssrc = 202020;
726 uint16_t seq_num = 1000;
727 RtpPacketSender::Priority prio = PacedSender::kNormalPriority;
728 int size = 1000;
729 auto now_ms = [this] { return clock_.TimeInMilliseconds(); };
730 EXPECT_CALL(callback_, TimeToSendPadding).Times(0);
731 // The pacing rate is low enough that the budget should not allow two packets
732 // to be sent in a row.
733 send_bucket_->SetPacingRates(400 * 8 * 1000 / 5, 0);
734 // The congestion window is small enough to only let one packet through.
735 send_bucket_->SetCongestionWindow(800);
736 send_bucket_->UpdateOutstandingData(0);
737 // Not yet budget limited or congested, packet is sent.
738 send_bucket_->InsertPacket(prio, ssrc, seq_num++, now_ms(), size, false);
739 EXPECT_CALL(callback_, TimeToSendPacket).WillOnce(Return(true));
740 clock_.AdvanceTimeMilliseconds(5);
741 send_bucket_->Process();
742 // Packet blocked due to congestion.
743 send_bucket_->InsertPacket(prio, ssrc, seq_num++, now_ms(), size, false);
744 EXPECT_CALL(callback_, TimeToSendPacket).Times(0);
745 clock_.AdvanceTimeMilliseconds(5);
746 send_bucket_->Process();
747 // Packet blocked due to congestion.
748 send_bucket_->InsertPacket(prio, ssrc, seq_num++, now_ms(), size, false);
749 EXPECT_CALL(callback_, TimeToSendPacket).Times(0);
750 clock_.AdvanceTimeMilliseconds(5);
751 send_bucket_->Process();
752 send_bucket_->UpdateOutstandingData(0);
753 // Congestion removed and budget has recovered, packet is sent.
754 send_bucket_->InsertPacket(prio, ssrc, seq_num++, now_ms(), size, false);
755 EXPECT_CALL(callback_, TimeToSendPacket).WillOnce(Return(true));
756 clock_.AdvanceTimeMilliseconds(5);
757 send_bucket_->Process();
758 send_bucket_->UpdateOutstandingData(0);
759 // Should be blocked due to budget limitation as congestion has be removed.
760 send_bucket_->InsertPacket(prio, ssrc, seq_num++, now_ms(), size, false);
761 EXPECT_CALL(callback_, TimeToSendPacket).Times(0);
762 clock_.AdvanceTimeMilliseconds(5);
763 send_bucket_->Process();
764}
765
Sebastian Jansson45d9c1d2018-03-09 12:48:01 +0100766TEST_F(PacedSenderTest, ResumesSendingWhenCongestionEnds) {
767 uint32_t ssrc = 202020;
768 uint16_t sequence_number = 1000;
769 int64_t kPacketSize = 250;
770 int64_t kCongestionCount = 10;
771 int64_t kCongestionWindow = kPacketSize * kCongestionCount;
772 int64_t kCongestionTimeMs = 1000;
773
774 send_bucket_->UpdateOutstandingData(0);
775 send_bucket_->SetCongestionWindow(kCongestionWindow);
776 int sent_data = 0;
777 while (sent_data < kCongestionWindow) {
778 sent_data += kPacketSize;
779 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
780 clock_.TimeInMilliseconds(), kPacketSize, false);
781 clock_.AdvanceTimeMilliseconds(5);
782 send_bucket_->Process();
783 }
784 testing::Mock::VerifyAndClearExpectations(&callback_);
785 EXPECT_CALL(callback_, TimeToSendPacket(_, _, _, _, _)).Times(0);
786 int unacked_packets = 0;
787 for (int duration = 0; duration < kCongestionTimeMs; duration += 5) {
788 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
789 sequence_number++, clock_.TimeInMilliseconds(),
790 kPacketSize, false);
791 unacked_packets++;
792 clock_.AdvanceTimeMilliseconds(5);
793 send_bucket_->Process();
794 }
795 testing::Mock::VerifyAndClearExpectations(&callback_);
796
797 // First mark half of the congested packets as cleared and make sure that just
798 // as many are sent
799 int ack_count = kCongestionCount / 2;
800 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, _, _, false, _))
801 .Times(ack_count)
802 .WillRepeatedly(Return(true));
803 send_bucket_->UpdateOutstandingData(kCongestionWindow -
804 kPacketSize * ack_count);
805
806 for (int duration = 0; duration < kCongestionTimeMs; duration += 5) {
807 clock_.AdvanceTimeMilliseconds(5);
808 send_bucket_->Process();
809 }
810 unacked_packets -= ack_count;
811 testing::Mock::VerifyAndClearExpectations(&callback_);
812
813 // Second make sure all packets are sent if sent packets are continuously
814 // marked as acked.
815 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, _, _, false, _))
816 .Times(unacked_packets)
817 .WillRepeatedly(Return(true));
818 for (int duration = 0; duration < kCongestionTimeMs; duration += 5) {
819 send_bucket_->UpdateOutstandingData(0);
820 clock_.AdvanceTimeMilliseconds(5);
821 send_bucket_->Process();
822 }
823}
824
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +0100825TEST_F(PacedSenderTest, Pause) {
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000826 uint32_t ssrc_low_priority = 12345;
827 uint32_t ssrc = 12346;
terelius8b70faf2016-08-01 09:47:31 -0700828 uint32_t ssrc_high_priority = 12347;
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000829 uint16_t sequence_number = 1234;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000830 int64_t capture_time_ms = clock_.TimeInMilliseconds();
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000831
832 EXPECT_EQ(0, send_bucket_->QueueInMs());
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000833
Danil Chapovalov74a369c2018-02-14 10:48:49 +0000834 // Due to the multiplicative factor we can send 5 packets during a send
835 // interval. (network capacity * multiplier / (8 bits per byte *
836 // (packet size * #send intervals per second)
837 const size_t packets_to_send_per_interval =
Sebastian Jansson439f0bc2018-02-20 10:46:39 +0100838 kTargetBitrateBps * kPaceMultiplier / (8 * 250 * 200);
perkjec81bcd2016-05-11 06:01:13 -0700839 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
840 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
841 clock_.TimeInMilliseconds(), 250, false);
842 }
843
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000844 send_bucket_->Process();
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000845
846 send_bucket_->Pause();
847
terelius8b70faf2016-08-01 09:47:31 -0700848 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
849 send_bucket_->InsertPacket(PacedSender::kLowPriority, ssrc_low_priority,
850 sequence_number++, capture_time_ms, 250, false);
851 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
852 sequence_number++, capture_time_ms, 250, false);
853 send_bucket_->InsertPacket(PacedSender::kHighPriority, ssrc_high_priority,
854 sequence_number++, capture_time_ms, 250, false);
855 }
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000856 clock_.AdvanceTimeMilliseconds(10000);
857 int64_t second_capture_time_ms = clock_.TimeInMilliseconds();
terelius8b70faf2016-08-01 09:47:31 -0700858 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
859 send_bucket_->InsertPacket(PacedSender::kLowPriority, ssrc_low_priority,
860 sequence_number++, second_capture_time_ms, 250,
861 false);
862 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
863 sequence_number++, second_capture_time_ms, 250,
864 false);
865 send_bucket_->InsertPacket(PacedSender::kHighPriority, ssrc_high_priority,
866 sequence_number++, second_capture_time_ms, 250,
867 false);
868 }
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000869
870 // Expect everything to be queued.
terelius8b70faf2016-08-01 09:47:31 -0700871 EXPECT_EQ(second_capture_time_ms - capture_time_ms,
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000872 send_bucket_->QueueInMs());
873
stefan9e117c5e12017-08-16 08:16:25 -0700874 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
875 EXPECT_CALL(callback_, TimeToSendPadding(1, _)).Times(1);
876 send_bucket_->Process();
877
878 int64_t expected_time_until_send = 500;
Sebastian Janssona1630f82018-02-21 13:39:26 +0100879 EXPECT_CALL(callback_, TimeToSendPadding(_, _)).Times(0);
880 while (expected_time_until_send >= 5) {
881 send_bucket_->Process();
stefan9e117c5e12017-08-16 08:16:25 -0700882 clock_.AdvanceTimeMilliseconds(5);
883 expected_time_until_send -= 5;
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000884 }
Sebastian Janssona1630f82018-02-21 13:39:26 +0100885 testing::Mock::VerifyAndClearExpectations(&callback_);
886 EXPECT_CALL(callback_, TimeToSendPadding(1, _)).Times(1);
887 clock_.AdvanceTimeMilliseconds(5);
888 send_bucket_->Process();
889 testing::Mock::VerifyAndClearExpectations(&callback_);
terelius8b70faf2016-08-01 09:47:31 -0700890
stefan099110c2017-02-01 03:57:42 -0800891 // Expect high prio packets to come out first followed by normal
892 // prio packets and low prio packets (all in capture order).
terelius8b70faf2016-08-01 09:47:31 -0700893 {
894 ::testing::InSequence sequence;
stefan099110c2017-02-01 03:57:42 -0800895 EXPECT_CALL(callback_,
896 TimeToSendPacket(ssrc_high_priority, _, capture_time_ms, _, _))
897 .Times(packets_to_send_per_interval)
898 .WillRepeatedly(Return(true));
899 EXPECT_CALL(callback_, TimeToSendPacket(ssrc_high_priority, _,
900 second_capture_time_ms, _, _))
901 .Times(packets_to_send_per_interval)
902 .WillRepeatedly(Return(true));
903
terelius8b70faf2016-08-01 09:47:31 -0700904 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
905 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, _, capture_time_ms, _, _))
906 .Times(1)
907 .WillRepeatedly(Return(true));
908 }
909 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
910 EXPECT_CALL(callback_,
911 TimeToSendPacket(ssrc, _, second_capture_time_ms, _, _))
912 .Times(1)
913 .WillRepeatedly(Return(true));
914 }
915 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
916 EXPECT_CALL(callback_,
917 TimeToSendPacket(ssrc_low_priority, _, capture_time_ms, _, _))
918 .Times(1)
919 .WillRepeatedly(Return(true));
920 }
921 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
922 EXPECT_CALL(callback_, TimeToSendPacket(ssrc_low_priority, _,
923 second_capture_time_ms, _, _))
924 .Times(1)
925 .WillRepeatedly(Return(true));
926 }
927 }
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000928 send_bucket_->Resume();
929
Sebastian Janssona1630f82018-02-21 13:39:26 +0100930 // The pacer was resumed directly after the previous process call finished. It
931 // will therefore wait 5 ms until next process.
932 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
933 clock_.AdvanceTimeMilliseconds(5);
934
terelius8b70faf2016-08-01 09:47:31 -0700935 for (size_t i = 0; i < 4; i++) {
stefan64136af2017-08-14 08:03:17 -0700936 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
937 send_bucket_->Process();
stefan9e117c5e12017-08-16 08:16:25 -0700938 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
939 clock_.AdvanceTimeMilliseconds(5);
terelius8b70faf2016-08-01 09:47:31 -0700940 }
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000941
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000942 EXPECT_EQ(0, send_bucket_->QueueInMs());
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000943}
944
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +0100945TEST_F(PacedSenderTest, ResendPacket) {
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000946 uint32_t ssrc = 12346;
947 uint16_t sequence_number = 1234;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000948 int64_t capture_time_ms = clock_.TimeInMilliseconds();
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000949 EXPECT_EQ(0, send_bucket_->QueueInMs());
950
Peter Boströme23e7372015-10-08 11:44:14 +0200951 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
952 sequence_number, capture_time_ms, 250, false);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000953 clock_.AdvanceTimeMilliseconds(1);
Peter Boströme23e7372015-10-08 11:44:14 +0200954 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
955 sequence_number + 1, capture_time_ms + 1, 250,
956 false);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000957 clock_.AdvanceTimeMilliseconds(9999);
958 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms,
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000959 send_bucket_->QueueInMs());
960 // Fails to send first packet so only one call.
philipel29dca2c2016-05-13 11:13:05 +0200961 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number,
962 capture_time_ms, false, _))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000963 .Times(1)
964 .WillOnce(Return(false));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000965 clock_.AdvanceTimeMilliseconds(10000);
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000966 send_bucket_->Process();
967
968 // Queue remains unchanged.
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000969 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms,
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000970 send_bucket_->QueueInMs());
971
972 // Fails to send second packet.
philipel29dca2c2016-05-13 11:13:05 +0200973 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number,
974 capture_time_ms, false, _))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000975 .Times(1)
976 .WillOnce(Return(true));
philipel29dca2c2016-05-13 11:13:05 +0200977 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number + 1,
978 capture_time_ms + 1, false, _))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000979 .Times(1)
980 .WillOnce(Return(false));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000981 clock_.AdvanceTimeMilliseconds(10000);
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000982 send_bucket_->Process();
983
984 // Queue is reduced by 1 packet.
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000985 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms - 1,
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000986 send_bucket_->QueueInMs());
987
988 // Send second packet and queue becomes empty.
philipel29dca2c2016-05-13 11:13:05 +0200989 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number + 1,
990 capture_time_ms + 1, false, _))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000991 .Times(1)
992 .WillOnce(Return(true));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000993 clock_.AdvanceTimeMilliseconds(10000);
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000994 send_bucket_->Process();
995 EXPECT_EQ(0, send_bucket_->QueueInMs());
996}
997
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +0100998TEST_F(PacedSenderTest, ExpectedQueueTimeMs) {
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000999 uint32_t ssrc = 12346;
1000 uint16_t sequence_number = 1234;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001001 const size_t kNumPackets = 60;
1002 const size_t kPacketSize = 1200;
Sebastian Jansson439f0bc2018-02-20 10:46:39 +01001003 const int32_t kMaxBitrate = kPaceMultiplier * 30000;
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +00001004 EXPECT_EQ(0, send_bucket_->ExpectedQueueTimeMs());
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +00001005
Sebastian Jansson439f0bc2018-02-20 10:46:39 +01001006 send_bucket_->SetPacingRates(30000 * kPaceMultiplier, 0);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001007 for (size_t i = 0; i < kNumPackets; ++i) {
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +00001008 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
1009 clock_.TimeInMilliseconds(), kPacketSize, false);
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +00001010 }
1011
perkjec81bcd2016-05-11 06:01:13 -07001012 // Queue in ms = 1000 * (bytes in queue) *8 / (bits per second)
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001013 int64_t queue_in_ms =
perkjec81bcd2016-05-11 06:01:13 -07001014 static_cast<int64_t>(1000 * kNumPackets * kPacketSize * 8 / kMaxBitrate);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +00001015 EXPECT_EQ(queue_in_ms, send_bucket_->ExpectedQueueTimeMs());
stefan@webrtc.org168f23f2014-07-11 13:44:02 +00001016
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +00001017 int64_t time_start = clock_.TimeInMilliseconds();
1018 while (send_bucket_->QueueSizePackets() > 0) {
1019 int time_until_process = send_bucket_->TimeUntilNextProcess();
1020 if (time_until_process <= 0) {
1021 send_bucket_->Process();
1022 } else {
1023 clock_.AdvanceTimeMilliseconds(time_until_process);
1024 }
1025 }
1026 int64_t duration = clock_.TimeInMilliseconds() - time_start;
1027
1028 EXPECT_EQ(0, send_bucket_->ExpectedQueueTimeMs());
1029
sprang0a43fef2015-11-20 09:00:37 -08001030 // Allow for aliasing, duration should be within one pack of max time limit.
1031 EXPECT_NEAR(duration, PacedSender::kMaxQueueLengthMs,
perkjec81bcd2016-05-11 06:01:13 -07001032 static_cast<int64_t>(1000 * kPacketSize * 8 / kMaxBitrate));
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +00001033}
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +00001034
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +01001035TEST_F(PacedSenderTest, QueueTimeGrowsOverTime) {
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +00001036 uint32_t ssrc = 12346;
1037 uint16_t sequence_number = 1234;
1038 EXPECT_EQ(0, send_bucket_->QueueInMs());
1039
Sebastian Jansson439f0bc2018-02-20 10:46:39 +01001040 send_bucket_->SetPacingRates(30000 * kPaceMultiplier, 0);
Yves Gerey665174f2018-06-19 15:03:05 +02001041 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number,
1042 clock_.TimeInMilliseconds(), 1200, false);
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +00001043
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +00001044 clock_.AdvanceTimeMilliseconds(500);
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +00001045 EXPECT_EQ(500, send_bucket_->QueueInMs());
1046 send_bucket_->Process();
1047 EXPECT_EQ(0, send_bucket_->QueueInMs());
1048}
stefan@webrtc.org82462aa2014-10-23 11:57:05 +00001049
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +01001050TEST_F(PacedSenderTest, ProbingWithInsertedPackets) {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001051 const size_t kPacketSize = 1200;
perkjec81bcd2016-05-11 06:01:13 -07001052 const int kInitialBitrateBps = 300000;
stefan@webrtc.org82462aa2014-10-23 11:57:05 +00001053 uint32_t ssrc = 12346;
1054 uint16_t sequence_number = 1234;
perkjec81bcd2016-05-11 06:01:13 -07001055
isheriffcc5903e2016-10-04 08:29:38 -07001056 PacedSenderProbing packet_sender;
philipelc3b3f7a2017-03-29 01:23:13 -07001057 send_bucket_.reset(new PacedSender(&clock_, &packet_sender, nullptr));
philipelfd58b612017-01-04 07:05:25 -08001058 send_bucket_->CreateProbeCluster(kFirstClusterBps);
1059 send_bucket_->CreateProbeCluster(kSecondClusterBps);
Sebastian Jansson439f0bc2018-02-20 10:46:39 +01001060 send_bucket_->SetPacingRates(kInitialBitrateBps * kPaceMultiplier, 0);
stefan@webrtc.orge9f0f592015-02-16 15:47:51 +00001061
philipelfd58b612017-01-04 07:05:25 -08001062 for (int i = 0; i < 10; ++i) {
Peter Boströme23e7372015-10-08 11:44:14 +02001063 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
1064 sequence_number++, clock_.TimeInMilliseconds(),
1065 kPacketSize, false);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +00001066 }
perkjec81bcd2016-05-11 06:01:13 -07001067
isheriffcc5903e2016-10-04 08:29:38 -07001068 int64_t start = clock_.TimeInMilliseconds();
philipelfd58b612017-01-04 07:05:25 -08001069 while (packet_sender.packets_sent() < 5) {
stefan@webrtc.org82462aa2014-10-23 11:57:05 +00001070 int time_until_process = send_bucket_->TimeUntilNextProcess();
isheriffcc5903e2016-10-04 08:29:38 -07001071 clock_.AdvanceTimeMilliseconds(time_until_process);
1072 send_bucket_->Process();
stefan@webrtc.org82462aa2014-10-23 11:57:05 +00001073 }
isheriffcc5903e2016-10-04 08:29:38 -07001074 int packets_sent = packet_sender.packets_sent();
1075 // Validate first cluster bitrate. Note that we have to account for number
1076 // of intervals and hence (packets_sent - 1) on the first cluster.
1077 EXPECT_NEAR((packets_sent - 1) * kPacketSize * 8000 /
1078 (clock_.TimeInMilliseconds() - start),
1079 kFirstClusterBps, kBitrateProbingError);
1080 EXPECT_EQ(0, packet_sender.padding_sent());
1081
sergeyu6dbbd892017-01-17 15:07:59 -08001082 clock_.AdvanceTimeMilliseconds(send_bucket_->TimeUntilNextProcess());
isheriffcc5903e2016-10-04 08:29:38 -07001083 start = clock_.TimeInMilliseconds();
philipelfd58b612017-01-04 07:05:25 -08001084 while (packet_sender.packets_sent() < 10) {
isheriffcc5903e2016-10-04 08:29:38 -07001085 int time_until_process = send_bucket_->TimeUntilNextProcess();
1086 clock_.AdvanceTimeMilliseconds(time_until_process);
1087 send_bucket_->Process();
1088 }
1089 packets_sent = packet_sender.packets_sent() - packets_sent;
1090 // Validate second cluster bitrate.
sergeyu6dbbd892017-01-17 15:07:59 -08001091 EXPECT_NEAR((packets_sent - 1) * kPacketSize * 8000 /
1092 (clock_.TimeInMilliseconds() - start),
1093 kSecondClusterBps, kBitrateProbingError);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +00001094}
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +00001095
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +01001096TEST_F(PacedSenderTest, ProbingWithPaddingSupport) {
Stefan Holmer01b48882015-05-05 10:21:24 +02001097 const size_t kPacketSize = 1200;
perkjec81bcd2016-05-11 06:01:13 -07001098 const int kInitialBitrateBps = 300000;
Stefan Holmer01b48882015-05-05 10:21:24 +02001099 uint32_t ssrc = 12346;
1100 uint16_t sequence_number = 1234;
isheriffcc5903e2016-10-04 08:29:38 -07001101
1102 PacedSenderProbing packet_sender;
philipelc3b3f7a2017-03-29 01:23:13 -07001103 send_bucket_.reset(new PacedSender(&clock_, &packet_sender, nullptr));
philipelfd58b612017-01-04 07:05:25 -08001104 send_bucket_->CreateProbeCluster(kFirstClusterBps);
Sebastian Jansson439f0bc2018-02-20 10:46:39 +01001105 send_bucket_->SetPacingRates(kInitialBitrateBps * kPaceMultiplier, 0);
Stefan Holmer01b48882015-05-05 10:21:24 +02001106
philipelfd58b612017-01-04 07:05:25 -08001107 for (int i = 0; i < 3; ++i) {
Peter Boströme23e7372015-10-08 11:44:14 +02001108 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
1109 sequence_number++, clock_.TimeInMilliseconds(),
1110 kPacketSize, false);
Stefan Holmer01b48882015-05-05 10:21:24 +02001111 }
Stefan Holmer01b48882015-05-05 10:21:24 +02001112
isheriffcc5903e2016-10-04 08:29:38 -07001113 int64_t start = clock_.TimeInMilliseconds();
1114 int process_count = 0;
philipelfd58b612017-01-04 07:05:25 -08001115 while (process_count < 5) {
isheriffcc5903e2016-10-04 08:29:38 -07001116 int time_until_process = send_bucket_->TimeUntilNextProcess();
1117 clock_.AdvanceTimeMilliseconds(time_until_process);
1118 send_bucket_->Process();
1119 ++process_count;
1120 }
1121 int packets_sent = packet_sender.packets_sent();
1122 int padding_sent = packet_sender.padding_sent();
1123 EXPECT_GT(packets_sent, 0);
1124 EXPECT_GT(padding_sent, 0);
1125 // Note that the number of intervals here for kPacketSize is
1126 // packets_sent due to padding in the same cluster.
1127 EXPECT_NEAR((packets_sent * kPacketSize * 8000 + padding_sent) /
1128 (clock_.TimeInMilliseconds() - start),
1129 kFirstClusterBps, kBitrateProbingError);
Stefan Holmer01b48882015-05-05 10:21:24 +02001130}
1131
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +01001132TEST_F(PacedSenderTest, PaddingOveruse) {
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +00001133 uint32_t ssrc = 12346;
1134 uint16_t sequence_number = 1234;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001135 const size_t kPacketSize = 1200;
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +00001136
perkjec81bcd2016-05-11 06:01:13 -07001137 send_bucket_->Process();
Sebastian Jansson439f0bc2018-02-20 10:46:39 +01001138 send_bucket_->SetPacingRates(60000 * kPaceMultiplier, 0);
perkjec81bcd2016-05-11 06:01:13 -07001139
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +00001140 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
1141 clock_.TimeInMilliseconds(), kPacketSize, false);
1142 send_bucket_->Process();
1143
1144 // Add 30kbit padding. When increasing budget, media budget will increase from
perkjec81bcd2016-05-11 06:01:13 -07001145 // negative (overuse) while padding budget will increase from 0.
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +00001146 clock_.AdvanceTimeMilliseconds(5);
Sebastian Jansson439f0bc2018-02-20 10:46:39 +01001147 send_bucket_->SetPacingRates(60000 * kPaceMultiplier, 30000);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +00001148
perkjec81bcd2016-05-11 06:01:13 -07001149 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
1150 clock_.TimeInMilliseconds(), kPacketSize, false);
1151 EXPECT_LT(5u, send_bucket_->ExpectedQueueTimeMs());
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +00001152 // Don't send padding if queue is non-empty, even if padding budget > 0.
philipela1ed0b32016-06-01 06:31:17 -07001153 EXPECT_CALL(callback_, TimeToSendPadding(_, _)).Times(0);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +00001154 send_bucket_->Process();
1155}
1156
Niels Möllerd6314d92017-10-23 09:08:22 +02001157// TODO(philipel): Move to PacketQueue2 unittests.
1158#if 0
Erik Språngad113e52015-11-26 16:26:12 +01001159TEST_F(PacedSenderTest, AverageQueueTime) {
1160 uint32_t ssrc = 12346;
1161 uint16_t sequence_number = 1234;
1162 const size_t kPacketSize = 1200;
1163 const int kBitrateBps = 10 * kPacketSize * 8; // 10 packets per second.
Erik Språngad113e52015-11-26 16:26:12 +01001164
Sebastian Jansson439f0bc2018-02-20 10:46:39 +01001165 send_bucket_->SetPacingRates(kBitrateBps * kPaceMultiplier, 0);
Erik Språngad113e52015-11-26 16:26:12 +01001166
1167 EXPECT_EQ(0, send_bucket_->AverageQueueTimeMs());
1168
1169 int64_t first_capture_time = clock_.TimeInMilliseconds();
Stefan Holmerc482eb32015-12-16 16:55:03 +01001170 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
1171 sequence_number, first_capture_time, kPacketSize,
1172 false);
Erik Språngad113e52015-11-26 16:26:12 +01001173 clock_.AdvanceTimeMilliseconds(10);
Stefan Holmerc482eb32015-12-16 16:55:03 +01001174 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
Erik Språngad113e52015-11-26 16:26:12 +01001175 sequence_number + 1, clock_.TimeInMilliseconds(),
1176 kPacketSize, false);
1177 clock_.AdvanceTimeMilliseconds(10);
1178
1179 EXPECT_EQ((20 + 10) / 2, send_bucket_->AverageQueueTimeMs());
1180
1181 // Only first packet (queued for 20ms) should be removed, leave the second
1182 // packet (queued for 10ms) alone in the queue.
1183 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number,
philipel29dca2c2016-05-13 11:13:05 +02001184 first_capture_time, false, _))
Erik Språngad113e52015-11-26 16:26:12 +01001185 .Times(1)
1186 .WillRepeatedly(Return(true));
1187 send_bucket_->Process();
1188
1189 EXPECT_EQ(10, send_bucket_->AverageQueueTimeMs());
1190
1191 clock_.AdvanceTimeMilliseconds(10);
1192 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number + 1,
philipel29dca2c2016-05-13 11:13:05 +02001193 first_capture_time + 10, false, _))
Erik Språngad113e52015-11-26 16:26:12 +01001194 .Times(1)
1195 .WillRepeatedly(Return(true));
1196 for (int i = 0; i < 3; ++i) {
1197 clock_.AdvanceTimeMilliseconds(30); // Max delta.
1198 send_bucket_->Process();
1199 }
1200
1201 EXPECT_EQ(0, send_bucket_->AverageQueueTimeMs());
1202}
Niels Möllerd6314d92017-10-23 09:08:22 +02001203#endif
Erik Språngad113e52015-11-26 16:26:12 +01001204
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +01001205TEST_F(PacedSenderTest, ProbeClusterId) {
philipel29dca2c2016-05-13 11:13:05 +02001206 uint32_t ssrc = 12346;
1207 uint16_t sequence_number = 1234;
1208 const size_t kPacketSize = 1200;
1209
Sebastian Jansson439f0bc2018-02-20 10:46:39 +01001210 send_bucket_->SetPacingRates(kTargetBitrateBps * kPaceMultiplier,
1211 kTargetBitrateBps);
philipel29dca2c2016-05-13 11:13:05 +02001212 send_bucket_->SetProbingEnabled(true);
philipelfd58b612017-01-04 07:05:25 -08001213 for (int i = 0; i < 10; ++i) {
philipel29dca2c2016-05-13 11:13:05 +02001214 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
1215 sequence_number + i, clock_.TimeInMilliseconds(),
1216 kPacketSize, false);
1217 }
1218
1219 // First probing cluster.
philipelc7bf32a2017-02-17 03:59:43 -08001220 EXPECT_CALL(callback_,
1221 TimeToSendPacket(_, _, _, _,
1222 Field(&PacedPacketInfo::probe_cluster_id, 0)))
philipelfd58b612017-01-04 07:05:25 -08001223 .Times(5)
philipel29dca2c2016-05-13 11:13:05 +02001224 .WillRepeatedly(Return(true));
philipelfd58b612017-01-04 07:05:25 -08001225 for (int i = 0; i < 5; ++i) {
philipel1a93cde2016-06-03 01:41:45 -07001226 clock_.AdvanceTimeMilliseconds(20);
philipel29dca2c2016-05-13 11:13:05 +02001227 send_bucket_->Process();
philipel1a93cde2016-06-03 01:41:45 -07001228 }
philipel29dca2c2016-05-13 11:13:05 +02001229
1230 // Second probing cluster.
philipelc7bf32a2017-02-17 03:59:43 -08001231 EXPECT_CALL(callback_,
1232 TimeToSendPacket(_, _, _, _,
1233 Field(&PacedPacketInfo::probe_cluster_id, 1)))
philipel29dca2c2016-05-13 11:13:05 +02001234 .Times(5)
1235 .WillRepeatedly(Return(true));
philipel1a93cde2016-06-03 01:41:45 -07001236 for (int i = 0; i < 5; ++i) {
1237 clock_.AdvanceTimeMilliseconds(20);
philipel29dca2c2016-05-13 11:13:05 +02001238 send_bucket_->Process();
philipel1a93cde2016-06-03 01:41:45 -07001239 }
philipel29dca2c2016-05-13 11:13:05 +02001240
philipelc7bf32a2017-02-17 03:59:43 -08001241 // Needed for the Field comparer below.
1242 const int kNotAProbe = PacedPacketInfo::kNotAProbe;
philipel29dca2c2016-05-13 11:13:05 +02001243 // No more probing packets.
philipelc7bf32a2017-02-17 03:59:43 -08001244 EXPECT_CALL(callback_,
1245 TimeToSendPadding(
1246 _, Field(&PacedPacketInfo::probe_cluster_id, kNotAProbe)))
1247 .Times(1)
1248 .WillRepeatedly(Return(500));
philipel29dca2c2016-05-13 11:13:05 +02001249 send_bucket_->Process();
1250}
1251
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +01001252TEST_F(PacedSenderTest, AvoidBusyLoopOnSendFailure) {
philipelb61927c2017-02-28 07:05:23 -08001253 uint32_t ssrc = 12346;
1254 uint16_t sequence_number = 1234;
1255 const size_t kPacketSize = kFirstClusterBps / (8000 / 10);
1256
Sebastian Jansson439f0bc2018-02-20 10:46:39 +01001257 send_bucket_->SetPacingRates(kTargetBitrateBps * kPaceMultiplier,
1258 kTargetBitrateBps);
philipelb61927c2017-02-28 07:05:23 -08001259 send_bucket_->SetProbingEnabled(true);
1260 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
1261 sequence_number, clock_.TimeInMilliseconds(),
1262 kPacketSize, false);
1263
1264 EXPECT_CALL(callback_, TimeToSendPacket(_, _, _, _, _))
1265 .WillOnce(Return(true));
1266 send_bucket_->Process();
1267 EXPECT_EQ(10, send_bucket_->TimeUntilNextProcess());
1268 clock_.AdvanceTimeMilliseconds(9);
1269
1270 EXPECT_CALL(callback_, TimeToSendPadding(_, _))
1271 .Times(2)
1272 .WillRepeatedly(Return(0));
1273 send_bucket_->Process();
1274 EXPECT_EQ(1, send_bucket_->TimeUntilNextProcess());
1275 clock_.AdvanceTimeMilliseconds(1);
1276 send_bucket_->Process();
1277 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
1278}
1279
Niels Möllerd6314d92017-10-23 09:08:22 +02001280// TODO(philipel): Move to PacketQueue2 unittests.
1281#if 0
sprangddcfb9f2017-08-16 05:38:49 -07001282TEST_F(PacedSenderTest, QueueTimeWithPause) {
1283 const size_t kPacketSize = 1200;
1284 const uint32_t kSsrc = 12346;
1285 uint16_t sequence_number = 1234;
1286
1287 send_bucket_->InsertPacket(PacedSender::kNormalPriority, kSsrc,
1288 sequence_number++, clock_.TimeInMilliseconds(),
1289 kPacketSize, false);
1290 send_bucket_->InsertPacket(PacedSender::kNormalPriority, kSsrc,
1291 sequence_number++, clock_.TimeInMilliseconds(),
1292 kPacketSize, false);
1293
1294 clock_.AdvanceTimeMilliseconds(100);
1295 EXPECT_EQ(100, send_bucket_->AverageQueueTimeMs());
1296
1297 send_bucket_->Pause();
1298 EXPECT_EQ(100, send_bucket_->AverageQueueTimeMs());
1299
1300 // In paused state, queue time should not increase.
1301 clock_.AdvanceTimeMilliseconds(100);
1302 EXPECT_EQ(100, send_bucket_->AverageQueueTimeMs());
1303
1304 send_bucket_->Resume();
1305 EXPECT_EQ(100, send_bucket_->AverageQueueTimeMs());
1306
1307 clock_.AdvanceTimeMilliseconds(100);
1308 EXPECT_EQ(200, send_bucket_->AverageQueueTimeMs());
1309}
1310
Ilya Nikolaevskiy94065692018-03-02 12:32:05 +01001311TEST_F(PacedSenderTest, QueueTimePausedDuringPush) {
sprangddcfb9f2017-08-16 05:38:49 -07001312 const size_t kPacketSize = 1200;
1313 const uint32_t kSsrc = 12346;
1314 uint16_t sequence_number = 1234;
1315
1316 send_bucket_->InsertPacket(PacedSender::kNormalPriority, kSsrc,
1317 sequence_number++, clock_.TimeInMilliseconds(),
1318 kPacketSize, false);
1319 clock_.AdvanceTimeMilliseconds(100);
1320 send_bucket_->Pause();
1321 clock_.AdvanceTimeMilliseconds(100);
1322 EXPECT_EQ(100, send_bucket_->AverageQueueTimeMs());
1323
1324 // Add a new packet during paused phase.
1325 send_bucket_->InsertPacket(PacedSender::kNormalPriority, kSsrc,
1326 sequence_number++, clock_.TimeInMilliseconds(),
1327 kPacketSize, false);
1328 // From a queue time perspective, packet inserted during pause will have zero
1329 // queue time. Average queue time will then be (0 + 100) / 2 = 50.
1330 EXPECT_EQ(50, send_bucket_->AverageQueueTimeMs());
1331
1332 clock_.AdvanceTimeMilliseconds(100);
1333 EXPECT_EQ(50, send_bucket_->AverageQueueTimeMs());
1334
1335 send_bucket_->Resume();
1336 EXPECT_EQ(50, send_bucket_->AverageQueueTimeMs());
1337
1338 clock_.AdvanceTimeMilliseconds(100);
1339 EXPECT_EQ(150, send_bucket_->AverageQueueTimeMs());
1340}
Niels Möllerd6314d92017-10-23 09:08:22 +02001341#endif
sprangddcfb9f2017-08-16 05:38:49 -07001342
1343// TODO(sprang): Extract PacketQueue from PacedSender so that we can test
1344// removing elements while paused. (This is possible, but only because of semi-
1345// racy condition so can't easily be tested).
1346
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +00001347} // namespace test
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +00001348} // namespace webrtc