blob: 6a0a006c32600f5bfe0489da183d3957d45b9e34 [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:
philipel29dca2c2016-05-13 11:13:05 +020029 MOCK_METHOD5(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,
philipel29dca2c2016-05-13 11:13:05 +020033 bool retransmission,
34 int probe_cluster_id));
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
perkjec81bcd2016-05-11 06:01:13 -070039class PacedSenderPadding : public PacedSender::PacketSender {
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000040 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,
philipel29dca2c2016-05-13 11:13:05 +020046 bool retransmission,
47 int probe_cluster_id) override {
hclam@chromium.org2e402ce2013-06-20 20:18:31 +000048 return true;
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000049 }
50
philipel29dca2c2016-05-13 11:13:05 +020051 size_t TimeToSendPadding(size_t bytes) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000052 const size_t kPaddingPacketSize = 224;
53 size_t num_packets = (bytes + kPaddingPacketSize - 1) / kPaddingPacketSize;
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000054 padding_sent_ += kPaddingPacketSize * num_packets;
55 return kPaddingPacketSize * num_packets;
56 }
57
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000058 size_t padding_sent() { return padding_sent_; }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000059
60 private:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000061 size_t padding_sent_;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000062};
63
perkjec81bcd2016-05-11 06:01:13 -070064class PacedSenderProbing : public PacedSender::PacketSender {
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000065 public:
66 PacedSenderProbing(const std::list<int>& expected_deltas, Clock* clock)
67 : prev_packet_time_ms_(-1),
68 expected_deltas_(expected_deltas),
69 packets_sent_(0),
70 clock_(clock) {}
71
72 bool TimeToSendPacket(uint32_t ssrc,
73 uint16_t sequence_number,
74 int64_t capture_time_ms,
philipel29dca2c2016-05-13 11:13:05 +020075 bool retransmission,
76 int probe_cluster_id) override {
Stefan Holmer01b48882015-05-05 10:21:24 +020077 ExpectAndCountPacket();
78 return true;
79 }
80
philipel29dca2c2016-05-13 11:13:05 +020081 size_t TimeToSendPadding(size_t bytes) override {
Stefan Holmer01b48882015-05-05 10:21:24 +020082 ExpectAndCountPacket();
83 return bytes;
84 }
85
86 void ExpectAndCountPacket() {
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000087 ++packets_sent_;
88 EXPECT_FALSE(expected_deltas_.empty());
89 if (expected_deltas_.empty())
Stefan Holmer01b48882015-05-05 10:21:24 +020090 return;
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000091 int64_t now_ms = clock_->TimeInMilliseconds();
92 if (prev_packet_time_ms_ >= 0) {
93 EXPECT_EQ(expected_deltas_.front(), now_ms - prev_packet_time_ms_);
94 expected_deltas_.pop_front();
95 }
96 prev_packet_time_ms_ = now_ms;
stefan@webrtc.org82462aa2014-10-23 11:57:05 +000097 }
98
99 int packets_sent() const { return packets_sent_; }
100
101 private:
102 int64_t prev_packet_time_ms_;
103 std::list<int> expected_deltas_;
104 int packets_sent_;
105 Clock* clock_;
106};
107
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000108class PacedSenderTest : public ::testing::Test {
109 protected:
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000110 PacedSenderTest() : clock_(123456) {
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000111 srand(0);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000112 // Need to initialize PacedSender after we initialize clock.
perkjec81bcd2016-05-11 06:01:13 -0700113 send_bucket_.reset(new PacedSender(&clock_, &callback_));
stefan@webrtc.orge9f0f592015-02-16 15:47:51 +0000114 // Default to bitrate probing disabled for testing purposes. Probing tests
115 // have to enable probing, either by creating a new PacedSender instance or
116 // by calling SetProbingEnabled(true).
117 send_bucket_->SetProbingEnabled(false);
perkjec81bcd2016-05-11 06:01:13 -0700118 send_bucket_->SetEstimatedBitrate(kTargetBitrateBps);
119
120 clock_.AdvanceTimeMilliseconds(send_bucket_->TimeUntilNextProcess());
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000121 }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000122
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000123 void SendAndExpectPacket(PacedSender::Priority priority,
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000124 uint32_t ssrc,
125 uint16_t sequence_number,
126 int64_t capture_time_ms,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000127 size_t size,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000128 bool retransmission) {
Peter Boströme23e7372015-10-08 11:44:14 +0200129 send_bucket_->InsertPacket(priority, ssrc, sequence_number, capture_time_ms,
130 size, retransmission);
philipel29dca2c2016-05-13 11:13:05 +0200131 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number,
132 capture_time_ms, false, _))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000133 .Times(1)
134 .WillRepeatedly(Return(true));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000135 }
136
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000137 SimulatedClock clock_;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000138 MockPacedSenderCallback callback_;
kwiberg22feaa32016-03-17 09:17:43 -0700139 std::unique_ptr<PacedSender> send_bucket_;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000140};
141
142TEST_F(PacedSenderTest, QueuePacket) {
143 uint32_t ssrc = 12345;
144 uint16_t sequence_number = 1234;
perkjec81bcd2016-05-11 06:01:13 -0700145 // Due to the multiplicative factor we can send 5 packets during a send
146 // interval. (network capacity * multiplier / (8 bits per byte *
147 // (packet size * #send intervals per second)
148 const size_t packets_to_send =
149 kTargetBitrateBps * PacedSender::kDefaultPaceMultiplier / (8 * 250 * 200);
150 for (size_t i = 0; i < packets_to_send; ++i) {
151 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
152 clock_.TimeInMilliseconds(), 250, false);
153 }
154
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000155 int64_t queued_packet_timestamp = clock_.TimeInMilliseconds();
Peter Boströme23e7372015-10-08 11:44:14 +0200156 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
157 sequence_number, queued_packet_timestamp, 250,
158 false);
perkjec81bcd2016-05-11 06:01:13 -0700159 EXPECT_EQ(packets_to_send + 1, send_bucket_->QueueSizePackets());
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000160 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000161 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000162 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000163 clock_.AdvanceTimeMilliseconds(4);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000164 EXPECT_EQ(1, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000165 clock_.AdvanceTimeMilliseconds(1);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000166 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
perkjec81bcd2016-05-11 06:01:13 -0700167 EXPECT_EQ(1u, send_bucket_->QueueSizePackets());
philipel29dca2c2016-05-13 11:13:05 +0200168 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number++,
169 queued_packet_timestamp, false, _))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000170 .Times(1)
171 .WillRepeatedly(Return(true));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000172 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000173 sequence_number++;
perkjec81bcd2016-05-11 06:01:13 -0700174 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
175
176 // We can send packets_to_send -1 packets of size 250 during the current
177 // interval since one packet has already been sent.
178 for (size_t i = 0; i < packets_to_send - 1; ++i) {
179 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
180 clock_.TimeInMilliseconds(), 250, false);
181 }
Peter Boströme23e7372015-10-08 11:44:14 +0200182 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
183 sequence_number++, clock_.TimeInMilliseconds(),
184 250, false);
perkjec81bcd2016-05-11 06:01:13 -0700185 EXPECT_EQ(packets_to_send, send_bucket_->QueueSizePackets());
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000186 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700187 EXPECT_EQ(1u, send_bucket_->QueueSizePackets());
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000188}
189
190TEST_F(PacedSenderTest, PaceQueuedPackets) {
191 uint32_t ssrc = 12345;
192 uint16_t sequence_number = 1234;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000193
perkjec81bcd2016-05-11 06:01:13 -0700194 // Due to the multiplicative factor we can send 5 packets during a send
195 // interval. (network capacity * multiplier / (8 bits per byte *
196 // (packet size * #send intervals per second)
197 const size_t packets_to_send_per_interval =
198 kTargetBitrateBps * PacedSender::kDefaultPaceMultiplier / (8 * 250 * 200);
199 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
200 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
201 clock_.TimeInMilliseconds(), 250, false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000202 }
perkjec81bcd2016-05-11 06:01:13 -0700203
204 for (size_t j = 0; j < packets_to_send_per_interval * 10; ++j) {
Peter Boströme23e7372015-10-08 11:44:14 +0200205 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
206 sequence_number++, clock_.TimeInMilliseconds(),
207 250, false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000208 }
perkjec81bcd2016-05-11 06:01:13 -0700209 EXPECT_EQ(packets_to_send_per_interval + packets_to_send_per_interval * 10,
210 send_bucket_->QueueSizePackets());
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000211 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700212 EXPECT_EQ(packets_to_send_per_interval * 10,
213 send_bucket_->QueueSizePackets());
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000214 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000215 for (int k = 0; k < 10; ++k) {
216 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000217 clock_.AdvanceTimeMilliseconds(5);
philipel29dca2c2016-05-13 11:13:05 +0200218 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, _, _, false, _))
perkjec81bcd2016-05-11 06:01:13 -0700219 .Times(packets_to_send_per_interval)
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000220 .WillRepeatedly(Return(true));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000221 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800222 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000223 }
perkjec81bcd2016-05-11 06:01:13 -0700224 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000225 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000226 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000227 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
perkjec81bcd2016-05-11 06:01:13 -0700228 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
pbosa26ac922016-02-25 04:50:01 -0800229 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700230
231 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
232 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
233 clock_.TimeInMilliseconds(), 250, false);
234 }
Peter Boströme23e7372015-10-08 11:44:14 +0200235 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
236 sequence_number, clock_.TimeInMilliseconds(), 250,
237 false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000238 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700239 EXPECT_EQ(1u, send_bucket_->QueueSizePackets());
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000240}
241
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000242TEST_F(PacedSenderTest, PaceQueuedPacketsWithDuplicates) {
243 uint32_t ssrc = 12345;
244 uint16_t sequence_number = 1234;
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000245 uint16_t queued_sequence_number;
246
perkjec81bcd2016-05-11 06:01:13 -0700247 // Due to the multiplicative factor we can send 5 packets during a send
248 // interval. (network capacity * multiplier / (8 bits per byte *
249 // (packet size * #send intervals per second)
250 const size_t packets_to_send_per_interval =
251 kTargetBitrateBps * PacedSender::kDefaultPaceMultiplier / (8 * 250 * 200);
252 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
253 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
254 clock_.TimeInMilliseconds(), 250, false);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000255 }
256 queued_sequence_number = sequence_number;
257
perkjec81bcd2016-05-11 06:01:13 -0700258 for (size_t j = 0; j < packets_to_send_per_interval * 10; ++j) {
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000259 // Send in duplicate packets.
Peter Boströme23e7372015-10-08 11:44:14 +0200260 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
261 sequence_number, clock_.TimeInMilliseconds(),
262 250, false);
263 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
264 sequence_number++, clock_.TimeInMilliseconds(),
265 250, false);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000266 }
267 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000268 send_bucket_->Process();
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000269 for (int k = 0; k < 10; ++k) {
270 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000271 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000272
perkjec81bcd2016-05-11 06:01:13 -0700273 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000274 EXPECT_CALL(callback_,
philipel29dca2c2016-05-13 11:13:05 +0200275 TimeToSendPacket(ssrc, queued_sequence_number++, _, false, _))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000276 .Times(1)
277 .WillRepeatedly(Return(true));
jbauchd2a22962016-02-08 23:18:25 -0800278 }
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000279 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800280 send_bucket_->Process();
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000281 }
282 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000283 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000284 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800285 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700286
287 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
288 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
289 clock_.TimeInMilliseconds(), 250, false);
290 }
Peter Boströme23e7372015-10-08 11:44:14 +0200291 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
292 sequence_number++, clock_.TimeInMilliseconds(),
293 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000294 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700295 EXPECT_EQ(1u, send_bucket_->QueueSizePackets());
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000296}
297
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000298TEST_F(PacedSenderTest, CanQueuePacketsWithSameSequenceNumberOnDifferentSsrcs) {
299 uint32_t ssrc = 12345;
300 uint16_t sequence_number = 1234;
301
302 SendAndExpectPacket(PacedSender::kNormalPriority,
303 ssrc,
304 sequence_number,
305 clock_.TimeInMilliseconds(),
306 250,
307 false);
308
309 // Expect packet on second ssrc to be queued and sent as well.
310 SendAndExpectPacket(PacedSender::kNormalPriority,
311 ssrc + 1,
312 sequence_number,
313 clock_.TimeInMilliseconds(),
314 250,
315 false);
316
317 clock_.AdvanceTimeMilliseconds(1000);
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000318 send_bucket_->Process();
319}
320
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000321TEST_F(PacedSenderTest, Padding) {
322 uint32_t ssrc = 12345;
323 uint16_t sequence_number = 1234;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000324
perkjec81bcd2016-05-11 06:01:13 -0700325 send_bucket_->SetEstimatedBitrate(kTargetBitrateBps);
326 send_bucket_->SetAllocatedSendBitrate(kTargetBitrateBps, kTargetBitrateBps);
327
328 // Due to the multiplicative factor we can send 5 packets during a send
329 // interval. (network capacity * multiplier / (8 bits per byte *
330 // (packet size * #send intervals per second)
331 const size_t packets_to_send_per_interval =
332 kTargetBitrateBps * PacedSender::kDefaultPaceMultiplier / (8 * 250 * 200);
333 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
334 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
335 clock_.TimeInMilliseconds(), 250, false);
336 }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000337 // No padding is expected since we have sent too much already.
338 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
perkjec81bcd2016-05-11 06:01:13 -0700339 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
340 send_bucket_->Process();
341 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
342
343 // 5 milliseconds later should not send padding since we filled the buffers
344 // initially.
345 EXPECT_CALL(callback_, TimeToSendPadding(250)).Times(0);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000346 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000347 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000348 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800349 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000350
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000351 // 5 milliseconds later we have enough budget to send some padding.
352 EXPECT_CALL(callback_, TimeToSendPadding(250)).Times(1).
353 WillOnce(Return(250));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000354 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000355 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000356 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800357 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000358}
359
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000360TEST_F(PacedSenderTest, VerifyPaddingUpToBitrate) {
361 uint32_t ssrc = 12345;
362 uint16_t sequence_number = 1234;
363 int64_t capture_time_ms = 56789;
364 const int kTimeStep = 5;
365 const int64_t kBitrateWindow = 100;
perkjec81bcd2016-05-11 06:01:13 -0700366 send_bucket_->SetEstimatedBitrate(kTargetBitrateBps);
367 send_bucket_->SetAllocatedSendBitrate(kTargetBitrateBps, kTargetBitrateBps);
368
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000369 int64_t start_time = clock_.TimeInMilliseconds();
370 while (clock_.TimeInMilliseconds() - start_time < kBitrateWindow) {
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000371 SendAndExpectPacket(PacedSender::kNormalPriority,
372 ssrc,
373 sequence_number++,
374 capture_time_ms,
375 250,
376 false);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000377 EXPECT_CALL(callback_, TimeToSendPadding(250)).Times(1).
378 WillOnce(Return(250));
379 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700380 clock_.AdvanceTimeMilliseconds(kTimeStep);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000381 }
382}
383
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000384TEST_F(PacedSenderTest, VerifyAverageBitrateVaryingMediaPayload) {
385 uint32_t ssrc = 12345;
386 uint16_t sequence_number = 1234;
387 int64_t capture_time_ms = 56789;
388 const int kTimeStep = 5;
389 const int64_t kBitrateWindow = 10000;
390 PacedSenderPadding callback;
perkjec81bcd2016-05-11 06:01:13 -0700391 send_bucket_.reset(new PacedSender(&clock_, &callback));
stefan@webrtc.orge9f0f592015-02-16 15:47:51 +0000392 send_bucket_->SetProbingEnabled(false);
perkjec81bcd2016-05-11 06:01:13 -0700393 send_bucket_->SetEstimatedBitrate(kTargetBitrateBps);
394 send_bucket_->SetAllocatedSendBitrate(kTargetBitrateBps, kTargetBitrateBps);
395
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000396 int64_t start_time = clock_.TimeInMilliseconds();
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000397 size_t media_bytes = 0;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000398 while (clock_.TimeInMilliseconds() - start_time < kBitrateWindow) {
jbauchd2a22962016-02-08 23:18:25 -0800399 int rand_value = rand(); // NOLINT (rand_r instead of rand)
400 size_t media_payload = rand_value % 100 + 200; // [200, 300] bytes.
Peter Boströme23e7372015-10-08 11:44:14 +0200401 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
402 sequence_number++, capture_time_ms,
403 media_payload, false);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000404 media_bytes += media_payload;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000405 clock_.AdvanceTimeMilliseconds(kTimeStep);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000406 send_bucket_->Process();
407 }
perkjec81bcd2016-05-11 06:01:13 -0700408 EXPECT_NEAR(kTargetBitrateBps / 1000,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000409 static_cast<int>(8 * (media_bytes + callback.padding_sent()) /
perkjec81bcd2016-05-11 06:01:13 -0700410 kBitrateWindow),
411 1);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000412}
413
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000414TEST_F(PacedSenderTest, Priority) {
415 uint32_t ssrc_low_priority = 12345;
416 uint32_t ssrc = 12346;
417 uint16_t sequence_number = 1234;
418 int64_t capture_time_ms = 56789;
419 int64_t capture_time_ms_low_priority = 1234567;
420
perkjec81bcd2016-05-11 06:01:13 -0700421 // Due to the multiplicative factor we can send 5 packets during a send
422 // interval. (network capacity * multiplier / (8 bits per byte *
423 // (packet size * #send intervals per second)
424 const size_t packets_to_send_per_interval =
425 kTargetBitrateBps * PacedSender::kDefaultPaceMultiplier / (8 * 250 * 200);
426 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
427 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
428 clock_.TimeInMilliseconds(), 250, false);
429 }
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000430 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700431 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000432
433 // Expect normal and low priority to be queued and high to pass through.
Peter Boströme23e7372015-10-08 11:44:14 +0200434 send_bucket_->InsertPacket(PacedSender::kLowPriority, ssrc_low_priority,
435 sequence_number++, capture_time_ms_low_priority,
436 250, false);
perkjec81bcd2016-05-11 06:01:13 -0700437
438 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
439 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
440 sequence_number++, capture_time_ms, 250, false);
441 }
Peter Boströme23e7372015-10-08 11:44:14 +0200442 send_bucket_->InsertPacket(PacedSender::kHighPriority, ssrc,
443 sequence_number++, capture_time_ms, 250, false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000444
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000445 // Expect all high and normal priority to be sent out first.
446 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
philipel29dca2c2016-05-13 11:13:05 +0200447 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, _, capture_time_ms, false, _))
perkjec81bcd2016-05-11 06:01:13 -0700448 .Times(packets_to_send_per_interval + 1)
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000449 .WillRepeatedly(Return(true));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000450
451 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000452 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000453 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800454 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700455 EXPECT_EQ(1u, send_bucket_->QueueSizePackets());
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000456
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000457 EXPECT_CALL(callback_,
philipel29dca2c2016-05-13 11:13:05 +0200458 TimeToSendPacket(ssrc_low_priority, _,
459 capture_time_ms_low_priority, false, _))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000460 .Times(1)
461 .WillRepeatedly(Return(true));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000462
463 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000464 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000465 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800466 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000467}
468
Stefan Holmerc482eb32015-12-16 16:55:03 +0100469TEST_F(PacedSenderTest, HighPrioDoesntAffectBudget) {
470 uint32_t ssrc = 12346;
471 uint16_t sequence_number = 1234;
472 int64_t capture_time_ms = 56789;
473
474 // As high prio packets doesn't affect the budget, we should be able to send
475 // a high number of them at once.
476 for (int i = 0; i < 25; ++i) {
477 SendAndExpectPacket(PacedSender::kHighPriority, ssrc, sequence_number++,
478 capture_time_ms, 250, false);
479 }
480 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700481 // Low prio packets does affect the budget.
482 // Due to the multiplicative factor we can send 5 packets during a send
483 // interval. (network capacity * multiplier / (8 bits per byte *
484 // (packet size * #send intervals per second)
485 const size_t packets_to_send_per_interval =
486 kTargetBitrateBps * PacedSender::kDefaultPaceMultiplier / (8 * 250 * 200);
487 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
Stefan Holmerc482eb32015-12-16 16:55:03 +0100488 SendAndExpectPacket(PacedSender::kLowPriority, ssrc, sequence_number++,
perkjec81bcd2016-05-11 06:01:13 -0700489 clock_.TimeInMilliseconds(), 250, false);
Stefan Holmerc482eb32015-12-16 16:55:03 +0100490 }
491 send_bucket_->InsertPacket(PacedSender::kLowPriority, ssrc, sequence_number,
492 capture_time_ms, 250, false);
493 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
494 clock_.AdvanceTimeMilliseconds(5);
495 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700496 EXPECT_EQ(1u, send_bucket_->QueueSizePackets());
philipel29dca2c2016-05-13 11:13:05 +0200497 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number++,
498 capture_time_ms, false, _))
perkjec81bcd2016-05-11 06:01:13 -0700499 .Times(1)
500 .WillRepeatedly(Return(true));
Stefan Holmerc482eb32015-12-16 16:55:03 +0100501 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
502 clock_.AdvanceTimeMilliseconds(5);
503 send_bucket_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700504 EXPECT_EQ(0u, send_bucket_->QueueSizePackets());
Stefan Holmerc482eb32015-12-16 16:55:03 +0100505}
506
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000507TEST_F(PacedSenderTest, Pause) {
508 uint32_t ssrc_low_priority = 12345;
509 uint32_t ssrc = 12346;
510 uint16_t sequence_number = 1234;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000511 int64_t capture_time_ms = clock_.TimeInMilliseconds();
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000512
513 EXPECT_EQ(0, send_bucket_->QueueInMs());
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000514
perkjec81bcd2016-05-11 06:01:13 -0700515 // Due to the multiplicative factor we can send 5 packets during a send
516 // interval. (network capacity * multiplier / (8 bits per byte *
517 // (packet size * #send intervals per second)
518 const size_t packets_to_send_per_interval =
519 kTargetBitrateBps * PacedSender::kDefaultPaceMultiplier / (8 * 250 * 200);
520 for (size_t i = 0; i < packets_to_send_per_interval; ++i) {
521 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
522 clock_.TimeInMilliseconds(), 250, false);
523 }
524
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000525 send_bucket_->Process();
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000526
527 send_bucket_->Pause();
528
Peter Boströme23e7372015-10-08 11:44:14 +0200529 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
530 sequence_number++, capture_time_ms, 250, false);
531 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
532 sequence_number++, capture_time_ms, 250, false);
533 send_bucket_->InsertPacket(PacedSender::kHighPriority, ssrc,
534 sequence_number++, capture_time_ms, 250, false);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000535
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000536 clock_.AdvanceTimeMilliseconds(10000);
537 int64_t second_capture_time_ms = clock_.TimeInMilliseconds();
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000538
539 // Expect everything to be queued.
Peter Boströme23e7372015-10-08 11:44:14 +0200540 send_bucket_->InsertPacket(PacedSender::kLowPriority, ssrc_low_priority,
541 sequence_number++, second_capture_time_ms, 250,
542 false);
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000543
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000544 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms,
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000545 send_bucket_->QueueInMs());
546
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000547 // Expect no packet to come out while paused.
548 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
philipel29dca2c2016-05-13 11:13:05 +0200549 EXPECT_CALL(callback_, TimeToSendPacket(_, _, _, _, _)).Times(0);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000550
551 for (int i = 0; i < 10; ++i) {
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000552 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000553 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800554 send_bucket_->Process();
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000555 }
556 // Expect high prio packets to come out first followed by all packets in the
557 // way they were added.
philipel29dca2c2016-05-13 11:13:05 +0200558 EXPECT_CALL(callback_, TimeToSendPacket(_, _, capture_time_ms, false, _))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000559 .Times(3)
560 .WillRepeatedly(Return(true));
philipel29dca2c2016-05-13 11:13:05 +0200561 EXPECT_CALL(callback_,
562 TimeToSendPacket(_, _, second_capture_time_ms, false, _))
sprang0a43fef2015-11-20 09:00:37 -0800563 .Times(1)
564 .WillRepeatedly(Return(true));
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000565 send_bucket_->Resume();
566
567 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000568 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000569 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
pbosa26ac922016-02-25 04:50:01 -0800570 send_bucket_->Process();
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000571
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000572 EXPECT_EQ(0, send_bucket_->QueueInMs());
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000573}
574
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000575TEST_F(PacedSenderTest, ResendPacket) {
576 uint32_t ssrc = 12346;
577 uint16_t sequence_number = 1234;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000578 int64_t capture_time_ms = clock_.TimeInMilliseconds();
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000579 EXPECT_EQ(0, send_bucket_->QueueInMs());
580
Peter Boströme23e7372015-10-08 11:44:14 +0200581 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
582 sequence_number, capture_time_ms, 250, false);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000583 clock_.AdvanceTimeMilliseconds(1);
Peter Boströme23e7372015-10-08 11:44:14 +0200584 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
585 sequence_number + 1, capture_time_ms + 1, 250,
586 false);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000587 clock_.AdvanceTimeMilliseconds(9999);
588 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms,
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000589 send_bucket_->QueueInMs());
590 // Fails to send first packet so only one call.
philipel29dca2c2016-05-13 11:13:05 +0200591 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number,
592 capture_time_ms, false, _))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000593 .Times(1)
594 .WillOnce(Return(false));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000595 clock_.AdvanceTimeMilliseconds(10000);
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000596 send_bucket_->Process();
597
598 // Queue remains unchanged.
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000599 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms,
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000600 send_bucket_->QueueInMs());
601
602 // Fails to send second packet.
philipel29dca2c2016-05-13 11:13:05 +0200603 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number,
604 capture_time_ms, false, _))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000605 .Times(1)
606 .WillOnce(Return(true));
philipel29dca2c2016-05-13 11:13:05 +0200607 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number + 1,
608 capture_time_ms + 1, false, _))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000609 .Times(1)
610 .WillOnce(Return(false));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000611 clock_.AdvanceTimeMilliseconds(10000);
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000612 send_bucket_->Process();
613
614 // Queue is reduced by 1 packet.
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000615 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms - 1,
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000616 send_bucket_->QueueInMs());
617
618 // Send second packet and queue becomes empty.
philipel29dca2c2016-05-13 11:13:05 +0200619 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number + 1,
620 capture_time_ms + 1, false, _))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000621 .Times(1)
622 .WillOnce(Return(true));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000623 clock_.AdvanceTimeMilliseconds(10000);
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000624 send_bucket_->Process();
625 EXPECT_EQ(0, send_bucket_->QueueInMs());
626}
627
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000628TEST_F(PacedSenderTest, ExpectedQueueTimeMs) {
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000629 uint32_t ssrc = 12346;
630 uint16_t sequence_number = 1234;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000631 const size_t kNumPackets = 60;
632 const size_t kPacketSize = 1200;
perkjec81bcd2016-05-11 06:01:13 -0700633 const int32_t kMaxBitrate = PacedSender::kDefaultPaceMultiplier * 30000;
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000634 EXPECT_EQ(0, send_bucket_->ExpectedQueueTimeMs());
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000635
perkjec81bcd2016-05-11 06:01:13 -0700636 send_bucket_->SetEstimatedBitrate(30000);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000637 for (size_t i = 0; i < kNumPackets; ++i) {
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000638 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
639 clock_.TimeInMilliseconds(), kPacketSize, false);
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000640 }
641
perkjec81bcd2016-05-11 06:01:13 -0700642 // Queue in ms = 1000 * (bytes in queue) *8 / (bits per second)
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000643 int64_t queue_in_ms =
perkjec81bcd2016-05-11 06:01:13 -0700644 static_cast<int64_t>(1000 * kNumPackets * kPacketSize * 8 / kMaxBitrate);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000645 EXPECT_EQ(queue_in_ms, send_bucket_->ExpectedQueueTimeMs());
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000646
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000647 int64_t time_start = clock_.TimeInMilliseconds();
648 while (send_bucket_->QueueSizePackets() > 0) {
649 int time_until_process = send_bucket_->TimeUntilNextProcess();
650 if (time_until_process <= 0) {
651 send_bucket_->Process();
652 } else {
653 clock_.AdvanceTimeMilliseconds(time_until_process);
654 }
655 }
656 int64_t duration = clock_.TimeInMilliseconds() - time_start;
657
658 EXPECT_EQ(0, send_bucket_->ExpectedQueueTimeMs());
659
sprang0a43fef2015-11-20 09:00:37 -0800660 // Allow for aliasing, duration should be within one pack of max time limit.
661 EXPECT_NEAR(duration, PacedSender::kMaxQueueLengthMs,
perkjec81bcd2016-05-11 06:01:13 -0700662 static_cast<int64_t>(1000 * kPacketSize * 8 / kMaxBitrate));
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000663}
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000664
665TEST_F(PacedSenderTest, QueueTimeGrowsOverTime) {
666 uint32_t ssrc = 12346;
667 uint16_t sequence_number = 1234;
668 EXPECT_EQ(0, send_bucket_->QueueInMs());
669
perkjec81bcd2016-05-11 06:01:13 -0700670 send_bucket_->SetEstimatedBitrate(30000);
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000671 SendAndExpectPacket(PacedSender::kNormalPriority,
672 ssrc,
673 sequence_number,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000674 clock_.TimeInMilliseconds(),
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000675 1200,
676 false);
677
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000678 clock_.AdvanceTimeMilliseconds(500);
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000679 EXPECT_EQ(500, send_bucket_->QueueInMs());
680 send_bucket_->Process();
681 EXPECT_EQ(0, send_bucket_->QueueInMs());
682}
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000683
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000684TEST_F(PacedSenderTest, ProbingWithInitialFrame) {
stefan@webrtc.orgd839e0a2014-11-04 19:33:55 +0000685 const int kNumPackets = 11;
686 const int kNumDeltas = kNumPackets - 1;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000687 const size_t kPacketSize = 1200;
perkjec81bcd2016-05-11 06:01:13 -0700688 const int kInitialBitrateBps = 300000;
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000689 uint32_t ssrc = 12346;
690 uint16_t sequence_number = 1234;
perkjec81bcd2016-05-11 06:01:13 -0700691
stefan0665f052016-02-24 03:04:17 -0800692 const int expected_deltas[kNumDeltas] = {10, 10, 10, 10, 10, 5, 5, 5, 5, 5};
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000693 std::list<int> expected_deltas_list(expected_deltas,
stefan0665f052016-02-24 03:04:17 -0800694 expected_deltas + kNumDeltas);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000695 PacedSenderProbing callback(expected_deltas_list, &clock_);
perkjec81bcd2016-05-11 06:01:13 -0700696 send_bucket_.reset(new PacedSender(&clock_, &callback));
697 send_bucket_->SetEstimatedBitrate(kInitialBitrateBps);
stefan@webrtc.orge9f0f592015-02-16 15:47:51 +0000698
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000699 for (int i = 0; i < kNumPackets; ++i) {
Peter Boströme23e7372015-10-08 11:44:14 +0200700 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
701 sequence_number++, clock_.TimeInMilliseconds(),
702 kPacketSize, false);
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000703 }
perkjec81bcd2016-05-11 06:01:13 -0700704
stefan@webrtc.org82462aa2014-10-23 11:57:05 +0000705 while (callback.packets_sent() < kNumPackets) {
706 int time_until_process = send_bucket_->TimeUntilNextProcess();
707 if (time_until_process <= 0) {
708 send_bucket_->Process();
709 } else {
710 clock_.AdvanceTimeMilliseconds(time_until_process);
711 }
712 }
713}
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000714
Stefan Holmer01b48882015-05-05 10:21:24 +0200715TEST_F(PacedSenderTest, ProbingWithTooSmallInitialFrame) {
716 const int kNumPackets = 11;
717 const int kNumDeltas = kNumPackets - 1;
718 const size_t kPacketSize = 1200;
perkjec81bcd2016-05-11 06:01:13 -0700719 const int kInitialBitrateBps = 300000;
Stefan Holmer01b48882015-05-05 10:21:24 +0200720 uint32_t ssrc = 12346;
721 uint16_t sequence_number = 1234;
722 const int expected_deltas[kNumDeltas] = {10, 10, 10, 10, 10, 5, 5, 5, 5, 5};
723 std::list<int> expected_deltas_list(expected_deltas,
stefan0665f052016-02-24 03:04:17 -0800724 expected_deltas + kNumDeltas);
Stefan Holmer01b48882015-05-05 10:21:24 +0200725 PacedSenderProbing callback(expected_deltas_list, &clock_);
perkjec81bcd2016-05-11 06:01:13 -0700726 send_bucket_.reset(new PacedSender(&clock_, &callback));
727 send_bucket_->SetEstimatedBitrate(kInitialBitrateBps);
Stefan Holmer01b48882015-05-05 10:21:24 +0200728
729 for (int i = 0; i < kNumPackets - 5; ++i) {
Peter Boströme23e7372015-10-08 11:44:14 +0200730 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
731 sequence_number++, clock_.TimeInMilliseconds(),
732 kPacketSize, false);
Stefan Holmer01b48882015-05-05 10:21:24 +0200733 }
734 while (callback.packets_sent() < kNumPackets) {
735 int time_until_process = send_bucket_->TimeUntilNextProcess();
736 if (time_until_process <= 0) {
737 send_bucket_->Process();
738 } else {
739 clock_.AdvanceTimeMilliseconds(time_until_process);
740 }
741 }
742
743 // Process one more time and make sure we don't send any more probes.
744 int time_until_process = send_bucket_->TimeUntilNextProcess();
745 clock_.AdvanceTimeMilliseconds(time_until_process);
746 send_bucket_->Process();
747 EXPECT_EQ(kNumPackets, callback.packets_sent());
748}
749
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000750TEST_F(PacedSenderTest, PriorityInversion) {
751 uint32_t ssrc = 12346;
752 uint16_t sequence_number = 1234;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000753 const size_t kPacketSize = 1200;
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000754
Peter Boströme23e7372015-10-08 11:44:14 +0200755 send_bucket_->InsertPacket(
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000756 PacedSender::kHighPriority, ssrc, sequence_number + 3,
Peter Boströme23e7372015-10-08 11:44:14 +0200757 clock_.TimeInMilliseconds() + 33, kPacketSize, true);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000758
Peter Boströme23e7372015-10-08 11:44:14 +0200759 send_bucket_->InsertPacket(
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000760 PacedSender::kHighPriority, ssrc, sequence_number + 2,
Peter Boströme23e7372015-10-08 11:44:14 +0200761 clock_.TimeInMilliseconds() + 33, kPacketSize, true);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000762
Peter Boströme23e7372015-10-08 11:44:14 +0200763 send_bucket_->InsertPacket(PacedSender::kHighPriority, ssrc, sequence_number,
764 clock_.TimeInMilliseconds(), kPacketSize, true);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000765
Peter Boströme23e7372015-10-08 11:44:14 +0200766 send_bucket_->InsertPacket(PacedSender::kHighPriority, ssrc,
767 sequence_number + 1, clock_.TimeInMilliseconds(),
768 kPacketSize, true);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000769
770 // Packets from earlier frames should be sent first.
771 {
772 ::testing::InSequence sequence;
philipel29dca2c2016-05-13 11:13:05 +0200773 EXPECT_CALL(callback_,
774 TimeToSendPacket(ssrc, sequence_number,
775 clock_.TimeInMilliseconds(), true, _))
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000776 .WillOnce(Return(true));
philipel29dca2c2016-05-13 11:13:05 +0200777 EXPECT_CALL(callback_,
778 TimeToSendPacket(ssrc, sequence_number + 1,
779 clock_.TimeInMilliseconds(), true, _))
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000780 .WillOnce(Return(true));
philipel29dca2c2016-05-13 11:13:05 +0200781 EXPECT_CALL(callback_,
782 TimeToSendPacket(ssrc, sequence_number + 3,
783 clock_.TimeInMilliseconds() + 33, true, _))
784 .WillOnce(Return(true));
785 EXPECT_CALL(callback_,
786 TimeToSendPacket(ssrc, sequence_number + 2,
787 clock_.TimeInMilliseconds() + 33, true, _))
788 .WillOnce(Return(true));
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000789
790 while (send_bucket_->QueueSizePackets() > 0) {
791 int time_until_process = send_bucket_->TimeUntilNextProcess();
792 if (time_until_process <= 0) {
793 send_bucket_->Process();
794 } else {
795 clock_.AdvanceTimeMilliseconds(time_until_process);
796 }
797 }
798 }
799}
800
801TEST_F(PacedSenderTest, PaddingOveruse) {
802 uint32_t ssrc = 12346;
803 uint16_t sequence_number = 1234;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000804 const size_t kPacketSize = 1200;
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000805
perkjec81bcd2016-05-11 06:01:13 -0700806 send_bucket_->Process();
807 send_bucket_->SetEstimatedBitrate(60000);
808 send_bucket_->SetAllocatedSendBitrate(60000, 0);
809
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000810 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
811 clock_.TimeInMilliseconds(), kPacketSize, false);
812 send_bucket_->Process();
813
814 // Add 30kbit padding. When increasing budget, media budget will increase from
perkjec81bcd2016-05-11 06:01:13 -0700815 // negative (overuse) while padding budget will increase from 0.
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000816 clock_.AdvanceTimeMilliseconds(5);
perkjec81bcd2016-05-11 06:01:13 -0700817 send_bucket_->SetAllocatedSendBitrate(60000, 30000);
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000818
perkjec81bcd2016-05-11 06:01:13 -0700819 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
820 clock_.TimeInMilliseconds(), kPacketSize, false);
821 EXPECT_LT(5u, send_bucket_->ExpectedQueueTimeMs());
sprang@webrtc.orgdcebf2d2014-11-04 16:27:16 +0000822 // Don't send padding if queue is non-empty, even if padding budget > 0.
823 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
824 send_bucket_->Process();
825}
826
Erik Språngad113e52015-11-26 16:26:12 +0100827TEST_F(PacedSenderTest, AverageQueueTime) {
828 uint32_t ssrc = 12346;
829 uint16_t sequence_number = 1234;
830 const size_t kPacketSize = 1200;
831 const int kBitrateBps = 10 * kPacketSize * 8; // 10 packets per second.
Erik Språngad113e52015-11-26 16:26:12 +0100832
perkjec81bcd2016-05-11 06:01:13 -0700833 send_bucket_->SetEstimatedBitrate(kBitrateBps);
Erik Språngad113e52015-11-26 16:26:12 +0100834
835 EXPECT_EQ(0, send_bucket_->AverageQueueTimeMs());
836
837 int64_t first_capture_time = clock_.TimeInMilliseconds();
Stefan Holmerc482eb32015-12-16 16:55:03 +0100838 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
839 sequence_number, first_capture_time, kPacketSize,
840 false);
Erik Språngad113e52015-11-26 16:26:12 +0100841 clock_.AdvanceTimeMilliseconds(10);
Stefan Holmerc482eb32015-12-16 16:55:03 +0100842 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
Erik Språngad113e52015-11-26 16:26:12 +0100843 sequence_number + 1, clock_.TimeInMilliseconds(),
844 kPacketSize, false);
845 clock_.AdvanceTimeMilliseconds(10);
846
847 EXPECT_EQ((20 + 10) / 2, send_bucket_->AverageQueueTimeMs());
848
849 // Only first packet (queued for 20ms) should be removed, leave the second
850 // packet (queued for 10ms) alone in the queue.
851 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number,
philipel29dca2c2016-05-13 11:13:05 +0200852 first_capture_time, false, _))
Erik Språngad113e52015-11-26 16:26:12 +0100853 .Times(1)
854 .WillRepeatedly(Return(true));
855 send_bucket_->Process();
856
857 EXPECT_EQ(10, send_bucket_->AverageQueueTimeMs());
858
859 clock_.AdvanceTimeMilliseconds(10);
860 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number + 1,
philipel29dca2c2016-05-13 11:13:05 +0200861 first_capture_time + 10, false, _))
Erik Språngad113e52015-11-26 16:26:12 +0100862 .Times(1)
863 .WillRepeatedly(Return(true));
864 for (int i = 0; i < 3; ++i) {
865 clock_.AdvanceTimeMilliseconds(30); // Max delta.
866 send_bucket_->Process();
867 }
868
869 EXPECT_EQ(0, send_bucket_->AverageQueueTimeMs());
870}
871
philipel29dca2c2016-05-13 11:13:05 +0200872TEST_F(PacedSenderTest, ProbeClusterId) {
873 uint32_t ssrc = 12346;
874 uint16_t sequence_number = 1234;
875 const size_t kPacketSize = 1200;
876
877 send_bucket_->SetProbingEnabled(true);
878 for (int i = 0; i < 11; ++i) {
879 send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc,
880 sequence_number + i, clock_.TimeInMilliseconds(),
881 kPacketSize, false);
882 }
883
884 // First probing cluster.
885 EXPECT_CALL(callback_, TimeToSendPacket(_, _, _, _, 0))
886 .Times(6)
887 .WillRepeatedly(Return(true));
888 for (int i = 0; i < 6; ++i)
889 send_bucket_->Process();
890
891 // Second probing cluster.
892 EXPECT_CALL(callback_, TimeToSendPacket(_, _, _, _, 1))
893 .Times(5)
894 .WillRepeatedly(Return(true));
895 for (int i = 0; i < 5; ++i)
896 send_bucket_->Process();
897
898 // No more probing packets.
899 EXPECT_CALL(callback_, TimeToSendPadding(_))
900 .Times(1);
901 send_bucket_->Process();
902}
903
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000904} // namespace test
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000905} // namespace webrtc