blob: 4410377e5f8da9b9dd7bc98dbc437f8c89663630 [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
perkjec81bcd2016-05-11 06:01:13 -070025static const int kTargetBitrateBps = 800000;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000026
perkjec81bcd2016-05-11 06:01:13 -070027class MockPacedSenderCallback : public PacedSender::PacketSender {
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000028 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
perkjec81bcd2016-05-11 06:01:13 -070038class PacedSenderPadding : public PacedSender::PacketSender {
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000039 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
perkjec81bcd2016-05-11 06:01:13 -070062class PacedSenderProbing : public PacedSender::PacketSender {
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000063 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.
perkjec81bcd2016-05-11 06:01:13 -0700110 send_bucket_.reset(new PacedSender(&clock_, &callback_));
stefan@webrtc.orge9f0f592015-02-16 15:47:51 +0000111 // Default to bitrate probing disabled for testing purposes. Probing tests
112 // have to enable probing, either by creating a new PacedSender instance or
113 // by calling SetProbingEnabled(true).
114 send_bucket_->SetProbingEnabled(false);
perkjec81bcd2016-05-11 06:01:13 -0700115 send_bucket_->SetEstimatedBitrate(kTargetBitrateBps);
116
117 clock_.AdvanceTimeMilliseconds(send_bucket_->TimeUntilNextProcess());
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000118 }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000119
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000120 void SendAndExpectPacket(PacedSender::Priority priority,
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000121 uint32_t ssrc,
122 uint16_t sequence_number,
123 int64_t capture_time_ms,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000124 size_t size,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000125 bool retransmission) {
Peter Boströme23e7372015-10-08 11:44:14 +0200126 send_bucket_->InsertPacket(priority, ssrc, sequence_number, capture_time_ms,
127 size, retransmission);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000128 EXPECT_CALL(callback_,
129 TimeToSendPacket(ssrc, sequence_number, capture_time_ms, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000130 .Times(1)
131 .WillRepeatedly(Return(true));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000132 }
133
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000134 SimulatedClock clock_;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000135 MockPacedSenderCallback callback_;
kwiberg22feaa32016-03-17 09:17:43 -0700136 std::unique_ptr<PacedSender> send_bucket_;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000137};
138
139TEST_F(PacedSenderTest, QueuePacket) {
140 uint32_t ssrc = 12345;
141 uint16_t sequence_number = 1234;
perkjec81bcd2016-05-11 06:01:13 -0700142 // Due to the multiplicative factor we can send 5 packets during a send
143 // interval. (network capacity * multiplier / (8 bits per byte *
144 // (packet size * #send intervals per second)
145 const size_t packets_to_send =
146 kTargetBitrateBps * PacedSender::kDefaultPaceMultiplier / (8 * 250 * 200);
147 for (size_t i = 0; i < packets_to_send; ++i) {
148 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
149 clock_.TimeInMilliseconds(), 250, false);
150 }
151
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000152 int64_t queued_packet_timestamp = clock_.TimeInMilliseconds();
Peter Boströme23e7372015-10-08 11:44:14 +0200153 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
154 sequence_number, queued_packet_timestamp, 250,
155 false);
perkjec81bcd2016-05-11 06:01:13 -0700156 EXPECT_EQ(packets_to_send + 1, send_bucket_->QueueSizePackets());
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000157 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000158 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000159 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000160 clock_.AdvanceTimeMilliseconds(4);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000161 EXPECT_EQ(1, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000162 clock_.AdvanceTimeMilliseconds(1);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000163 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
perkjec81bcd2016-05-11 06:01:13 -0700164 EXPECT_EQ(1u, send_bucket_->QueueSizePackets());
165 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number,
166 queued_packet_timestamp, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000167 .Times(1)
168 .WillRepeatedly(Return(true));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000169 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000170 sequence_number++;
perkjec81bcd2016-05-11 06:01:13 -0700171 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
172
173 // We can send packets_to_send -1 packets of size 250 during the current
174 // interval since one packet has already been sent.
175 for (size_t i = 0; i < packets_to_send - 1; ++i) {
176 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
177 clock_.TimeInMilliseconds(), 250, false);
178 }
Peter Boströme23e7372015-10-08 11:44:14 +0200179 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
180 sequence_number++, clock_.TimeInMilliseconds(),
181 250, false);
perkjec81bcd2016-05-11 06:01:13 -0700182 EXPECT_EQ(packets_to_send, send_bucket_->QueueSizePackets());
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000183 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700184 EXPECT_EQ(1u, send_bucket_->QueueSizePackets());
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000185}
186
187TEST_F(PacedSenderTest, PaceQueuedPackets) {
188 uint32_t ssrc = 12345;
189 uint16_t sequence_number = 1234;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000190
perkjec81bcd2016-05-11 06:01:13 -0700191 // Due to the multiplicative factor we can send 5 packets during a send
192 // interval. (network capacity * multiplier / (8 bits per byte *
193 // (packet size * #send intervals per second)
194 const size_t packets_to_send_per_interval =
195 kTargetBitrateBps * PacedSender::kDefaultPaceMultiplier / (8 * 250 * 200);
196 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
197 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
198 clock_.TimeInMilliseconds(), 250, false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000199 }
perkjec81bcd2016-05-11 06:01:13 -0700200
201 for (size_t j = 0; j < packets_to_send_per_interval * 10; ++j) {
Peter Boströme23e7372015-10-08 11:44:14 +0200202 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
203 sequence_number++, clock_.TimeInMilliseconds(),
204 250, false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000205 }
perkjec81bcd2016-05-11 06:01:13 -0700206 EXPECT_EQ(packets_to_send_per_interval + packets_to_send_per_interval * 10,
207 send_bucket_->QueueSizePackets());
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000208 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700209 EXPECT_EQ(packets_to_send_per_interval * 10,
210 send_bucket_->QueueSizePackets());
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000211 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000212 for (int k = 0; k < 10; ++k) {
213 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000214 clock_.AdvanceTimeMilliseconds(5);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000215 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, _, _, false))
perkjec81bcd2016-05-11 06:01:13 -0700216 .Times(packets_to_send_per_interval)
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000217 .WillRepeatedly(Return(true));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000218 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800219 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000220 }
perkjec81bcd2016-05-11 06:01:13 -0700221 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000222 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000223 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000224 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
perkjec81bcd2016-05-11 06:01:13 -0700225 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
pbosa26ac922016-02-25 04:50:01 -0800226 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700227
228 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
229 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
230 clock_.TimeInMilliseconds(), 250, false);
231 }
Peter Boströme23e7372015-10-08 11:44:14 +0200232 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
233 sequence_number, clock_.TimeInMilliseconds(), 250,
234 false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000235 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700236 EXPECT_EQ(1u, send_bucket_->QueueSizePackets());
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000237}
238
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000239TEST_F(PacedSenderTest, PaceQueuedPacketsWithDuplicates) {
240 uint32_t ssrc = 12345;
241 uint16_t sequence_number = 1234;
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000242 uint16_t queued_sequence_number;
243
perkjec81bcd2016-05-11 06:01:13 -0700244 // Due to the multiplicative factor we can send 5 packets during a send
245 // interval. (network capacity * multiplier / (8 bits per byte *
246 // (packet size * #send intervals per second)
247 const size_t packets_to_send_per_interval =
248 kTargetBitrateBps * PacedSender::kDefaultPaceMultiplier / (8 * 250 * 200);
249 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
250 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
251 clock_.TimeInMilliseconds(), 250, false);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000252 }
253 queued_sequence_number = sequence_number;
254
perkjec81bcd2016-05-11 06:01:13 -0700255 for (size_t j = 0; j < packets_to_send_per_interval * 10; ++j) {
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000256 // Send in duplicate packets.
Peter Boströme23e7372015-10-08 11:44:14 +0200257 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
258 sequence_number, clock_.TimeInMilliseconds(),
259 250, false);
260 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
261 sequence_number++, clock_.TimeInMilliseconds(),
262 250, false);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000263 }
264 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000265 send_bucket_->Process();
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000266 for (int k = 0; k < 10; ++k) {
267 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000268 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000269
perkjec81bcd2016-05-11 06:01:13 -0700270 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000271 EXPECT_CALL(callback_,
272 TimeToSendPacket(ssrc, queued_sequence_number++, _, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000273 .Times(1)
274 .WillRepeatedly(Return(true));
jbauchd2a22962016-02-08 23:18:25 -0800275 }
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000276 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800277 send_bucket_->Process();
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000278 }
279 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000280 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000281 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800282 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700283
284 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
285 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
286 clock_.TimeInMilliseconds(), 250, false);
287 }
Peter Boströme23e7372015-10-08 11:44:14 +0200288 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
289 sequence_number++, clock_.TimeInMilliseconds(),
290 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000291 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700292 EXPECT_EQ(1u, send_bucket_->QueueSizePackets());
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000293}
294
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000295TEST_F(PacedSenderTest, CanQueuePacketsWithSameSequenceNumberOnDifferentSsrcs) {
296 uint32_t ssrc = 12345;
297 uint16_t sequence_number = 1234;
298
299 SendAndExpectPacket(PacedSender::kNormalPriority,
300 ssrc,
301 sequence_number,
302 clock_.TimeInMilliseconds(),
303 250,
304 false);
305
306 // Expect packet on second ssrc to be queued and sent as well.
307 SendAndExpectPacket(PacedSender::kNormalPriority,
308 ssrc + 1,
309 sequence_number,
310 clock_.TimeInMilliseconds(),
311 250,
312 false);
313
314 clock_.AdvanceTimeMilliseconds(1000);
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000315 send_bucket_->Process();
316}
317
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000318TEST_F(PacedSenderTest, Padding) {
319 uint32_t ssrc = 12345;
320 uint16_t sequence_number = 1234;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000321
perkjec81bcd2016-05-11 06:01:13 -0700322 send_bucket_->SetEstimatedBitrate(kTargetBitrateBps);
323 send_bucket_->SetAllocatedSendBitrate(kTargetBitrateBps, kTargetBitrateBps);
324
325 // Due to the multiplicative factor we can send 5 packets during a send
326 // interval. (network capacity * multiplier / (8 bits per byte *
327 // (packet size * #send intervals per second)
328 const size_t packets_to_send_per_interval =
329 kTargetBitrateBps * PacedSender::kDefaultPaceMultiplier / (8 * 250 * 200);
330 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
331 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
332 clock_.TimeInMilliseconds(), 250, false);
333 }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000334 // No padding is expected since we have sent too much already.
335 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
perkjec81bcd2016-05-11 06:01:13 -0700336 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
337 send_bucket_->Process();
338 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
339
340 // 5 milliseconds later should not send padding since we filled the buffers
341 // initially.
342 EXPECT_CALL(callback_, TimeToSendPadding(250)).Times(0);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000343 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000344 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000345 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800346 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000347
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000348 // 5 milliseconds later we have enough budget to send some padding.
349 EXPECT_CALL(callback_, TimeToSendPadding(250)).Times(1).
350 WillOnce(Return(250));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000351 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000352 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000353 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800354 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000355}
356
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000357TEST_F(PacedSenderTest, VerifyPaddingUpToBitrate) {
358 uint32_t ssrc = 12345;
359 uint16_t sequence_number = 1234;
360 int64_t capture_time_ms = 56789;
361 const int kTimeStep = 5;
362 const int64_t kBitrateWindow = 100;
perkjec81bcd2016-05-11 06:01:13 -0700363 send_bucket_->SetEstimatedBitrate(kTargetBitrateBps);
364 send_bucket_->SetAllocatedSendBitrate(kTargetBitrateBps, kTargetBitrateBps);
365
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000366 int64_t start_time = clock_.TimeInMilliseconds();
367 while (clock_.TimeInMilliseconds() - start_time < kBitrateWindow) {
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000368 SendAndExpectPacket(PacedSender::kNormalPriority,
369 ssrc,
370 sequence_number++,
371 capture_time_ms,
372 250,
373 false);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000374 EXPECT_CALL(callback_, TimeToSendPadding(250)).Times(1).
375 WillOnce(Return(250));
376 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700377 clock_.AdvanceTimeMilliseconds(kTimeStep);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000378 }
379}
380
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000381TEST_F(PacedSenderTest, VerifyAverageBitrateVaryingMediaPayload) {
382 uint32_t ssrc = 12345;
383 uint16_t sequence_number = 1234;
384 int64_t capture_time_ms = 56789;
385 const int kTimeStep = 5;
386 const int64_t kBitrateWindow = 10000;
387 PacedSenderPadding callback;
perkjec81bcd2016-05-11 06:01:13 -0700388 send_bucket_.reset(new PacedSender(&clock_, &callback));
stefan@webrtc.orge9f0f592015-02-16 15:47:51 +0000389 send_bucket_->SetProbingEnabled(false);
perkjec81bcd2016-05-11 06:01:13 -0700390 send_bucket_->SetEstimatedBitrate(kTargetBitrateBps);
391 send_bucket_->SetAllocatedSendBitrate(kTargetBitrateBps, kTargetBitrateBps);
392
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000393 int64_t start_time = clock_.TimeInMilliseconds();
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000394 size_t media_bytes = 0;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000395 while (clock_.TimeInMilliseconds() - start_time < kBitrateWindow) {
jbauchd2a22962016-02-08 23:18:25 -0800396 int rand_value = rand(); // NOLINT (rand_r instead of rand)
397 size_t media_payload = rand_value % 100 + 200; // [200, 300] bytes.
Peter Boströme23e7372015-10-08 11:44:14 +0200398 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
399 sequence_number++, capture_time_ms,
400 media_payload, false);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000401 media_bytes += media_payload;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000402 clock_.AdvanceTimeMilliseconds(kTimeStep);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000403 send_bucket_->Process();
404 }
perkjec81bcd2016-05-11 06:01:13 -0700405 EXPECT_NEAR(kTargetBitrateBps / 1000,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000406 static_cast<int>(8 * (media_bytes + callback.padding_sent()) /
perkjec81bcd2016-05-11 06:01:13 -0700407 kBitrateWindow),
408 1);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000409}
410
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000411TEST_F(PacedSenderTest, Priority) {
412 uint32_t ssrc_low_priority = 12345;
413 uint32_t ssrc = 12346;
414 uint16_t sequence_number = 1234;
415 int64_t capture_time_ms = 56789;
416 int64_t capture_time_ms_low_priority = 1234567;
417
perkjec81bcd2016-05-11 06:01:13 -0700418 // Due to the multiplicative factor we can send 5 packets during a send
419 // interval. (network capacity * multiplier / (8 bits per byte *
420 // (packet size * #send intervals per second)
421 const size_t packets_to_send_per_interval =
422 kTargetBitrateBps * PacedSender::kDefaultPaceMultiplier / (8 * 250 * 200);
423 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
424 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
425 clock_.TimeInMilliseconds(), 250, false);
426 }
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000427 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700428 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000429
430 // Expect normal and low priority to be queued and high to pass through.
Peter Boströme23e7372015-10-08 11:44:14 +0200431 send_bucket_->InsertPacket(PacedSender::kLowPriority, ssrc_low_priority,
432 sequence_number++, capture_time_ms_low_priority,
433 250, false);
perkjec81bcd2016-05-11 06:01:13 -0700434
435 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
436 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
437 sequence_number++, capture_time_ms, 250, false);
438 }
Peter Boströme23e7372015-10-08 11:44:14 +0200439 send_bucket_->InsertPacket(PacedSender::kHighPriority, ssrc,
440 sequence_number++, capture_time_ms, 250, false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000441
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000442 // Expect all high and normal priority to be sent out first.
443 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000444 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, _, capture_time_ms, false))
perkjec81bcd2016-05-11 06:01:13 -0700445 .Times(packets_to_send_per_interval + 1)
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000446 .WillRepeatedly(Return(true));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000447
448 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000449 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000450 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800451 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700452 EXPECT_EQ(1u, send_bucket_->QueueSizePackets());
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000453
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000454 EXPECT_CALL(callback_,
455 TimeToSendPacket(
456 ssrc_low_priority, _, capture_time_ms_low_priority, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000457 .Times(1)
458 .WillRepeatedly(Return(true));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000459
460 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000461 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000462 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800463 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000464}
465
Stefan Holmerc482eb32015-12-16 16:55:03 +0100466TEST_F(PacedSenderTest, HighPrioDoesntAffectBudget) {
467 uint32_t ssrc = 12346;
468 uint16_t sequence_number = 1234;
469 int64_t capture_time_ms = 56789;
470
471 // As high prio packets doesn't affect the budget, we should be able to send
472 // a high number of them at once.
473 for (int i = 0; i < 25; ++i) {
474 SendAndExpectPacket(PacedSender::kHighPriority, ssrc, sequence_number++,
475 capture_time_ms, 250, false);
476 }
477 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700478 // Low prio packets does affect the budget.
479 // Due to the multiplicative factor we can send 5 packets during a send
480 // interval. (network capacity * multiplier / (8 bits per byte *
481 // (packet size * #send intervals per second)
482 const size_t packets_to_send_per_interval =
483 kTargetBitrateBps * PacedSender::kDefaultPaceMultiplier / (8 * 250 * 200);
484 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
Stefan Holmerc482eb32015-12-16 16:55:03 +0100485 SendAndExpectPacket(PacedSender::kLowPriority, ssrc, sequence_number++,
perkjec81bcd2016-05-11 06:01:13 -0700486 clock_.TimeInMilliseconds(), 250, false);
Stefan Holmerc482eb32015-12-16 16:55:03 +0100487 }
488 send_bucket_->InsertPacket(PacedSender::kLowPriority, ssrc, sequence_number,
489 capture_time_ms, 250, false);
490 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
491 clock_.AdvanceTimeMilliseconds(5);
492 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700493 EXPECT_EQ(1u, send_bucket_->QueueSizePackets());
Stefan Holmerc482eb32015-12-16 16:55:03 +0100494 EXPECT_CALL(callback_,
495 TimeToSendPacket(ssrc, sequence_number++, capture_time_ms, false))
perkjec81bcd2016-05-11 06:01:13 -0700496 .Times(1)
497 .WillRepeatedly(Return(true));
Stefan Holmerc482eb32015-12-16 16:55:03 +0100498 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
499 clock_.AdvanceTimeMilliseconds(5);
500 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700501 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
Stefan Holmerc482eb32015-12-16 16:55:03 +0100502}
503
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000504TEST_F(PacedSenderTest, Pause) {
505 uint32_t ssrc_low_priority = 12345;
506 uint32_t ssrc = 12346;
507 uint16_t sequence_number = 1234;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000508 int64_t capture_time_ms = clock_.TimeInMilliseconds();
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000509
510 EXPECT_EQ(0, send_bucket_->QueueInMs());
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000511
perkjec81bcd2016-05-11 06:01:13 -0700512 // Due to the multiplicative factor we can send 5 packets during a send
513 // interval. (network capacity * multiplier / (8 bits per byte *
514 // (packet size * #send intervals per second)
515 const size_t packets_to_send_per_interval =
516 kTargetBitrateBps * PacedSender::kDefaultPaceMultiplier / (8 * 250 * 200);
517 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
518 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
519 clock_.TimeInMilliseconds(), 250, false);
520 }
521
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000522 send_bucket_->Process();
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000523
524 send_bucket_->Pause();
525
Peter Boströme23e7372015-10-08 11:44:14 +0200526 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
527 sequence_number++, capture_time_ms, 250, false);
528 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
529 sequence_number++, capture_time_ms, 250, false);
530 send_bucket_->InsertPacket(PacedSender::kHighPriority, ssrc,
531 sequence_number++, capture_time_ms, 250, false);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000532
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000533 clock_.AdvanceTimeMilliseconds(10000);
534 int64_t second_capture_time_ms = clock_.TimeInMilliseconds();
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000535
536 // Expect everything to be queued.
Peter Boströme23e7372015-10-08 11:44:14 +0200537 send_bucket_->InsertPacket(PacedSender::kLowPriority, ssrc_low_priority,
538 sequence_number++, second_capture_time_ms, 250,
539 false);
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000540
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000541 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms,
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000542 send_bucket_->QueueInMs());
543
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000544 // Expect no packet to come out while paused.
545 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000546 EXPECT_CALL(callback_, TimeToSendPacket(_, _, _, _)).Times(0);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000547
548 for (int i = 0; i < 10; ++i) {
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000549 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000550 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800551 send_bucket_->Process();
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000552 }
553 // Expect high prio packets to come out first followed by all packets in the
554 // way they were added.
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000555 EXPECT_CALL(callback_, TimeToSendPacket(_, _, capture_time_ms, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000556 .Times(3)
557 .WillRepeatedly(Return(true));
sprang0a43fef2015-11-20 09:00:37 -0800558 EXPECT_CALL(callback_, TimeToSendPacket(_, _, second_capture_time_ms, false))
559 .Times(1)
560 .WillRepeatedly(Return(true));
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000561 send_bucket_->Resume();
562
563 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000564 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000565 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800566 send_bucket_->Process();
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000567
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000568 EXPECT_EQ(0, send_bucket_->QueueInMs());
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000569}
570
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000571TEST_F(PacedSenderTest, ResendPacket) {
572 uint32_t ssrc = 12346;
573 uint16_t sequence_number = 1234;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000574 int64_t capture_time_ms = clock_.TimeInMilliseconds();
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000575 EXPECT_EQ(0, send_bucket_->QueueInMs());
576
Peter Boströme23e7372015-10-08 11:44:14 +0200577 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
578 sequence_number, capture_time_ms, 250, false);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000579 clock_.AdvanceTimeMilliseconds(1);
Peter Boströme23e7372015-10-08 11:44:14 +0200580 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
581 sequence_number + 1, capture_time_ms + 1, 250,
582 false);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000583 clock_.AdvanceTimeMilliseconds(9999);
584 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms,
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000585 send_bucket_->QueueInMs());
586 // Fails to send first packet so only one call.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000587 EXPECT_CALL(callback_,
588 TimeToSendPacket(ssrc, sequence_number, capture_time_ms, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000589 .Times(1)
590 .WillOnce(Return(false));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000591 clock_.AdvanceTimeMilliseconds(10000);
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000592 send_bucket_->Process();
593
594 // Queue remains unchanged.
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000595 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms,
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000596 send_bucket_->QueueInMs());
597
598 // Fails to send second packet.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000599 EXPECT_CALL(callback_,
600 TimeToSendPacket(ssrc, sequence_number, capture_time_ms, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000601 .Times(1)
602 .WillOnce(Return(true));
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000603 EXPECT_CALL(
604 callback_,
605 TimeToSendPacket(ssrc, sequence_number + 1, capture_time_ms + 1, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000606 .Times(1)
607 .WillOnce(Return(false));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000608 clock_.AdvanceTimeMilliseconds(10000);
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000609 send_bucket_->Process();
610
611 // Queue is reduced by 1 packet.
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000612 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms - 1,
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000613 send_bucket_->QueueInMs());
614
615 // Send second packet and queue becomes empty.
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000616 EXPECT_CALL(
617 callback_,
618 TimeToSendPacket(ssrc, sequence_number + 1, capture_time_ms + 1, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000619 .Times(1)
620 .WillOnce(Return(true));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000621 clock_.AdvanceTimeMilliseconds(10000);
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000622 send_bucket_->Process();
623 EXPECT_EQ(0, send_bucket_->QueueInMs());
624}
625
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000626TEST_F(PacedSenderTest, ExpectedQueueTimeMs) {
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000627 uint32_t ssrc = 12346;
628 uint16_t sequence_number = 1234;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000629 const size_t kNumPackets = 60;
630 const size_t kPacketSize = 1200;
perkjec81bcd2016-05-11 06:01:13 -0700631 const int32_t kMaxBitrate = PacedSender::kDefaultPaceMultiplier * 30000;
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000632 EXPECT_EQ(0, send_bucket_->ExpectedQueueTimeMs());
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000633
perkjec81bcd2016-05-11 06:01:13 -0700634 send_bucket_->SetEstimatedBitrate(30000);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000635 for (size_t i = 0; i < kNumPackets; ++i) {
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000636 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
637 clock_.TimeInMilliseconds(), kPacketSize, false);
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000638 }
639
perkjec81bcd2016-05-11 06:01:13 -0700640 // Queue in ms = 1000 * (bytes in queue) *8 / (bits per second)
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000641 int64_t queue_in_ms =
perkjec81bcd2016-05-11 06:01:13 -0700642 static_cast<int64_t>(1000 * kNumPackets * kPacketSize * 8 / kMaxBitrate);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000643 EXPECT_EQ(queue_in_ms, send_bucket_->ExpectedQueueTimeMs());
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000644
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000645 int64_t time_start = clock_.TimeInMilliseconds();
646 while (send_bucket_->QueueSizePackets() > 0) {
647 int time_until_process = send_bucket_->TimeUntilNextProcess();
648 if (time_until_process <= 0) {
649 send_bucket_->Process();
650 } else {
651 clock_.AdvanceTimeMilliseconds(time_until_process);
652 }
653 }
654 int64_t duration = clock_.TimeInMilliseconds() - time_start;
655
656 EXPECT_EQ(0, send_bucket_->ExpectedQueueTimeMs());
657
sprang0a43fef2015-11-20 09:00:37 -0800658 // Allow for aliasing, duration should be within one pack of max time limit.
659 EXPECT_NEAR(duration, PacedSender::kMaxQueueLengthMs,
perkjec81bcd2016-05-11 06:01:13 -0700660 static_cast<int64_t>(1000 * kPacketSize * 8 / kMaxBitrate));
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000661}
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000662
663TEST_F(PacedSenderTest, QueueTimeGrowsOverTime) {
664 uint32_t ssrc = 12346;
665 uint16_t sequence_number = 1234;
666 EXPECT_EQ(0, send_bucket_->QueueInMs());
667
perkjec81bcd2016-05-11 06:01:13 -0700668 send_bucket_->SetEstimatedBitrate(30000);
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000669 SendAndExpectPacket(PacedSender::kNormalPriority,
670 ssrc,
671 sequence_number,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000672 clock_.TimeInMilliseconds(),
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000673 1200,
674 false);
675
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000676 clock_.AdvanceTimeMilliseconds(500);
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000677 EXPECT_EQ(500, send_bucket_->QueueInMs());
678 send_bucket_->Process();
679 EXPECT_EQ(0, send_bucket_->QueueInMs());
680}
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000681
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000682TEST_F(PacedSenderTest, ProbingWithInitialFrame) {
stefan@webrtc.orgd839e0a2014-11-04 19:33:55 +0000683 const int kNumPackets = 11;
684 const int kNumDeltas = kNumPackets - 1;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000685 const size_t kPacketSize = 1200;
perkjec81bcd2016-05-11 06:01:13 -0700686 const int kInitialBitrateBps = 300000;
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000687 uint32_t ssrc = 12346;
688 uint16_t sequence_number = 1234;
perkjec81bcd2016-05-11 06:01:13 -0700689
stefan0665f052016-02-24 03:04:17 -0800690 const int expected_deltas[kNumDeltas] = {10, 10, 10, 10, 10, 5, 5, 5, 5, 5};
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000691 std::list<int> expected_deltas_list(expected_deltas,
stefan0665f052016-02-24 03:04:17 -0800692 expected_deltas + kNumDeltas);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000693 PacedSenderProbing callback(expected_deltas_list, &clock_);
perkjec81bcd2016-05-11 06:01:13 -0700694 send_bucket_.reset(new PacedSender(&clock_, &callback));
695 send_bucket_->SetEstimatedBitrate(kInitialBitrateBps);
stefan@webrtc.orge9f0f592015-02-16 15:47:51 +0000696
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000697 for (int i = 0; i < kNumPackets; ++i) {
Peter Boströme23e7372015-10-08 11:44:14 +0200698 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
699 sequence_number++, clock_.TimeInMilliseconds(),
700 kPacketSize, false);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000701 }
perkjec81bcd2016-05-11 06:01:13 -0700702
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000703 while (callback.packets_sent() < kNumPackets) {
704 int time_until_process = send_bucket_->TimeUntilNextProcess();
705 if (time_until_process <= 0) {
706 send_bucket_->Process();
707 } else {
708 clock_.AdvanceTimeMilliseconds(time_until_process);
709 }
710 }
711}
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000712
Stefan Holmer01b48882015-05-05 10:21:24 +0200713TEST_F(PacedSenderTest, ProbingWithTooSmallInitialFrame) {
714 const int kNumPackets = 11;
715 const int kNumDeltas = kNumPackets - 1;
716 const size_t kPacketSize = 1200;
perkjec81bcd2016-05-11 06:01:13 -0700717 const int kInitialBitrateBps = 300000;
Stefan Holmer01b48882015-05-05 10:21:24 +0200718 uint32_t ssrc = 12346;
719 uint16_t sequence_number = 1234;
720 const int expected_deltas[kNumDeltas] = {10, 10, 10, 10, 10, 5, 5, 5, 5, 5};
721 std::list<int> expected_deltas_list(expected_deltas,
stefan0665f052016-02-24 03:04:17 -0800722 expected_deltas + kNumDeltas);
Stefan Holmer01b48882015-05-05 10:21:24 +0200723 PacedSenderProbing callback(expected_deltas_list, &clock_);
perkjec81bcd2016-05-11 06:01:13 -0700724 send_bucket_.reset(new PacedSender(&clock_, &callback));
725 send_bucket_->SetEstimatedBitrate(kInitialBitrateBps);
Stefan Holmer01b48882015-05-05 10:21:24 +0200726
727 for (int i = 0; i < kNumPackets - 5; ++i) {
Peter Boströme23e7372015-10-08 11:44:14 +0200728 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
729 sequence_number++, clock_.TimeInMilliseconds(),
730 kPacketSize, false);
Stefan Holmer01b48882015-05-05 10:21:24 +0200731 }
732 while (callback.packets_sent() < kNumPackets) {
733 int time_until_process = send_bucket_->TimeUntilNextProcess();
734 if (time_until_process <= 0) {
735 send_bucket_->Process();
736 } else {
737 clock_.AdvanceTimeMilliseconds(time_until_process);
738 }
739 }
740
741 // Process one more time and make sure we don't send any more probes.
742 int time_until_process = send_bucket_->TimeUntilNextProcess();
743 clock_.AdvanceTimeMilliseconds(time_until_process);
744 send_bucket_->Process();
745 EXPECT_EQ(kNumPackets, callback.packets_sent());
746}
747
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000748TEST_F(PacedSenderTest, PriorityInversion) {
749 uint32_t ssrc = 12346;
750 uint16_t sequence_number = 1234;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000751 const size_t kPacketSize = 1200;
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000752
Peter Boströme23e7372015-10-08 11:44:14 +0200753 send_bucket_->InsertPacket(
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000754 PacedSender::kHighPriority, ssrc, sequence_number + 3,
Peter Boströme23e7372015-10-08 11:44:14 +0200755 clock_.TimeInMilliseconds() + 33, kPacketSize, true);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000756
Peter Boströme23e7372015-10-08 11:44:14 +0200757 send_bucket_->InsertPacket(
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000758 PacedSender::kHighPriority, ssrc, sequence_number + 2,
Peter Boströme23e7372015-10-08 11:44:14 +0200759 clock_.TimeInMilliseconds() + 33, kPacketSize, true);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000760
Peter Boströme23e7372015-10-08 11:44:14 +0200761 send_bucket_->InsertPacket(PacedSender::kHighPriority, ssrc, sequence_number,
762 clock_.TimeInMilliseconds(), kPacketSize, true);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000763
Peter Boströme23e7372015-10-08 11:44:14 +0200764 send_bucket_->InsertPacket(PacedSender::kHighPriority, ssrc,
765 sequence_number + 1, clock_.TimeInMilliseconds(),
766 kPacketSize, true);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000767
768 // Packets from earlier frames should be sent first.
769 {
770 ::testing::InSequence sequence;
771 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number,
772 clock_.TimeInMilliseconds(), true))
773 .WillOnce(Return(true));
774 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number + 1,
775 clock_.TimeInMilliseconds(), true))
776 .WillOnce(Return(true));
777 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number + 3,
778 clock_.TimeInMilliseconds() + 33,
779 true)).WillOnce(Return(true));
780 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number + 2,
781 clock_.TimeInMilliseconds() + 33,
782 true)).WillOnce(Return(true));
783
784 while (send_bucket_->QueueSizePackets() > 0) {
785 int time_until_process = send_bucket_->TimeUntilNextProcess();
786 if (time_until_process <= 0) {
787 send_bucket_->Process();
788 } else {
789 clock_.AdvanceTimeMilliseconds(time_until_process);
790 }
791 }
792 }
793}
794
795TEST_F(PacedSenderTest, PaddingOveruse) {
796 uint32_t ssrc = 12346;
797 uint16_t sequence_number = 1234;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000798 const size_t kPacketSize = 1200;
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000799
perkjec81bcd2016-05-11 06:01:13 -0700800 send_bucket_->Process();
801 send_bucket_->SetEstimatedBitrate(60000);
802 send_bucket_->SetAllocatedSendBitrate(60000, 0);
803
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000804 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
805 clock_.TimeInMilliseconds(), kPacketSize, false);
806 send_bucket_->Process();
807
808 // Add 30kbit padding. When increasing budget, media budget will increase from
perkjec81bcd2016-05-11 06:01:13 -0700809 // negative (overuse) while padding budget will increase from 0.
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000810 clock_.AdvanceTimeMilliseconds(5);
perkjec81bcd2016-05-11 06:01:13 -0700811 send_bucket_->SetAllocatedSendBitrate(60000, 30000);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000812
perkjec81bcd2016-05-11 06:01:13 -0700813 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
814 clock_.TimeInMilliseconds(), kPacketSize, false);
815 EXPECT_LT(5u, send_bucket_->ExpectedQueueTimeMs());
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000816 // Don't send padding if queue is non-empty, even if padding budget > 0.
817 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
818 send_bucket_->Process();
819}
820
Erik Språngad113e52015-11-26 16:26:12 +0100821TEST_F(PacedSenderTest, AverageQueueTime) {
822 uint32_t ssrc = 12346;
823 uint16_t sequence_number = 1234;
824 const size_t kPacketSize = 1200;
825 const int kBitrateBps = 10 * kPacketSize * 8; // 10 packets per second.
Erik Språngad113e52015-11-26 16:26:12 +0100826
perkjec81bcd2016-05-11 06:01:13 -0700827 send_bucket_->SetEstimatedBitrate(kBitrateBps);
Erik Språngad113e52015-11-26 16:26:12 +0100828
829 EXPECT_EQ(0, send_bucket_->AverageQueueTimeMs());
830
831 int64_t first_capture_time = clock_.TimeInMilliseconds();
Stefan Holmerc482eb32015-12-16 16:55:03 +0100832 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
833 sequence_number, first_capture_time, kPacketSize,
834 false);
Erik Språngad113e52015-11-26 16:26:12 +0100835 clock_.AdvanceTimeMilliseconds(10);
Stefan Holmerc482eb32015-12-16 16:55:03 +0100836 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
Erik Språngad113e52015-11-26 16:26:12 +0100837 sequence_number + 1, clock_.TimeInMilliseconds(),
838 kPacketSize, false);
839 clock_.AdvanceTimeMilliseconds(10);
840
841 EXPECT_EQ((20 + 10) / 2, send_bucket_->AverageQueueTimeMs());
842
843 // Only first packet (queued for 20ms) should be removed, leave the second
844 // packet (queued for 10ms) alone in the queue.
845 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number,
846 first_capture_time, false))
847 .Times(1)
848 .WillRepeatedly(Return(true));
849 send_bucket_->Process();
850
851 EXPECT_EQ(10, send_bucket_->AverageQueueTimeMs());
852
853 clock_.AdvanceTimeMilliseconds(10);
854 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number + 1,
855 first_capture_time + 10, false))
856 .Times(1)
857 .WillRepeatedly(Return(true));
858 for (int i = 0; i < 3; ++i) {
859 clock_.AdvanceTimeMilliseconds(30); // Max delta.
860 send_bucket_->Process();
861 }
862
863 EXPECT_EQ(0, send_bucket_->AverageQueueTimeMs());
864}
865
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000866} // namespace test
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000867} // namespace webrtc