blob: f40dba3e2bdcd7cefa9ff9388f210f1eba6161c4 [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>
12
pbos@webrtc.orgdb6e3f82013-07-11 09:50:05 +000013#include "testing/gmock/include/gmock/gmock.h"
14#include "testing/gtest/include/gtest/gtest.h"
Henrik Kjellander0b9e29c2015-11-16 11:12:24 +010015#include "webrtc/modules/pacing/paced_sender.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010016#include "webrtc/system_wrappers/include/clock.h"
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000017
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +000018using testing::_;
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000019using testing::Return;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000020
21namespace webrtc {
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +000022namespace test {
23
24static const int kTargetBitrate = 800;
pwestin@webrtc.org52b4e882013-05-02 19:02:17 +000025static const float kPaceMultiplier = 1.5f;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000026
27class MockPacedSenderCallback : public PacedSender::Callback {
28 public:
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +000029 MOCK_METHOD4(TimeToSendPacket,
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000030 bool(uint32_t ssrc,
31 uint16_t sequence_number,
32 int64_t capture_time_ms,
33 bool retransmission));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000034 MOCK_METHOD1(TimeToSendPadding,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000035 size_t(size_t bytes));
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000036};
37
38class PacedSenderPadding : public PacedSender::Callback {
39 public:
40 PacedSenderPadding() : padding_sent_(0) {}
41
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000042 bool TimeToSendPacket(uint32_t ssrc,
43 uint16_t sequence_number,
44 int64_t capture_time_ms,
45 bool retransmission) {
hclam@chromium.org2e402ce2013-06-20 20:18:31 +000046 return true;
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000047 }
48
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000049 size_t TimeToSendPadding(size_t bytes) {
50 const size_t kPaddingPacketSize = 224;
51 size_t num_packets = (bytes + kPaddingPacketSize - 1) / kPaddingPacketSize;
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000052 padding_sent_ += kPaddingPacketSize * num_packets;
53 return kPaddingPacketSize * num_packets;
54 }
55
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000056 size_t padding_sent() { return padding_sent_; }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000057
58 private:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000059 size_t padding_sent_;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000060};
61
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000062class PacedSenderProbing : public PacedSender::Callback {
63 public:
64 PacedSenderProbing(const std::list<int>& expected_deltas, Clock* clock)
65 : prev_packet_time_ms_(-1),
66 expected_deltas_(expected_deltas),
67 packets_sent_(0),
68 clock_(clock) {}
69
70 bool TimeToSendPacket(uint32_t ssrc,
71 uint16_t sequence_number,
72 int64_t capture_time_ms,
73 bool retransmission) {
Stefan Holmer01b48882015-05-05 10:21:24 +020074 ExpectAndCountPacket();
75 return true;
76 }
77
78 size_t TimeToSendPadding(size_t bytes) {
79 ExpectAndCountPacket();
80 return bytes;
81 }
82
83 void ExpectAndCountPacket() {
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000084 ++packets_sent_;
85 EXPECT_FALSE(expected_deltas_.empty());
86 if (expected_deltas_.empty())
Stefan Holmer01b48882015-05-05 10:21:24 +020087 return;
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000088 int64_t now_ms = clock_->TimeInMilliseconds();
89 if (prev_packet_time_ms_ >= 0) {
90 EXPECT_EQ(expected_deltas_.front(), now_ms - prev_packet_time_ms_);
91 expected_deltas_.pop_front();
92 }
93 prev_packet_time_ms_ = now_ms;
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000094 }
95
96 int packets_sent() const { return packets_sent_; }
97
98 private:
99 int64_t prev_packet_time_ms_;
100 std::list<int> expected_deltas_;
101 int packets_sent_;
102 Clock* clock_;
103};
104
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000105class PacedSenderTest : public ::testing::Test {
106 protected:
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000107 PacedSenderTest() : clock_(123456) {
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000108 srand(0);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000109 // Need to initialize PacedSender after we initialize clock.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000110 send_bucket_.reset(new PacedSender(&clock_,
111 &callback_,
112 kTargetBitrate,
113 kPaceMultiplier * kTargetBitrate,
114 0));
stefan@webrtc.orge9f0f592015-02-16 15:47:51 +0000115 // Default to bitrate probing disabled for testing purposes. Probing tests
116 // have to enable probing, either by creating a new PacedSender instance or
117 // by calling SetProbingEnabled(true).
118 send_bucket_->SetProbingEnabled(false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000119 }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000120
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000121 void SendAndExpectPacket(PacedSender::Priority priority,
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000122 uint32_t ssrc,
123 uint16_t sequence_number,
124 int64_t capture_time_ms,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000125 size_t size,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000126 bool retransmission) {
Peter Boströme23e7372015-10-08 11:44:14 +0200127 send_bucket_->InsertPacket(priority, ssrc, sequence_number, capture_time_ms,
128 size, retransmission);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000129 EXPECT_CALL(callback_,
130 TimeToSendPacket(ssrc, sequence_number, capture_time_ms, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000131 .Times(1)
132 .WillRepeatedly(Return(true));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000133 }
134
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000135 SimulatedClock clock_;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000136 MockPacedSenderCallback callback_;
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +0000137 rtc::scoped_ptr<PacedSender> send_bucket_;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000138};
139
140TEST_F(PacedSenderTest, QueuePacket) {
141 uint32_t ssrc = 12345;
142 uint16_t sequence_number = 1234;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000143 // Due to the multiplicative factor we can send 3 packets not 2 packets.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000144 SendAndExpectPacket(PacedSender::kNormalPriority,
145 ssrc,
146 sequence_number++,
147 clock_.TimeInMilliseconds(),
148 250,
149 false);
150 SendAndExpectPacket(PacedSender::kNormalPriority,
151 ssrc,
152 sequence_number++,
153 clock_.TimeInMilliseconds(),
154 250,
155 false);
156 SendAndExpectPacket(PacedSender::kNormalPriority,
157 ssrc,
158 sequence_number++,
159 clock_.TimeInMilliseconds(),
160 250,
161 false);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000162 int64_t queued_packet_timestamp = clock_.TimeInMilliseconds();
Peter Boströme23e7372015-10-08 11:44:14 +0200163 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
164 sequence_number, queued_packet_timestamp, 250,
165 false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000166 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000167 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000168 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000169 clock_.AdvanceTimeMilliseconds(4);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000170 EXPECT_EQ(1, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000171 clock_.AdvanceTimeMilliseconds(1);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000172 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000173 EXPECT_CALL(
174 callback_,
175 TimeToSendPacket(ssrc, sequence_number++, queued_packet_timestamp, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000176 .Times(1)
177 .WillRepeatedly(Return(true));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000178 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000179 sequence_number++;
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000180 SendAndExpectPacket(PacedSender::kNormalPriority,
181 ssrc,
182 sequence_number++,
183 clock_.TimeInMilliseconds(),
184 250,
185 false);
186 SendAndExpectPacket(PacedSender::kNormalPriority,
187 ssrc,
188 sequence_number++,
189 clock_.TimeInMilliseconds(),
190 250,
191 false);
Peter Boströme23e7372015-10-08 11:44:14 +0200192 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
193 sequence_number++, clock_.TimeInMilliseconds(),
194 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000195 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000196}
197
198TEST_F(PacedSenderTest, PaceQueuedPackets) {
199 uint32_t ssrc = 12345;
200 uint16_t sequence_number = 1234;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000201
202 // Due to the multiplicative factor we can send 3 packets not 2 packets.
203 for (int i = 0; i < 3; ++i) {
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000204 SendAndExpectPacket(PacedSender::kNormalPriority,
205 ssrc,
206 sequence_number++,
207 clock_.TimeInMilliseconds(),
208 250,
209 false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000210 }
211 for (int j = 0; j < 30; ++j) {
Peter Boströme23e7372015-10-08 11:44:14 +0200212 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
213 sequence_number++, clock_.TimeInMilliseconds(),
214 250, false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000215 }
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000216 send_bucket_->Process();
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000217 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000218 for (int k = 0; k < 10; ++k) {
219 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000220 clock_.AdvanceTimeMilliseconds(5);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000221 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, _, _, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000222 .Times(3)
223 .WillRepeatedly(Return(true));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000224 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
225 EXPECT_EQ(0, send_bucket_->Process());
226 }
227 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000228 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000229 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
230 EXPECT_EQ(0, send_bucket_->Process());
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000231 SendAndExpectPacket(PacedSender::kNormalPriority,
232 ssrc,
233 sequence_number++,
234 clock_.TimeInMilliseconds(),
235 250,
236 false);
237 SendAndExpectPacket(PacedSender::kNormalPriority,
238 ssrc,
239 sequence_number++,
240 clock_.TimeInMilliseconds(),
241 250,
242 false);
243 SendAndExpectPacket(PacedSender::kNormalPriority,
244 ssrc,
245 sequence_number++,
246 clock_.TimeInMilliseconds(),
247 250,
248 false);
Peter Boströme23e7372015-10-08 11:44:14 +0200249 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
250 sequence_number, clock_.TimeInMilliseconds(), 250,
251 false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000252 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000253}
254
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000255TEST_F(PacedSenderTest, PaceQueuedPacketsWithDuplicates) {
256 uint32_t ssrc = 12345;
257 uint16_t sequence_number = 1234;
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000258 uint16_t queued_sequence_number;
259
260 // Due to the multiplicative factor we can send 3 packets not 2 packets.
261 for (int i = 0; i < 3; ++i) {
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000262 SendAndExpectPacket(PacedSender::kNormalPriority,
263 ssrc,
264 sequence_number++,
265 clock_.TimeInMilliseconds(),
266 250,
267 false);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000268 }
269 queued_sequence_number = sequence_number;
270
271 for (int j = 0; j < 30; ++j) {
272 // Send in duplicate packets.
Peter Boströme23e7372015-10-08 11:44:14 +0200273 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
274 sequence_number, clock_.TimeInMilliseconds(),
275 250, false);
276 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
277 sequence_number++, clock_.TimeInMilliseconds(),
278 250, false);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000279 }
280 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000281 send_bucket_->Process();
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000282 for (int k = 0; k < 10; ++k) {
283 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000284 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000285
286 for (int i = 0; i < 3; ++i) {
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000287 EXPECT_CALL(callback_,
288 TimeToSendPacket(ssrc, queued_sequence_number++, _, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000289 .Times(1)
290 .WillRepeatedly(Return(true));
jbauchd2a22962016-02-08 23:18:25 -0800291 }
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000292 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
293 EXPECT_EQ(0, send_bucket_->Process());
294 }
295 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000296 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000297 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
298 EXPECT_EQ(0, send_bucket_->Process());
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000299 SendAndExpectPacket(PacedSender::kNormalPriority,
300 ssrc,
301 sequence_number++,
302 clock_.TimeInMilliseconds(),
303 250,
304 false);
305 SendAndExpectPacket(PacedSender::kNormalPriority,
306 ssrc,
307 sequence_number++,
308 clock_.TimeInMilliseconds(),
309 250,
310 false);
311 SendAndExpectPacket(PacedSender::kNormalPriority,
312 ssrc,
313 sequence_number++,
314 clock_.TimeInMilliseconds(),
315 250,
316 false);
Peter Boströme23e7372015-10-08 11:44:14 +0200317 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
318 sequence_number++, clock_.TimeInMilliseconds(),
319 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000320 send_bucket_->Process();
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000321}
322
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000323TEST_F(PacedSenderTest, CanQueuePacketsWithSameSequenceNumberOnDifferentSsrcs) {
324 uint32_t ssrc = 12345;
325 uint16_t sequence_number = 1234;
326
327 SendAndExpectPacket(PacedSender::kNormalPriority,
328 ssrc,
329 sequence_number,
330 clock_.TimeInMilliseconds(),
331 250,
332 false);
333
334 // Expect packet on second ssrc to be queued and sent as well.
335 SendAndExpectPacket(PacedSender::kNormalPriority,
336 ssrc + 1,
337 sequence_number,
338 clock_.TimeInMilliseconds(),
339 250,
340 false);
341
342 clock_.AdvanceTimeMilliseconds(1000);
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000343 send_bucket_->Process();
344}
345
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000346TEST_F(PacedSenderTest, Padding) {
347 uint32_t ssrc = 12345;
348 uint16_t sequence_number = 1234;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000349
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000350 send_bucket_->UpdateBitrate(
351 kTargetBitrate, kPaceMultiplier * kTargetBitrate, kTargetBitrate);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000352 // Due to the multiplicative factor we can send 3 packets not 2 packets.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000353 SendAndExpectPacket(PacedSender::kNormalPriority,
354 ssrc,
355 sequence_number++,
356 clock_.TimeInMilliseconds(),
357 250,
358 false);
359 SendAndExpectPacket(PacedSender::kNormalPriority,
360 ssrc,
361 sequence_number++,
362 clock_.TimeInMilliseconds(),
363 250,
364 false);
365 SendAndExpectPacket(PacedSender::kNormalPriority,
366 ssrc,
367 sequence_number++,
368 clock_.TimeInMilliseconds(),
369 250,
370 false);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000371 // No padding is expected since we have sent too much already.
372 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000373 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000374 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000375 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
376 EXPECT_EQ(0, send_bucket_->Process());
377
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000378 // 5 milliseconds later we have enough budget to send some padding.
379 EXPECT_CALL(callback_, TimeToSendPadding(250)).Times(1).
380 WillOnce(Return(250));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000381 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000382 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000383 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
384 EXPECT_EQ(0, send_bucket_->Process());
385}
386
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000387TEST_F(PacedSenderTest, VerifyPaddingUpToBitrate) {
388 uint32_t ssrc = 12345;
389 uint16_t sequence_number = 1234;
390 int64_t capture_time_ms = 56789;
391 const int kTimeStep = 5;
392 const int64_t kBitrateWindow = 100;
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000393 send_bucket_->UpdateBitrate(
394 kTargetBitrate, kPaceMultiplier * kTargetBitrate, kTargetBitrate);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000395 int64_t start_time = clock_.TimeInMilliseconds();
396 while (clock_.TimeInMilliseconds() - start_time < kBitrateWindow) {
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000397 SendAndExpectPacket(PacedSender::kNormalPriority,
398 ssrc,
399 sequence_number++,
400 capture_time_ms,
401 250,
402 false);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000403 clock_.AdvanceTimeMilliseconds(kTimeStep);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000404 EXPECT_CALL(callback_, TimeToSendPadding(250)).Times(1).
405 WillOnce(Return(250));
406 send_bucket_->Process();
407 }
408}
409
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000410TEST_F(PacedSenderTest, VerifyAverageBitrateVaryingMediaPayload) {
411 uint32_t ssrc = 12345;
412 uint16_t sequence_number = 1234;
413 int64_t capture_time_ms = 56789;
414 const int kTimeStep = 5;
415 const int64_t kBitrateWindow = 10000;
416 PacedSenderPadding callback;
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000417 send_bucket_.reset(new PacedSender(
418 &clock_, &callback, kTargetBitrate, kPaceMultiplier * kTargetBitrate, 0));
stefan@webrtc.orge9f0f592015-02-16 15:47:51 +0000419 send_bucket_->SetProbingEnabled(false);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000420 send_bucket_->UpdateBitrate(
421 kTargetBitrate, kPaceMultiplier * kTargetBitrate, kTargetBitrate);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000422 int64_t start_time = clock_.TimeInMilliseconds();
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000423 size_t media_bytes = 0;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000424 while (clock_.TimeInMilliseconds() - start_time < kBitrateWindow) {
jbauchd2a22962016-02-08 23:18:25 -0800425 int rand_value = rand(); // NOLINT (rand_r instead of rand)
426 size_t media_payload = rand_value % 100 + 200; // [200, 300] bytes.
Peter Boströme23e7372015-10-08 11:44:14 +0200427 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
428 sequence_number++, capture_time_ms,
429 media_payload, false);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000430 media_bytes += media_payload;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000431 clock_.AdvanceTimeMilliseconds(kTimeStep);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000432 send_bucket_->Process();
433 }
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000434 EXPECT_NEAR(kTargetBitrate,
435 static_cast<int>(8 * (media_bytes + callback.padding_sent()) /
436 kBitrateWindow), 1);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000437}
438
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000439TEST_F(PacedSenderTest, Priority) {
440 uint32_t ssrc_low_priority = 12345;
441 uint32_t ssrc = 12346;
442 uint16_t sequence_number = 1234;
443 int64_t capture_time_ms = 56789;
444 int64_t capture_time_ms_low_priority = 1234567;
445
446 // Due to the multiplicative factor we can send 3 packets not 2 packets.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000447 SendAndExpectPacket(PacedSender::kLowPriority,
448 ssrc,
449 sequence_number++,
450 capture_time_ms,
451 250,
452 false);
453 SendAndExpectPacket(PacedSender::kNormalPriority,
454 ssrc,
455 sequence_number++,
456 capture_time_ms,
457 250,
458 false);
459 SendAndExpectPacket(PacedSender::kNormalPriority,
460 ssrc,
461 sequence_number++,
462 capture_time_ms,
463 250,
464 false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000465 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000466
467 // Expect normal and low priority to be queued and high to pass through.
Peter Boströme23e7372015-10-08 11:44:14 +0200468 send_bucket_->InsertPacket(PacedSender::kLowPriority, ssrc_low_priority,
469 sequence_number++, capture_time_ms_low_priority,
470 250, false);
471 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
472 sequence_number++, capture_time_ms, 250, false);
473 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
474 sequence_number++, capture_time_ms, 250, false);
Stefan Holmerc482eb32015-12-16 16:55:03 +0100475 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
476 sequence_number++, capture_time_ms, 250, false);
Peter Boströme23e7372015-10-08 11:44:14 +0200477 send_bucket_->InsertPacket(PacedSender::kHighPriority, ssrc,
478 sequence_number++, capture_time_ms, 250, false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000479
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000480 // Expect all high and normal priority to be sent out first.
481 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000482 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, _, capture_time_ms, false))
Stefan Holmerc482eb32015-12-16 16:55:03 +0100483 .Times(4)
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000484 .WillRepeatedly(Return(true));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000485
486 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000487 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000488 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
489 EXPECT_EQ(0, send_bucket_->Process());
490
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000491 EXPECT_CALL(callback_,
492 TimeToSendPacket(
493 ssrc_low_priority, _, capture_time_ms_low_priority, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000494 .Times(1)
495 .WillRepeatedly(Return(true));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000496
497 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000498 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000499 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
500 EXPECT_EQ(0, send_bucket_->Process());
501}
502
Stefan Holmerc482eb32015-12-16 16:55:03 +0100503TEST_F(PacedSenderTest, HighPrioDoesntAffectBudget) {
504 uint32_t ssrc = 12346;
505 uint16_t sequence_number = 1234;
506 int64_t capture_time_ms = 56789;
507
508 // As high prio packets doesn't affect the budget, we should be able to send
509 // a high number of them at once.
510 for (int i = 0; i < 25; ++i) {
511 SendAndExpectPacket(PacedSender::kHighPriority, ssrc, sequence_number++,
512 capture_time_ms, 250, false);
513 }
514 send_bucket_->Process();
515 // Low prio packets does affect the budget, so we should only be able to send
516 // 3 at once, the 4th should be queued.
517 for (int i = 0; i < 3; ++i) {
518 SendAndExpectPacket(PacedSender::kLowPriority, ssrc, sequence_number++,
519 capture_time_ms, 250, false);
520 }
521 send_bucket_->InsertPacket(PacedSender::kLowPriority, ssrc, sequence_number,
522 capture_time_ms, 250, false);
523 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
524 clock_.AdvanceTimeMilliseconds(5);
525 send_bucket_->Process();
526 EXPECT_CALL(callback_,
527 TimeToSendPacket(ssrc, sequence_number++, capture_time_ms, false))
528 .Times(1);
529 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
530 clock_.AdvanceTimeMilliseconds(5);
531 send_bucket_->Process();
532}
533
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000534TEST_F(PacedSenderTest, Pause) {
535 uint32_t ssrc_low_priority = 12345;
536 uint32_t ssrc = 12346;
537 uint16_t sequence_number = 1234;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000538 int64_t capture_time_ms = clock_.TimeInMilliseconds();
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000539
540 EXPECT_EQ(0, send_bucket_->QueueInMs());
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000541
542 // Due to the multiplicative factor we can send 3 packets not 2 packets.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000543 SendAndExpectPacket(PacedSender::kLowPriority,
544 ssrc,
545 sequence_number++,
546 capture_time_ms,
547 250,
548 false);
549 SendAndExpectPacket(PacedSender::kNormalPriority,
550 ssrc,
551 sequence_number++,
552 capture_time_ms,
553 250,
554 false);
555 SendAndExpectPacket(PacedSender::kNormalPriority,
556 ssrc,
557 sequence_number++,
558 capture_time_ms,
559 250,
560 false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000561 send_bucket_->Process();
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000562
563 send_bucket_->Pause();
564
Peter Boströme23e7372015-10-08 11:44:14 +0200565 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
566 sequence_number++, capture_time_ms, 250, false);
567 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
568 sequence_number++, capture_time_ms, 250, false);
569 send_bucket_->InsertPacket(PacedSender::kHighPriority, ssrc,
570 sequence_number++, capture_time_ms, 250, false);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000571
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000572 clock_.AdvanceTimeMilliseconds(10000);
573 int64_t second_capture_time_ms = clock_.TimeInMilliseconds();
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000574
575 // Expect everything to be queued.
Peter Boströme23e7372015-10-08 11:44:14 +0200576 send_bucket_->InsertPacket(PacedSender::kLowPriority, ssrc_low_priority,
577 sequence_number++, second_capture_time_ms, 250,
578 false);
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000579
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000580 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms,
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000581 send_bucket_->QueueInMs());
582
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000583 // Expect no packet to come out while paused.
584 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000585 EXPECT_CALL(callback_, TimeToSendPacket(_, _, _, _)).Times(0);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000586
587 for (int i = 0; i < 10; ++i) {
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000588 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000589 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
590 EXPECT_EQ(0, send_bucket_->Process());
591 }
592 // Expect high prio packets to come out first followed by all packets in the
593 // way they were added.
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000594 EXPECT_CALL(callback_, TimeToSendPacket(_, _, capture_time_ms, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000595 .Times(3)
596 .WillRepeatedly(Return(true));
sprang0a43fef2015-11-20 09:00:37 -0800597 EXPECT_CALL(callback_, TimeToSendPacket(_, _, second_capture_time_ms, false))
598 .Times(1)
599 .WillRepeatedly(Return(true));
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000600 send_bucket_->Resume();
601
602 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000603 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000604 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
605 EXPECT_EQ(0, send_bucket_->Process());
606
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000607 EXPECT_EQ(0, send_bucket_->QueueInMs());
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000608}
609
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000610TEST_F(PacedSenderTest, ResendPacket) {
611 uint32_t ssrc = 12346;
612 uint16_t sequence_number = 1234;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000613 int64_t capture_time_ms = clock_.TimeInMilliseconds();
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000614 EXPECT_EQ(0, send_bucket_->QueueInMs());
615
Peter Boströme23e7372015-10-08 11:44:14 +0200616 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
617 sequence_number, capture_time_ms, 250, false);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000618 clock_.AdvanceTimeMilliseconds(1);
Peter Boströme23e7372015-10-08 11:44:14 +0200619 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
620 sequence_number + 1, capture_time_ms + 1, 250,
621 false);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000622 clock_.AdvanceTimeMilliseconds(9999);
623 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms,
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000624 send_bucket_->QueueInMs());
625 // Fails to send first packet so only one call.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000626 EXPECT_CALL(callback_,
627 TimeToSendPacket(ssrc, sequence_number, capture_time_ms, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000628 .Times(1)
629 .WillOnce(Return(false));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000630 clock_.AdvanceTimeMilliseconds(10000);
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000631 send_bucket_->Process();
632
633 // Queue remains unchanged.
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000634 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms,
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000635 send_bucket_->QueueInMs());
636
637 // Fails to send second packet.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000638 EXPECT_CALL(callback_,
639 TimeToSendPacket(ssrc, sequence_number, capture_time_ms, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000640 .Times(1)
641 .WillOnce(Return(true));
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000642 EXPECT_CALL(
643 callback_,
644 TimeToSendPacket(ssrc, sequence_number + 1, capture_time_ms + 1, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000645 .Times(1)
646 .WillOnce(Return(false));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000647 clock_.AdvanceTimeMilliseconds(10000);
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000648 send_bucket_->Process();
649
650 // Queue is reduced by 1 packet.
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000651 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms - 1,
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000652 send_bucket_->QueueInMs());
653
654 // Send second packet and queue becomes empty.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000655 EXPECT_CALL(
656 callback_,
657 TimeToSendPacket(ssrc, sequence_number + 1, capture_time_ms + 1, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000658 .Times(1)
659 .WillOnce(Return(true));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000660 clock_.AdvanceTimeMilliseconds(10000);
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000661 send_bucket_->Process();
662 EXPECT_EQ(0, send_bucket_->QueueInMs());
663}
664
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000665TEST_F(PacedSenderTest, ExpectedQueueTimeMs) {
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000666 uint32_t ssrc = 12346;
667 uint16_t sequence_number = 1234;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000668 const size_t kNumPackets = 60;
669 const size_t kPacketSize = 1200;
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000670 const int32_t kMaxBitrate = kPaceMultiplier * 30;
671 EXPECT_EQ(0, send_bucket_->ExpectedQueueTimeMs());
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000672
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000673 send_bucket_->UpdateBitrate(30, kMaxBitrate, 0);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000674 for (size_t i = 0; i < kNumPackets; ++i) {
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000675 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
676 clock_.TimeInMilliseconds(), kPacketSize, false);
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000677 }
678
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000679 // Queue in ms = 1000 * (bytes in queue) / (kbit per second * 1000 / 8)
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000680 int64_t queue_in_ms =
681 static_cast<int64_t>(kNumPackets * kPacketSize * 8 / kMaxBitrate);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000682 EXPECT_EQ(queue_in_ms, send_bucket_->ExpectedQueueTimeMs());
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000683
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000684 int64_t time_start = clock_.TimeInMilliseconds();
685 while (send_bucket_->QueueSizePackets() > 0) {
686 int time_until_process = send_bucket_->TimeUntilNextProcess();
687 if (time_until_process <= 0) {
688 send_bucket_->Process();
689 } else {
690 clock_.AdvanceTimeMilliseconds(time_until_process);
691 }
692 }
693 int64_t duration = clock_.TimeInMilliseconds() - time_start;
694
695 EXPECT_EQ(0, send_bucket_->ExpectedQueueTimeMs());
696
sprang0a43fef2015-11-20 09:00:37 -0800697 // Allow for aliasing, duration should be within one pack of max time limit.
698 EXPECT_NEAR(duration, PacedSender::kMaxQueueLengthMs,
699 static_cast<int64_t>(kPacketSize * 8 / kMaxBitrate));
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000700}
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000701
702TEST_F(PacedSenderTest, QueueTimeGrowsOverTime) {
703 uint32_t ssrc = 12346;
704 uint16_t sequence_number = 1234;
705 EXPECT_EQ(0, send_bucket_->QueueInMs());
706
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000707 send_bucket_->UpdateBitrate(30, kPaceMultiplier * 30, 0);
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000708 SendAndExpectPacket(PacedSender::kNormalPriority,
709 ssrc,
710 sequence_number,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000711 clock_.TimeInMilliseconds(),
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000712 1200,
713 false);
714
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000715 clock_.AdvanceTimeMilliseconds(500);
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000716 EXPECT_EQ(500, send_bucket_->QueueInMs());
717 send_bucket_->Process();
718 EXPECT_EQ(0, send_bucket_->QueueInMs());
719}
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000720
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000721TEST_F(PacedSenderTest, ProbingWithInitialFrame) {
stefan@webrtc.orgd839e0a2014-11-04 19:33:55 +0000722 const int kNumPackets = 11;
723 const int kNumDeltas = kNumPackets - 1;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000724 const size_t kPacketSize = 1200;
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000725 const int kInitialBitrateKbps = 300;
726 uint32_t ssrc = 12346;
727 uint16_t sequence_number = 1234;
stefan@webrtc.orgd839e0a2014-11-04 19:33:55 +0000728 const int expected_deltas[kNumDeltas] = {
729 10, 10, 10, 10, 10, 5, 5, 5, 5, 5};
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000730 std::list<int> expected_deltas_list(expected_deltas,
731 expected_deltas + kNumPackets - 1);
732 PacedSenderProbing callback(expected_deltas_list, &clock_);
733 send_bucket_.reset(
stefan@webrtc.orge9f0f592015-02-16 15:47:51 +0000734 new PacedSender(&clock_,
735 &callback,
736 kInitialBitrateKbps,
737 kPaceMultiplier * kInitialBitrateKbps,
738 0));
739
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000740 for (int i = 0; i < kNumPackets; ++i) {
Peter Boströme23e7372015-10-08 11:44:14 +0200741 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
742 sequence_number++, clock_.TimeInMilliseconds(),
743 kPacketSize, false);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000744 }
745 while (callback.packets_sent() < kNumPackets) {
746 int time_until_process = send_bucket_->TimeUntilNextProcess();
747 if (time_until_process <= 0) {
748 send_bucket_->Process();
749 } else {
750 clock_.AdvanceTimeMilliseconds(time_until_process);
751 }
752 }
753}
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000754
Stefan Holmer01b48882015-05-05 10:21:24 +0200755TEST_F(PacedSenderTest, ProbingWithTooSmallInitialFrame) {
756 const int kNumPackets = 11;
757 const int kNumDeltas = kNumPackets - 1;
758 const size_t kPacketSize = 1200;
759 const int kInitialBitrateKbps = 300;
760 uint32_t ssrc = 12346;
761 uint16_t sequence_number = 1234;
762 const int expected_deltas[kNumDeltas] = {10, 10, 10, 10, 10, 5, 5, 5, 5, 5};
763 std::list<int> expected_deltas_list(expected_deltas,
764 expected_deltas + kNumPackets - 1);
765 PacedSenderProbing callback(expected_deltas_list, &clock_);
Stefan Holmer586b19b2015-09-18 11:14:31 +0200766 send_bucket_.reset(new PacedSender(&clock_, &callback, kInitialBitrateKbps,
767 kPaceMultiplier * kInitialBitrateKbps, 0));
Stefan Holmer01b48882015-05-05 10:21:24 +0200768
769 for (int i = 0; i < kNumPackets - 5; ++i) {
Peter Boströme23e7372015-10-08 11:44:14 +0200770 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
771 sequence_number++, clock_.TimeInMilliseconds(),
772 kPacketSize, false);
Stefan Holmer01b48882015-05-05 10:21:24 +0200773 }
774 while (callback.packets_sent() < kNumPackets) {
775 int time_until_process = send_bucket_->TimeUntilNextProcess();
776 if (time_until_process <= 0) {
777 send_bucket_->Process();
778 } else {
779 clock_.AdvanceTimeMilliseconds(time_until_process);
780 }
781 }
782
783 // Process one more time and make sure we don't send any more probes.
784 int time_until_process = send_bucket_->TimeUntilNextProcess();
785 clock_.AdvanceTimeMilliseconds(time_until_process);
786 send_bucket_->Process();
787 EXPECT_EQ(kNumPackets, callback.packets_sent());
788}
789
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000790TEST_F(PacedSenderTest, PriorityInversion) {
791 uint32_t ssrc = 12346;
792 uint16_t sequence_number = 1234;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000793 const size_t kPacketSize = 1200;
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000794
Peter Boströme23e7372015-10-08 11:44:14 +0200795 send_bucket_->InsertPacket(
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000796 PacedSender::kHighPriority, ssrc, sequence_number + 3,
Peter Boströme23e7372015-10-08 11:44:14 +0200797 clock_.TimeInMilliseconds() + 33, kPacketSize, true);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000798
Peter Boströme23e7372015-10-08 11:44:14 +0200799 send_bucket_->InsertPacket(
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000800 PacedSender::kHighPriority, ssrc, sequence_number + 2,
Peter Boströme23e7372015-10-08 11:44:14 +0200801 clock_.TimeInMilliseconds() + 33, kPacketSize, true);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000802
Peter Boströme23e7372015-10-08 11:44:14 +0200803 send_bucket_->InsertPacket(PacedSender::kHighPriority, ssrc, sequence_number,
804 clock_.TimeInMilliseconds(), kPacketSize, true);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000805
Peter Boströme23e7372015-10-08 11:44:14 +0200806 send_bucket_->InsertPacket(PacedSender::kHighPriority, ssrc,
807 sequence_number + 1, clock_.TimeInMilliseconds(),
808 kPacketSize, true);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000809
810 // Packets from earlier frames should be sent first.
811 {
812 ::testing::InSequence sequence;
813 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number,
814 clock_.TimeInMilliseconds(), true))
815 .WillOnce(Return(true));
816 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number + 1,
817 clock_.TimeInMilliseconds(), true))
818 .WillOnce(Return(true));
819 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number + 3,
820 clock_.TimeInMilliseconds() + 33,
821 true)).WillOnce(Return(true));
822 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number + 2,
823 clock_.TimeInMilliseconds() + 33,
824 true)).WillOnce(Return(true));
825
826 while (send_bucket_->QueueSizePackets() > 0) {
827 int time_until_process = send_bucket_->TimeUntilNextProcess();
828 if (time_until_process <= 0) {
829 send_bucket_->Process();
830 } else {
831 clock_.AdvanceTimeMilliseconds(time_until_process);
832 }
833 }
834 }
835}
836
837TEST_F(PacedSenderTest, PaddingOveruse) {
838 uint32_t ssrc = 12346;
839 uint16_t sequence_number = 1234;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000840 const size_t kPacketSize = 1200;
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000841
842 // Min bitrate 0 => no padding, padding budget will stay at 0.
843 send_bucket_->UpdateBitrate(60, 90, 0);
844 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
845 clock_.TimeInMilliseconds(), kPacketSize, false);
846 send_bucket_->Process();
847
848 // Add 30kbit padding. When increasing budget, media budget will increase from
849 // negative (overuse) while padding budget will increase form 0.
850 clock_.AdvanceTimeMilliseconds(5);
851 send_bucket_->UpdateBitrate(60, 90, 30);
852
Peter Boströme23e7372015-10-08 11:44:14 +0200853 send_bucket_->InsertPacket(PacedSender::kHighPriority, ssrc,
854 sequence_number++, clock_.TimeInMilliseconds(),
855 kPacketSize, false);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000856
857 // Don't send padding if queue is non-empty, even if padding budget > 0.
858 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
859 send_bucket_->Process();
860}
861
Erik Språngad113e52015-11-26 16:26:12 +0100862TEST_F(PacedSenderTest, AverageQueueTime) {
863 uint32_t ssrc = 12346;
864 uint16_t sequence_number = 1234;
865 const size_t kPacketSize = 1200;
866 const int kBitrateBps = 10 * kPacketSize * 8; // 10 packets per second.
867 const int kBitrateKbps = (kBitrateBps + 500) / 1000;
868
869 send_bucket_->UpdateBitrate(kBitrateKbps, kBitrateKbps, kBitrateKbps);
870
871 EXPECT_EQ(0, send_bucket_->AverageQueueTimeMs());
872
873 int64_t first_capture_time = clock_.TimeInMilliseconds();
Stefan Holmerc482eb32015-12-16 16:55:03 +0100874 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
875 sequence_number, first_capture_time, kPacketSize,
876 false);
Erik Språngad113e52015-11-26 16:26:12 +0100877 clock_.AdvanceTimeMilliseconds(10);
Stefan Holmerc482eb32015-12-16 16:55:03 +0100878 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
Erik Språngad113e52015-11-26 16:26:12 +0100879 sequence_number + 1, clock_.TimeInMilliseconds(),
880 kPacketSize, false);
881 clock_.AdvanceTimeMilliseconds(10);
882
883 EXPECT_EQ((20 + 10) / 2, send_bucket_->AverageQueueTimeMs());
884
885 // Only first packet (queued for 20ms) should be removed, leave the second
886 // packet (queued for 10ms) alone in the queue.
887 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number,
888 first_capture_time, false))
889 .Times(1)
890 .WillRepeatedly(Return(true));
891 send_bucket_->Process();
892
893 EXPECT_EQ(10, send_bucket_->AverageQueueTimeMs());
894
895 clock_.AdvanceTimeMilliseconds(10);
896 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number + 1,
897 first_capture_time + 10, false))
898 .Times(1)
899 .WillRepeatedly(Return(true));
900 for (int i = 0; i < 3; ++i) {
901 clock_.AdvanceTimeMilliseconds(30); // Max delta.
902 send_bucket_->Process();
903 }
904
905 EXPECT_EQ(0, send_bucket_->AverageQueueTimeMs());
906}
907
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000908} // namespace test
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000909} // namespace webrtc