blob: 941c81335b6cf073c7a5bac225c84fecbeb5784d [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>
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000013
pbos@webrtc.orgdb6e3f82013-07-11 09:50:05 +000014#include "testing/gmock/include/gmock/gmock.h"
15#include "testing/gtest/include/gtest/gtest.h"
Henrik Kjellander0b9e29c2015-11-16 11:12:24 +010016#include "webrtc/modules/pacing/paced_sender.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010017#include "webrtc/system_wrappers/include/clock.h"
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000018
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +000019using testing::_;
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000020using testing::Return;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000021
22namespace webrtc {
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +000023namespace test {
24
25static const int kTargetBitrate = 800;
pwestin@webrtc.org52b4e882013-05-02 19:02:17 +000026static const float kPaceMultiplier = 1.5f;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000027
28class MockPacedSenderCallback : public PacedSender::Callback {
29 public:
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +000030 MOCK_METHOD4(TimeToSendPacket,
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000031 bool(uint32_t ssrc,
32 uint16_t sequence_number,
33 int64_t capture_time_ms,
34 bool retransmission));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000035 MOCK_METHOD1(TimeToSendPadding,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000036 size_t(size_t bytes));
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000037};
38
39class PacedSenderPadding : public PacedSender::Callback {
40 public:
41 PacedSenderPadding() : padding_sent_(0) {}
42
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000043 bool TimeToSendPacket(uint32_t ssrc,
44 uint16_t sequence_number,
45 int64_t capture_time_ms,
46 bool retransmission) {
hclam@chromium.org2e402ce2013-06-20 20:18:31 +000047 return true;
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000048 }
49
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000050 size_t TimeToSendPadding(size_t bytes) {
51 const size_t kPaddingPacketSize = 224;
52 size_t num_packets = (bytes + kPaddingPacketSize - 1) / kPaddingPacketSize;
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000053 padding_sent_ += kPaddingPacketSize * num_packets;
54 return kPaddingPacketSize * num_packets;
55 }
56
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000057 size_t padding_sent() { return padding_sent_; }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000058
59 private:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000060 size_t padding_sent_;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000061};
62
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000063class PacedSenderProbing : public PacedSender::Callback {
64 public:
65 PacedSenderProbing(const std::list<int>& expected_deltas, Clock* clock)
66 : prev_packet_time_ms_(-1),
67 expected_deltas_(expected_deltas),
68 packets_sent_(0),
69 clock_(clock) {}
70
71 bool TimeToSendPacket(uint32_t ssrc,
72 uint16_t sequence_number,
73 int64_t capture_time_ms,
74 bool retransmission) {
Stefan Holmer01b48882015-05-05 10:21:24 +020075 ExpectAndCountPacket();
76 return true;
77 }
78
79 size_t TimeToSendPadding(size_t bytes) {
80 ExpectAndCountPacket();
81 return bytes;
82 }
83
84 void ExpectAndCountPacket() {
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000085 ++packets_sent_;
86 EXPECT_FALSE(expected_deltas_.empty());
87 if (expected_deltas_.empty())
Stefan Holmer01b48882015-05-05 10:21:24 +020088 return;
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000089 int64_t now_ms = clock_->TimeInMilliseconds();
90 if (prev_packet_time_ms_ >= 0) {
91 EXPECT_EQ(expected_deltas_.front(), now_ms - prev_packet_time_ms_);
92 expected_deltas_.pop_front();
93 }
94 prev_packet_time_ms_ = now_ms;
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000095 }
96
97 int packets_sent() const { return packets_sent_; }
98
99 private:
100 int64_t prev_packet_time_ms_;
101 std::list<int> expected_deltas_;
102 int packets_sent_;
103 Clock* clock_;
104};
105
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000106class PacedSenderTest : public ::testing::Test {
107 protected:
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000108 PacedSenderTest() : clock_(123456) {
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000109 srand(0);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000110 // Need to initialize PacedSender after we initialize clock.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000111 send_bucket_.reset(new PacedSender(&clock_,
112 &callback_,
113 kTargetBitrate,
114 kPaceMultiplier * kTargetBitrate,
115 0));
stefan@webrtc.orge9f0f592015-02-16 15:47:51 +0000116 // Default to bitrate probing disabled for testing purposes. Probing tests
117 // have to enable probing, either by creating a new PacedSender instance or
118 // by calling SetProbingEnabled(true).
119 send_bucket_->SetProbingEnabled(false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000120 }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000121
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000122 void SendAndExpectPacket(PacedSender::Priority priority,
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000123 uint32_t ssrc,
124 uint16_t sequence_number,
125 int64_t capture_time_ms,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000126 size_t size,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000127 bool retransmission) {
Peter Boströme23e7372015-10-08 11:44:14 +0200128 send_bucket_->InsertPacket(priority, ssrc, sequence_number, capture_time_ms,
129 size, retransmission);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000130 EXPECT_CALL(callback_,
131 TimeToSendPacket(ssrc, sequence_number, capture_time_ms, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000132 .Times(1)
133 .WillRepeatedly(Return(true));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000134 }
135
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000136 SimulatedClock clock_;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000137 MockPacedSenderCallback callback_;
kwiberg22feaa32016-03-17 09:17:43 -0700138 std::unique_ptr<PacedSender> send_bucket_;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000139};
140
141TEST_F(PacedSenderTest, QueuePacket) {
142 uint32_t ssrc = 12345;
143 uint16_t sequence_number = 1234;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000144 // Due to the multiplicative factor we can send 3 packets not 2 packets.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000145 SendAndExpectPacket(PacedSender::kNormalPriority,
146 ssrc,
147 sequence_number++,
148 clock_.TimeInMilliseconds(),
149 250,
150 false);
151 SendAndExpectPacket(PacedSender::kNormalPriority,
152 ssrc,
153 sequence_number++,
154 clock_.TimeInMilliseconds(),
155 250,
156 false);
157 SendAndExpectPacket(PacedSender::kNormalPriority,
158 ssrc,
159 sequence_number++,
160 clock_.TimeInMilliseconds(),
161 250,
162 false);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000163 int64_t queued_packet_timestamp = clock_.TimeInMilliseconds();
Peter Boströme23e7372015-10-08 11:44:14 +0200164 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
165 sequence_number, queued_packet_timestamp, 250,
166 false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000167 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000168 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000169 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000170 clock_.AdvanceTimeMilliseconds(4);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000171 EXPECT_EQ(1, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000172 clock_.AdvanceTimeMilliseconds(1);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000173 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000174 EXPECT_CALL(
175 callback_,
176 TimeToSendPacket(ssrc, sequence_number++, queued_packet_timestamp, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000177 .Times(1)
178 .WillRepeatedly(Return(true));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000179 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000180 sequence_number++;
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000181 SendAndExpectPacket(PacedSender::kNormalPriority,
182 ssrc,
183 sequence_number++,
184 clock_.TimeInMilliseconds(),
185 250,
186 false);
187 SendAndExpectPacket(PacedSender::kNormalPriority,
188 ssrc,
189 sequence_number++,
190 clock_.TimeInMilliseconds(),
191 250,
192 false);
Peter Boströme23e7372015-10-08 11:44:14 +0200193 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
194 sequence_number++, clock_.TimeInMilliseconds(),
195 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000196 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000197}
198
199TEST_F(PacedSenderTest, PaceQueuedPackets) {
200 uint32_t ssrc = 12345;
201 uint16_t sequence_number = 1234;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000202
203 // Due to the multiplicative factor we can send 3 packets not 2 packets.
204 for (int i = 0; i < 3; ++i) {
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000205 SendAndExpectPacket(PacedSender::kNormalPriority,
206 ssrc,
207 sequence_number++,
208 clock_.TimeInMilliseconds(),
209 250,
210 false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000211 }
212 for (int j = 0; j < 30; ++j) {
Peter Boströme23e7372015-10-08 11:44:14 +0200213 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
214 sequence_number++, clock_.TimeInMilliseconds(),
215 250, false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000216 }
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000217 send_bucket_->Process();
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000218 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000219 for (int k = 0; k < 10; ++k) {
220 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000221 clock_.AdvanceTimeMilliseconds(5);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000222 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, _, _, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000223 .Times(3)
224 .WillRepeatedly(Return(true));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000225 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800226 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000227 }
228 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000229 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000230 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800231 send_bucket_->Process();
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000232 SendAndExpectPacket(PacedSender::kNormalPriority,
233 ssrc,
234 sequence_number++,
235 clock_.TimeInMilliseconds(),
236 250,
237 false);
238 SendAndExpectPacket(PacedSender::kNormalPriority,
239 ssrc,
240 sequence_number++,
241 clock_.TimeInMilliseconds(),
242 250,
243 false);
244 SendAndExpectPacket(PacedSender::kNormalPriority,
245 ssrc,
246 sequence_number++,
247 clock_.TimeInMilliseconds(),
248 250,
249 false);
Peter Boströme23e7372015-10-08 11:44:14 +0200250 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
251 sequence_number, clock_.TimeInMilliseconds(), 250,
252 false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000253 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000254}
255
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000256TEST_F(PacedSenderTest, PaceQueuedPacketsWithDuplicates) {
257 uint32_t ssrc = 12345;
258 uint16_t sequence_number = 1234;
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000259 uint16_t queued_sequence_number;
260
261 // Due to the multiplicative factor we can send 3 packets not 2 packets.
262 for (int i = 0; i < 3; ++i) {
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000263 SendAndExpectPacket(PacedSender::kNormalPriority,
264 ssrc,
265 sequence_number++,
266 clock_.TimeInMilliseconds(),
267 250,
268 false);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000269 }
270 queued_sequence_number = sequence_number;
271
272 for (int j = 0; j < 30; ++j) {
273 // Send in duplicate packets.
Peter Boströme23e7372015-10-08 11:44:14 +0200274 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
275 sequence_number, clock_.TimeInMilliseconds(),
276 250, false);
277 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
278 sequence_number++, clock_.TimeInMilliseconds(),
279 250, false);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000280 }
281 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000282 send_bucket_->Process();
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000283 for (int k = 0; k < 10; ++k) {
284 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000285 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000286
287 for (int i = 0; i < 3; ++i) {
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000288 EXPECT_CALL(callback_,
289 TimeToSendPacket(ssrc, queued_sequence_number++, _, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000290 .Times(1)
291 .WillRepeatedly(Return(true));
jbauchd2a22962016-02-08 23:18:25 -0800292 }
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000293 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800294 send_bucket_->Process();
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000295 }
296 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000297 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000298 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800299 send_bucket_->Process();
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000300 SendAndExpectPacket(PacedSender::kNormalPriority,
301 ssrc,
302 sequence_number++,
303 clock_.TimeInMilliseconds(),
304 250,
305 false);
306 SendAndExpectPacket(PacedSender::kNormalPriority,
307 ssrc,
308 sequence_number++,
309 clock_.TimeInMilliseconds(),
310 250,
311 false);
312 SendAndExpectPacket(PacedSender::kNormalPriority,
313 ssrc,
314 sequence_number++,
315 clock_.TimeInMilliseconds(),
316 250,
317 false);
Peter Boströme23e7372015-10-08 11:44:14 +0200318 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
319 sequence_number++, clock_.TimeInMilliseconds(),
320 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000321 send_bucket_->Process();
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000322}
323
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000324TEST_F(PacedSenderTest, CanQueuePacketsWithSameSequenceNumberOnDifferentSsrcs) {
325 uint32_t ssrc = 12345;
326 uint16_t sequence_number = 1234;
327
328 SendAndExpectPacket(PacedSender::kNormalPriority,
329 ssrc,
330 sequence_number,
331 clock_.TimeInMilliseconds(),
332 250,
333 false);
334
335 // Expect packet on second ssrc to be queued and sent as well.
336 SendAndExpectPacket(PacedSender::kNormalPriority,
337 ssrc + 1,
338 sequence_number,
339 clock_.TimeInMilliseconds(),
340 250,
341 false);
342
343 clock_.AdvanceTimeMilliseconds(1000);
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000344 send_bucket_->Process();
345}
346
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000347TEST_F(PacedSenderTest, Padding) {
348 uint32_t ssrc = 12345;
349 uint16_t sequence_number = 1234;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000350
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000351 send_bucket_->UpdateBitrate(
352 kTargetBitrate, kPaceMultiplier * kTargetBitrate, kTargetBitrate);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000353 // Due to the multiplicative factor we can send 3 packets not 2 packets.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000354 SendAndExpectPacket(PacedSender::kNormalPriority,
355 ssrc,
356 sequence_number++,
357 clock_.TimeInMilliseconds(),
358 250,
359 false);
360 SendAndExpectPacket(PacedSender::kNormalPriority,
361 ssrc,
362 sequence_number++,
363 clock_.TimeInMilliseconds(),
364 250,
365 false);
366 SendAndExpectPacket(PacedSender::kNormalPriority,
367 ssrc,
368 sequence_number++,
369 clock_.TimeInMilliseconds(),
370 250,
371 false);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000372 // No padding is expected since we have sent too much already.
373 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000374 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000375 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000376 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800377 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000378
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000379 // 5 milliseconds later we have enough budget to send some padding.
380 EXPECT_CALL(callback_, TimeToSendPadding(250)).Times(1).
381 WillOnce(Return(250));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000382 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000383 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000384 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800385 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000386}
387
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000388TEST_F(PacedSenderTest, VerifyPaddingUpToBitrate) {
389 uint32_t ssrc = 12345;
390 uint16_t sequence_number = 1234;
391 int64_t capture_time_ms = 56789;
392 const int kTimeStep = 5;
393 const int64_t kBitrateWindow = 100;
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000394 send_bucket_->UpdateBitrate(
395 kTargetBitrate, kPaceMultiplier * kTargetBitrate, kTargetBitrate);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000396 int64_t start_time = clock_.TimeInMilliseconds();
397 while (clock_.TimeInMilliseconds() - start_time < kBitrateWindow) {
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000398 SendAndExpectPacket(PacedSender::kNormalPriority,
399 ssrc,
400 sequence_number++,
401 capture_time_ms,
402 250,
403 false);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000404 clock_.AdvanceTimeMilliseconds(kTimeStep);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000405 EXPECT_CALL(callback_, TimeToSendPadding(250)).Times(1).
406 WillOnce(Return(250));
407 send_bucket_->Process();
408 }
409}
410
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000411TEST_F(PacedSenderTest, VerifyAverageBitrateVaryingMediaPayload) {
412 uint32_t ssrc = 12345;
413 uint16_t sequence_number = 1234;
414 int64_t capture_time_ms = 56789;
415 const int kTimeStep = 5;
416 const int64_t kBitrateWindow = 10000;
417 PacedSenderPadding callback;
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000418 send_bucket_.reset(new PacedSender(
419 &clock_, &callback, kTargetBitrate, kPaceMultiplier * kTargetBitrate, 0));
stefan@webrtc.orge9f0f592015-02-16 15:47:51 +0000420 send_bucket_->SetProbingEnabled(false);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000421 send_bucket_->UpdateBitrate(
422 kTargetBitrate, kPaceMultiplier * kTargetBitrate, kTargetBitrate);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000423 int64_t start_time = clock_.TimeInMilliseconds();
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000424 size_t media_bytes = 0;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000425 while (clock_.TimeInMilliseconds() - start_time < kBitrateWindow) {
jbauchd2a22962016-02-08 23:18:25 -0800426 int rand_value = rand(); // NOLINT (rand_r instead of rand)
427 size_t media_payload = rand_value % 100 + 200; // [200, 300] bytes.
Peter Boströme23e7372015-10-08 11:44:14 +0200428 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
429 sequence_number++, capture_time_ms,
430 media_payload, false);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000431 media_bytes += media_payload;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000432 clock_.AdvanceTimeMilliseconds(kTimeStep);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000433 send_bucket_->Process();
434 }
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000435 EXPECT_NEAR(kTargetBitrate,
436 static_cast<int>(8 * (media_bytes + callback.padding_sent()) /
437 kBitrateWindow), 1);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000438}
439
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000440TEST_F(PacedSenderTest, Priority) {
441 uint32_t ssrc_low_priority = 12345;
442 uint32_t ssrc = 12346;
443 uint16_t sequence_number = 1234;
444 int64_t capture_time_ms = 56789;
445 int64_t capture_time_ms_low_priority = 1234567;
446
447 // Due to the multiplicative factor we can send 3 packets not 2 packets.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000448 SendAndExpectPacket(PacedSender::kLowPriority,
449 ssrc,
450 sequence_number++,
451 capture_time_ms,
452 250,
453 false);
454 SendAndExpectPacket(PacedSender::kNormalPriority,
455 ssrc,
456 sequence_number++,
457 capture_time_ms,
458 250,
459 false);
460 SendAndExpectPacket(PacedSender::kNormalPriority,
461 ssrc,
462 sequence_number++,
463 capture_time_ms,
464 250,
465 false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000466 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000467
468 // Expect normal and low priority to be queued and high to pass through.
Peter Boströme23e7372015-10-08 11:44:14 +0200469 send_bucket_->InsertPacket(PacedSender::kLowPriority, ssrc_low_priority,
470 sequence_number++, capture_time_ms_low_priority,
471 250, false);
472 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
473 sequence_number++, capture_time_ms, 250, false);
474 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
475 sequence_number++, capture_time_ms, 250, false);
Stefan Holmerc482eb32015-12-16 16:55:03 +0100476 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
477 sequence_number++, capture_time_ms, 250, false);
Peter Boströme23e7372015-10-08 11:44:14 +0200478 send_bucket_->InsertPacket(PacedSender::kHighPriority, ssrc,
479 sequence_number++, capture_time_ms, 250, false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000480
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000481 // Expect all high and normal priority to be sent out first.
482 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000483 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, _, capture_time_ms, false))
Stefan Holmerc482eb32015-12-16 16:55:03 +0100484 .Times(4)
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000485 .WillRepeatedly(Return(true));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000486
487 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000488 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000489 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800490 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000491
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000492 EXPECT_CALL(callback_,
493 TimeToSendPacket(
494 ssrc_low_priority, _, capture_time_ms_low_priority, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000495 .Times(1)
496 .WillRepeatedly(Return(true));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000497
498 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000499 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000500 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800501 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000502}
503
Stefan Holmerc482eb32015-12-16 16:55:03 +0100504TEST_F(PacedSenderTest, HighPrioDoesntAffectBudget) {
505 uint32_t ssrc = 12346;
506 uint16_t sequence_number = 1234;
507 int64_t capture_time_ms = 56789;
508
509 // As high prio packets doesn't affect the budget, we should be able to send
510 // a high number of them at once.
511 for (int i = 0; i < 25; ++i) {
512 SendAndExpectPacket(PacedSender::kHighPriority, ssrc, sequence_number++,
513 capture_time_ms, 250, false);
514 }
515 send_bucket_->Process();
516 // Low prio packets does affect the budget, so we should only be able to send
517 // 3 at once, the 4th should be queued.
518 for (int i = 0; i < 3; ++i) {
519 SendAndExpectPacket(PacedSender::kLowPriority, ssrc, sequence_number++,
520 capture_time_ms, 250, false);
521 }
522 send_bucket_->InsertPacket(PacedSender::kLowPriority, ssrc, sequence_number,
523 capture_time_ms, 250, false);
524 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
525 clock_.AdvanceTimeMilliseconds(5);
526 send_bucket_->Process();
527 EXPECT_CALL(callback_,
528 TimeToSendPacket(ssrc, sequence_number++, capture_time_ms, false))
529 .Times(1);
530 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
531 clock_.AdvanceTimeMilliseconds(5);
532 send_bucket_->Process();
533}
534
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000535TEST_F(PacedSenderTest, Pause) {
536 uint32_t ssrc_low_priority = 12345;
537 uint32_t ssrc = 12346;
538 uint16_t sequence_number = 1234;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000539 int64_t capture_time_ms = clock_.TimeInMilliseconds();
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000540
541 EXPECT_EQ(0, send_bucket_->QueueInMs());
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000542
543 // Due to the multiplicative factor we can send 3 packets not 2 packets.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000544 SendAndExpectPacket(PacedSender::kLowPriority,
545 ssrc,
546 sequence_number++,
547 capture_time_ms,
548 250,
549 false);
550 SendAndExpectPacket(PacedSender::kNormalPriority,
551 ssrc,
552 sequence_number++,
553 capture_time_ms,
554 250,
555 false);
556 SendAndExpectPacket(PacedSender::kNormalPriority,
557 ssrc,
558 sequence_number++,
559 capture_time_ms,
560 250,
561 false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000562 send_bucket_->Process();
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000563
564 send_bucket_->Pause();
565
Peter Boströme23e7372015-10-08 11:44:14 +0200566 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
567 sequence_number++, capture_time_ms, 250, false);
568 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
569 sequence_number++, capture_time_ms, 250, false);
570 send_bucket_->InsertPacket(PacedSender::kHighPriority, ssrc,
571 sequence_number++, capture_time_ms, 250, false);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000572
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000573 clock_.AdvanceTimeMilliseconds(10000);
574 int64_t second_capture_time_ms = clock_.TimeInMilliseconds();
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000575
576 // Expect everything to be queued.
Peter Boströme23e7372015-10-08 11:44:14 +0200577 send_bucket_->InsertPacket(PacedSender::kLowPriority, ssrc_low_priority,
578 sequence_number++, second_capture_time_ms, 250,
579 false);
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000580
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000581 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms,
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000582 send_bucket_->QueueInMs());
583
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000584 // Expect no packet to come out while paused.
585 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000586 EXPECT_CALL(callback_, TimeToSendPacket(_, _, _, _)).Times(0);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000587
588 for (int i = 0; i < 10; ++i) {
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000589 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000590 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800591 send_bucket_->Process();
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000592 }
593 // Expect high prio packets to come out first followed by all packets in the
594 // way they were added.
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000595 EXPECT_CALL(callback_, TimeToSendPacket(_, _, capture_time_ms, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000596 .Times(3)
597 .WillRepeatedly(Return(true));
sprang0a43fef2015-11-20 09:00:37 -0800598 EXPECT_CALL(callback_, TimeToSendPacket(_, _, second_capture_time_ms, false))
599 .Times(1)
600 .WillRepeatedly(Return(true));
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000601 send_bucket_->Resume();
602
603 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000604 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000605 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800606 send_bucket_->Process();
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000607
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000608 EXPECT_EQ(0, send_bucket_->QueueInMs());
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000609}
610
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000611TEST_F(PacedSenderTest, ResendPacket) {
612 uint32_t ssrc = 12346;
613 uint16_t sequence_number = 1234;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000614 int64_t capture_time_ms = clock_.TimeInMilliseconds();
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000615 EXPECT_EQ(0, send_bucket_->QueueInMs());
616
Peter Boströme23e7372015-10-08 11:44:14 +0200617 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
618 sequence_number, capture_time_ms, 250, false);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000619 clock_.AdvanceTimeMilliseconds(1);
Peter Boströme23e7372015-10-08 11:44:14 +0200620 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
621 sequence_number + 1, capture_time_ms + 1, 250,
622 false);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000623 clock_.AdvanceTimeMilliseconds(9999);
624 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms,
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000625 send_bucket_->QueueInMs());
626 // Fails to send first packet so only one call.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000627 EXPECT_CALL(callback_,
628 TimeToSendPacket(ssrc, sequence_number, capture_time_ms, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000629 .Times(1)
630 .WillOnce(Return(false));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000631 clock_.AdvanceTimeMilliseconds(10000);
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000632 send_bucket_->Process();
633
634 // Queue remains unchanged.
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000635 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms,
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000636 send_bucket_->QueueInMs());
637
638 // Fails to send second packet.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000639 EXPECT_CALL(callback_,
640 TimeToSendPacket(ssrc, sequence_number, capture_time_ms, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000641 .Times(1)
642 .WillOnce(Return(true));
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000643 EXPECT_CALL(
644 callback_,
645 TimeToSendPacket(ssrc, sequence_number + 1, capture_time_ms + 1, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000646 .Times(1)
647 .WillOnce(Return(false));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000648 clock_.AdvanceTimeMilliseconds(10000);
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000649 send_bucket_->Process();
650
651 // Queue is reduced by 1 packet.
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000652 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms - 1,
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000653 send_bucket_->QueueInMs());
654
655 // Send second packet and queue becomes empty.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000656 EXPECT_CALL(
657 callback_,
658 TimeToSendPacket(ssrc, sequence_number + 1, capture_time_ms + 1, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000659 .Times(1)
660 .WillOnce(Return(true));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000661 clock_.AdvanceTimeMilliseconds(10000);
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000662 send_bucket_->Process();
663 EXPECT_EQ(0, send_bucket_->QueueInMs());
664}
665
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000666TEST_F(PacedSenderTest, ExpectedQueueTimeMs) {
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000667 uint32_t ssrc = 12346;
668 uint16_t sequence_number = 1234;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000669 const size_t kNumPackets = 60;
670 const size_t kPacketSize = 1200;
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000671 const int32_t kMaxBitrate = kPaceMultiplier * 30;
672 EXPECT_EQ(0, send_bucket_->ExpectedQueueTimeMs());
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000673
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000674 send_bucket_->UpdateBitrate(30, kMaxBitrate, 0);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000675 for (size_t i = 0; i < kNumPackets; ++i) {
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000676 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
677 clock_.TimeInMilliseconds(), kPacketSize, false);
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000678 }
679
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000680 // Queue in ms = 1000 * (bytes in queue) / (kbit per second * 1000 / 8)
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000681 int64_t queue_in_ms =
682 static_cast<int64_t>(kNumPackets * kPacketSize * 8 / kMaxBitrate);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000683 EXPECT_EQ(queue_in_ms, send_bucket_->ExpectedQueueTimeMs());
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000684
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000685 int64_t time_start = clock_.TimeInMilliseconds();
686 while (send_bucket_->QueueSizePackets() > 0) {
687 int time_until_process = send_bucket_->TimeUntilNextProcess();
688 if (time_until_process <= 0) {
689 send_bucket_->Process();
690 } else {
691 clock_.AdvanceTimeMilliseconds(time_until_process);
692 }
693 }
694 int64_t duration = clock_.TimeInMilliseconds() - time_start;
695
696 EXPECT_EQ(0, send_bucket_->ExpectedQueueTimeMs());
697
sprang0a43fef2015-11-20 09:00:37 -0800698 // Allow for aliasing, duration should be within one pack of max time limit.
699 EXPECT_NEAR(duration, PacedSender::kMaxQueueLengthMs,
700 static_cast<int64_t>(kPacketSize * 8 / kMaxBitrate));
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000701}
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000702
703TEST_F(PacedSenderTest, QueueTimeGrowsOverTime) {
704 uint32_t ssrc = 12346;
705 uint16_t sequence_number = 1234;
706 EXPECT_EQ(0, send_bucket_->QueueInMs());
707
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000708 send_bucket_->UpdateBitrate(30, kPaceMultiplier * 30, 0);
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000709 SendAndExpectPacket(PacedSender::kNormalPriority,
710 ssrc,
711 sequence_number,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000712 clock_.TimeInMilliseconds(),
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000713 1200,
714 false);
715
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000716 clock_.AdvanceTimeMilliseconds(500);
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000717 EXPECT_EQ(500, send_bucket_->QueueInMs());
718 send_bucket_->Process();
719 EXPECT_EQ(0, send_bucket_->QueueInMs());
720}
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000721
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000722TEST_F(PacedSenderTest, ProbingWithInitialFrame) {
stefan@webrtc.orgd839e0a2014-11-04 19:33:55 +0000723 const int kNumPackets = 11;
724 const int kNumDeltas = kNumPackets - 1;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000725 const size_t kPacketSize = 1200;
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000726 const int kInitialBitrateKbps = 300;
727 uint32_t ssrc = 12346;
728 uint16_t sequence_number = 1234;
stefan0665f052016-02-24 03:04:17 -0800729 const int expected_deltas[kNumDeltas] = {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,
stefan0665f052016-02-24 03:04:17 -0800731 expected_deltas + kNumDeltas);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000732 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,
stefan0665f052016-02-24 03:04:17 -0800764 expected_deltas + kNumDeltas);
Stefan Holmer01b48882015-05-05 10:21:24 +0200765 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