blob: 14dcdbc512f2014f181b0b1a7c10eecf3f75e480 [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
pbos@webrtc.orgdb6e3f82013-07-11 09:50:05 +000011#include "testing/gmock/include/gmock/gmock.h"
12#include "testing/gtest/include/gtest/gtest.h"
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000013
14#include "webrtc/modules/pacing/include/paced_sender.h"
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +000015#include "webrtc/system_wrappers/interface/clock.h"
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000016
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +000017using testing::_;
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000018using testing::Return;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000019
20namespace webrtc {
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +000021namespace test {
22
23static const int kTargetBitrate = 800;
pwestin@webrtc.org52b4e882013-05-02 19:02:17 +000024static const float kPaceMultiplier = 1.5f;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000025
26class MockPacedSenderCallback : public PacedSender::Callback {
27 public:
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +000028 MOCK_METHOD4(TimeToSendPacket,
29 bool(uint32_t ssrc, uint16_t sequence_number, int64_t capture_time_ms,
30 bool retransmission));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000031 MOCK_METHOD1(TimeToSendPadding,
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000032 int(int bytes));
33};
34
35class PacedSenderPadding : public PacedSender::Callback {
36 public:
37 PacedSenderPadding() : padding_sent_(0) {}
38
hclam@chromium.org2e402ce2013-06-20 20:18:31 +000039 bool TimeToSendPacket(uint32_t ssrc, uint16_t sequence_number,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +000040 int64_t capture_time_ms, bool retransmission) {
hclam@chromium.org2e402ce2013-06-20 20:18:31 +000041 return true;
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000042 }
43
44 int TimeToSendPadding(int bytes) {
45 const int kPaddingPacketSize = 224;
46 int num_packets = (bytes + kPaddingPacketSize - 1) / kPaddingPacketSize;
47 padding_sent_ += kPaddingPacketSize * num_packets;
48 return kPaddingPacketSize * num_packets;
49 }
50
51 int padding_sent() { return padding_sent_; }
52
53 private:
54 int padding_sent_;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000055};
56
57class PacedSenderTest : public ::testing::Test {
58 protected:
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +000059 PacedSenderTest() : clock_(123456) {
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000060 srand(0);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000061 // Need to initialize PacedSender after we initialize clock.
pbos@webrtc.org709e2972014-03-19 10:59:52 +000062 send_bucket_.reset(
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +000063 new PacedSender(
64 &clock_, &callback_, kPaceMultiplier * kTargetBitrate, 0));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000065 }
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +000066
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +000067 void SendAndExpectPacket(PacedSender::Priority priority,
68 uint32_t ssrc, uint16_t sequence_number,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +000069 int64_t capture_time_ms, int size,
70 bool retransmission) {
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +000071 EXPECT_FALSE(send_bucket_->SendPacket(priority, ssrc,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +000072 sequence_number, capture_time_ms, size, retransmission));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +000073 EXPECT_CALL(callback_, TimeToSendPacket(
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +000074 ssrc, sequence_number, capture_time_ms, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +000075 .Times(1)
76 .WillRepeatedly(Return(true));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +000077 }
78
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +000079 SimulatedClock clock_;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000080 MockPacedSenderCallback callback_;
81 scoped_ptr<PacedSender> send_bucket_;
82};
83
84TEST_F(PacedSenderTest, QueuePacket) {
85 uint32_t ssrc = 12345;
86 uint16_t sequence_number = 1234;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000087 // Due to the multiplicative factor we can send 3 packets not 2 packets.
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +000088 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +000089 clock_.TimeInMilliseconds(), 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +000090 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +000091 clock_.TimeInMilliseconds(), 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +000092 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +000093 clock_.TimeInMilliseconds(), 250, false);
94 int64_t queued_packet_timestamp = clock_.TimeInMilliseconds();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000095 EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc,
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +000096 sequence_number, queued_packet_timestamp, 250, false));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +000097 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +000098 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +000099 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000100 clock_.AdvanceTimeMilliseconds(4);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000101 EXPECT_EQ(1, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000102 clock_.AdvanceTimeMilliseconds(1);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000103 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000104 EXPECT_CALL(callback_, TimeToSendPacket(
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000105 ssrc, sequence_number++, queued_packet_timestamp, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000106 .Times(1)
107 .WillRepeatedly(Return(true));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000108 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000109 sequence_number++;
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000110 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000111 clock_.TimeInMilliseconds(), 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000112 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000113 clock_.TimeInMilliseconds(), 250, false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000114 EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000115 sequence_number++, clock_.TimeInMilliseconds(), 250, false));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000116 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000117}
118
119TEST_F(PacedSenderTest, PaceQueuedPackets) {
120 uint32_t ssrc = 12345;
121 uint16_t sequence_number = 1234;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000122
123 // Due to the multiplicative factor we can send 3 packets not 2 packets.
124 for (int i = 0; i < 3; ++i) {
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000125 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000126 clock_.TimeInMilliseconds(), 250, false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000127 }
128 for (int j = 0; j < 30; ++j) {
129 EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000130 sequence_number++, clock_.TimeInMilliseconds(), 250, false));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000131 }
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000132 send_bucket_->Process();
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000133 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000134 for (int k = 0; k < 10; ++k) {
135 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000136 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000137 EXPECT_CALL(callback_,
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000138 TimeToSendPacket(ssrc, _, _, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000139 .Times(3)
140 .WillRepeatedly(Return(true));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000141 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
142 EXPECT_EQ(0, send_bucket_->Process());
143 }
144 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000145 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000146 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
147 EXPECT_EQ(0, send_bucket_->Process());
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000148 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000149 clock_.TimeInMilliseconds(), 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000150 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000151 clock_.TimeInMilliseconds(), 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000152 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000153 clock_.TimeInMilliseconds(), 250, false);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000154 EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000155 sequence_number, clock_.TimeInMilliseconds(), 250, false));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000156 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000157}
158
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000159TEST_F(PacedSenderTest, PaceQueuedPacketsWithDuplicates) {
160 uint32_t ssrc = 12345;
161 uint16_t sequence_number = 1234;
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000162 uint16_t queued_sequence_number;
163
164 // Due to the multiplicative factor we can send 3 packets not 2 packets.
165 for (int i = 0; i < 3; ++i) {
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000166 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000167 clock_.TimeInMilliseconds(), 250, false);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000168 }
169 queued_sequence_number = sequence_number;
170
171 for (int j = 0; j < 30; ++j) {
172 // Send in duplicate packets.
173 EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000174 sequence_number, clock_.TimeInMilliseconds(), 250, false));
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000175 EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000176 sequence_number++, clock_.TimeInMilliseconds(), 250, false));
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000177 }
178 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000179 send_bucket_->Process();
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000180 for (int k = 0; k < 10; ++k) {
181 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000182 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000183
184 for (int i = 0; i < 3; ++i) {
185 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, queued_sequence_number++,
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000186 _,
187 false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000188 .Times(1)
189 .WillRepeatedly(Return(true));
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000190 }
191 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
192 EXPECT_EQ(0, send_bucket_->Process());
193 }
194 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000195 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000196 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
197 EXPECT_EQ(0, send_bucket_->Process());
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000198 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000199 clock_.TimeInMilliseconds(), 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000200 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000201 clock_.TimeInMilliseconds(), 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000202 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000203 clock_.TimeInMilliseconds(), 250, false);
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000204 EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000205 sequence_number++, clock_.TimeInMilliseconds(), 250, false));
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000206 send_bucket_->Process();
pwestin@webrtc.org52aa0192013-04-25 17:35:56 +0000207}
208
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000209TEST_F(PacedSenderTest, CanQueuePacketsWithSameSequenceNumberOnDifferentSsrcs) {
210 uint32_t ssrc = 12345;
211 uint16_t sequence_number = 1234;
212
213 SendAndExpectPacket(PacedSender::kNormalPriority,
214 ssrc,
215 sequence_number,
216 clock_.TimeInMilliseconds(),
217 250,
218 false);
219
220 // Expect packet on second ssrc to be queued and sent as well.
221 SendAndExpectPacket(PacedSender::kNormalPriority,
222 ssrc + 1,
223 sequence_number,
224 clock_.TimeInMilliseconds(),
225 250,
226 false);
227
228 clock_.AdvanceTimeMilliseconds(1000);
pbos@webrtc.org03c817e2014-07-07 10:20:35 +0000229 send_bucket_->Process();
230}
231
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000232TEST_F(PacedSenderTest, Padding) {
233 uint32_t ssrc = 12345;
234 uint16_t sequence_number = 1234;
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000235
pbos@webrtc.org709e2972014-03-19 10:59:52 +0000236 send_bucket_->UpdateBitrate(kPaceMultiplier * kTargetBitrate, kTargetBitrate);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000237 // Due to the multiplicative factor we can send 3 packets not 2 packets.
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000238 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000239 clock_.TimeInMilliseconds(), 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000240 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000241 clock_.TimeInMilliseconds(), 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000242 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000243 clock_.TimeInMilliseconds(), 250, false);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000244 // No padding is expected since we have sent too much already.
245 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000246 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000247 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000248 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
249 EXPECT_EQ(0, send_bucket_->Process());
250
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000251 // 5 milliseconds later we have enough budget to send some padding.
252 EXPECT_CALL(callback_, TimeToSendPadding(250)).Times(1).
253 WillOnce(Return(250));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000254 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000255 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000256 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
257 EXPECT_EQ(0, send_bucket_->Process());
258}
259
stefan@webrtc.org80865fd2013-08-09 11:31:23 +0000260TEST_F(PacedSenderTest, NoPaddingWhenDisabled) {
261 send_bucket_->SetStatus(false);
pbos@webrtc.org709e2972014-03-19 10:59:52 +0000262 send_bucket_->UpdateBitrate(kPaceMultiplier * kTargetBitrate, kTargetBitrate);
stefan@webrtc.org80865fd2013-08-09 11:31:23 +0000263 // No padding is expected since the pacer is disabled.
264 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
265 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000266 clock_.AdvanceTimeMilliseconds(5);
stefan@webrtc.org80865fd2013-08-09 11:31:23 +0000267 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
268 EXPECT_EQ(0, send_bucket_->Process());
269 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
270 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000271 clock_.AdvanceTimeMilliseconds(5);
stefan@webrtc.org80865fd2013-08-09 11:31:23 +0000272 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
273 EXPECT_EQ(0, send_bucket_->Process());
274}
275
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000276TEST_F(PacedSenderTest, VerifyPaddingUpToBitrate) {
277 uint32_t ssrc = 12345;
278 uint16_t sequence_number = 1234;
279 int64_t capture_time_ms = 56789;
280 const int kTimeStep = 5;
281 const int64_t kBitrateWindow = 100;
pbos@webrtc.org709e2972014-03-19 10:59:52 +0000282 send_bucket_->UpdateBitrate(kPaceMultiplier * kTargetBitrate, kTargetBitrate);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000283 int64_t start_time = clock_.TimeInMilliseconds();
284 while (clock_.TimeInMilliseconds() - start_time < kBitrateWindow) {
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000285 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000286 capture_time_ms, 250, false);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000287 clock_.AdvanceTimeMilliseconds(kTimeStep);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000288 EXPECT_CALL(callback_, TimeToSendPadding(250)).Times(1).
289 WillOnce(Return(250));
290 send_bucket_->Process();
291 }
292}
293
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000294TEST_F(PacedSenderTest, VerifyAverageBitrateVaryingMediaPayload) {
295 uint32_t ssrc = 12345;
296 uint16_t sequence_number = 1234;
297 int64_t capture_time_ms = 56789;
298 const int kTimeStep = 5;
299 const int64_t kBitrateWindow = 10000;
300 PacedSenderPadding callback;
pbos@webrtc.org709e2972014-03-19 10:59:52 +0000301 send_bucket_.reset(
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000302 new PacedSender(&clock_, &callback, kPaceMultiplier * kTargetBitrate, 0));
pbos@webrtc.org709e2972014-03-19 10:59:52 +0000303 send_bucket_->UpdateBitrate(kPaceMultiplier * kTargetBitrate, kTargetBitrate);
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000304 int64_t start_time = clock_.TimeInMilliseconds();
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000305 int media_bytes = 0;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000306 while (clock_.TimeInMilliseconds() - start_time < kBitrateWindow) {
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000307 int media_payload = rand() % 100 + 200; // [200, 300] bytes.
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000308 EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc,
309 sequence_number++, capture_time_ms,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000310 media_payload, false));
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000311 media_bytes += media_payload;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000312 clock_.AdvanceTimeMilliseconds(kTimeStep);
stefan@webrtc.orgc3cc3752013-06-04 09:36:56 +0000313 send_bucket_->Process();
314 }
315 EXPECT_NEAR(kTargetBitrate, 8 * (media_bytes + callback.padding_sent()) /
316 kBitrateWindow, 1);
317}
318
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000319TEST_F(PacedSenderTest, Priority) {
320 uint32_t ssrc_low_priority = 12345;
321 uint32_t ssrc = 12346;
322 uint16_t sequence_number = 1234;
323 int64_t capture_time_ms = 56789;
324 int64_t capture_time_ms_low_priority = 1234567;
325
326 // Due to the multiplicative factor we can send 3 packets not 2 packets.
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000327 SendAndExpectPacket(PacedSender::kLowPriority, ssrc, sequence_number++,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000328 capture_time_ms, 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000329 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000330 capture_time_ms, 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000331 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000332 capture_time_ms, 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000333 send_bucket_->Process();
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000334
335 // Expect normal and low priority to be queued and high to pass through.
336 EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kLowPriority,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000337 ssrc_low_priority, sequence_number++, capture_time_ms_low_priority, 250,
338 false));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000339 EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000340 ssrc, sequence_number++, capture_time_ms, 250, false));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000341 EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000342 ssrc, sequence_number++, capture_time_ms, 250, false));
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000343 EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kHighPriority,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000344 ssrc, sequence_number++, capture_time_ms, 250, false));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000345
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000346 // Expect all high and normal priority to be sent out first.
347 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000348 EXPECT_CALL(callback_, TimeToSendPacket(ssrc, _, capture_time_ms, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000349 .Times(3)
350 .WillRepeatedly(Return(true));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000351
352 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000353 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000354 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
355 EXPECT_EQ(0, send_bucket_->Process());
356
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000357 EXPECT_CALL(callback_, TimeToSendPacket(
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000358 ssrc_low_priority, _, capture_time_ms_low_priority, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000359 .Times(1)
360 .WillRepeatedly(Return(true));
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000361
362 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000363 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000364 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
365 EXPECT_EQ(0, send_bucket_->Process());
366}
367
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000368TEST_F(PacedSenderTest, Pause) {
369 uint32_t ssrc_low_priority = 12345;
370 uint32_t ssrc = 12346;
371 uint16_t sequence_number = 1234;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000372 int64_t capture_time_ms = clock_.TimeInMilliseconds();
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000373
374 EXPECT_EQ(0, send_bucket_->QueueInMs());
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000375
376 // Due to the multiplicative factor we can send 3 packets not 2 packets.
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000377 SendAndExpectPacket(PacedSender::kLowPriority, ssrc, sequence_number++,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000378 capture_time_ms, 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000379 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000380 capture_time_ms, 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000381 SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000382 capture_time_ms, 250, false);
stefan@webrtc.org8ccb9f92013-06-19 14:13:42 +0000383 send_bucket_->Process();
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000384
385 send_bucket_->Pause();
386
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000387 EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000388 ssrc, sequence_number++, capture_time_ms, 250, false));
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000389 EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000390 ssrc, sequence_number++, capture_time_ms, 250, false));
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000391 EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kHighPriority,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000392 ssrc, sequence_number++, capture_time_ms, 250, false));
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000393
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000394 clock_.AdvanceTimeMilliseconds(10000);
395 int64_t second_capture_time_ms = clock_.TimeInMilliseconds();
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000396
397 // Expect everything to be queued.
398 EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kLowPriority,
399 ssrc_low_priority, sequence_number++, second_capture_time_ms, 250,
400 false));
401
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000402 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms,
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000403 send_bucket_->QueueInMs());
404
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000405 // Expect no packet to come out while paused.
406 EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0);
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000407 EXPECT_CALL(callback_, TimeToSendPacket(_, _, _, _)).Times(0);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000408
409 for (int i = 0; i < 10; ++i) {
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000410 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000411 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
412 EXPECT_EQ(0, send_bucket_->Process());
413 }
414 // Expect high prio packets to come out first followed by all packets in the
415 // way they were added.
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000416 EXPECT_CALL(callback_, TimeToSendPacket(_, _, capture_time_ms, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000417 .Times(3)
418 .WillRepeatedly(Return(true));
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000419 send_bucket_->Resume();
420
421 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000422 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000423 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
424 EXPECT_EQ(0, send_bucket_->Process());
425
jiayl@webrtc.org9fd8d872014-02-27 22:32:40 +0000426 EXPECT_CALL(
427 callback_, TimeToSendPacket(_, _, second_capture_time_ms, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000428 .Times(1)
429 .WillRepeatedly(Return(true));
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000430 EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000431 clock_.AdvanceTimeMilliseconds(5);
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000432 EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess());
433 EXPECT_EQ(0, send_bucket_->Process());
stefan@webrtc.orgbfacda62013-03-27 16:36:01 +0000434 EXPECT_EQ(0, send_bucket_->QueueInMs());
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000435}
436
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000437TEST_F(PacedSenderTest, ResendPacket) {
438 uint32_t ssrc = 12346;
439 uint16_t sequence_number = 1234;
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000440 int64_t capture_time_ms = clock_.TimeInMilliseconds();
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000441 EXPECT_EQ(0, send_bucket_->QueueInMs());
442
443 EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority,
444 ssrc,
445 sequence_number,
446 capture_time_ms,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000447 250,
448 false));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000449 clock_.AdvanceTimeMilliseconds(1);
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000450 EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority,
451 ssrc,
452 sequence_number + 1,
453 capture_time_ms + 1,
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000454 250,
455 false));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000456 clock_.AdvanceTimeMilliseconds(9999);
457 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms,
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000458 send_bucket_->QueueInMs());
459 // Fails to send first packet so only one call.
460 EXPECT_CALL(callback_, TimeToSendPacket(
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000461 ssrc, sequence_number, capture_time_ms, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000462 .Times(1)
463 .WillOnce(Return(false));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000464 clock_.AdvanceTimeMilliseconds(10000);
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000465 send_bucket_->Process();
466
467 // Queue remains unchanged.
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000468 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms,
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000469 send_bucket_->QueueInMs());
470
471 // Fails to send second packet.
472 EXPECT_CALL(callback_, TimeToSendPacket(
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000473 ssrc, sequence_number, capture_time_ms, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000474 .Times(1)
475 .WillOnce(Return(true));
476 EXPECT_CALL(callback_, TimeToSendPacket(
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000477 ssrc, sequence_number + 1, capture_time_ms + 1, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000478 .Times(1)
479 .WillOnce(Return(false));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000480 clock_.AdvanceTimeMilliseconds(10000);
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000481 send_bucket_->Process();
482
483 // Queue is reduced by 1 packet.
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000484 EXPECT_EQ(clock_.TimeInMilliseconds() - capture_time_ms - 1,
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000485 send_bucket_->QueueInMs());
486
487 // Send second packet and queue becomes empty.
488 EXPECT_CALL(callback_, TimeToSendPacket(
stefan@webrtc.org9b82f5a2013-11-13 15:29:21 +0000489 ssrc, sequence_number + 1, capture_time_ms + 1, false))
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000490 .Times(1)
491 .WillOnce(Return(true));
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000492 clock_.AdvanceTimeMilliseconds(10000);
hclam@chromium.org2e402ce2013-06-20 20:18:31 +0000493 send_bucket_->Process();
494 EXPECT_EQ(0, send_bucket_->QueueInMs());
495}
496
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000497TEST_F(PacedSenderTest, MaxQueueLength) {
498 uint32_t ssrc = 12346;
499 uint16_t sequence_number = 1234;
500 EXPECT_EQ(0, send_bucket_->QueueInMs());
501
pbos@webrtc.org709e2972014-03-19 10:59:52 +0000502 send_bucket_->UpdateBitrate(kPaceMultiplier * 30, 0);
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000503 for (int i = 0; i < 30; ++i) {
504 SendAndExpectPacket(PacedSender::kNormalPriority,
505 ssrc,
506 sequence_number++,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000507 clock_.TimeInMilliseconds(),
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000508 1200,
509 false);
510 }
511
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000512 clock_.AdvanceTimeMilliseconds(2001);
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000513 SendAndExpectPacket(PacedSender::kNormalPriority,
514 ssrc,
515 sequence_number++,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000516 clock_.TimeInMilliseconds(),
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000517 1200,
518 false);
519 EXPECT_EQ(2001, send_bucket_->QueueInMs());
520 send_bucket_->Process();
521 EXPECT_EQ(0, send_bucket_->QueueInMs());
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000522 clock_.AdvanceTimeMilliseconds(31);
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000523
stefan@webrtc.org19a40ff2013-11-27 14:16:20 +0000524 send_bucket_->Process();
525}
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000526
527TEST_F(PacedSenderTest, QueueTimeGrowsOverTime) {
528 uint32_t ssrc = 12346;
529 uint16_t sequence_number = 1234;
530 EXPECT_EQ(0, send_bucket_->QueueInMs());
531
pbos@webrtc.org709e2972014-03-19 10:59:52 +0000532 send_bucket_->UpdateBitrate(kPaceMultiplier * 30, 0);
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000533 SendAndExpectPacket(PacedSender::kNormalPriority,
534 ssrc,
535 sequence_number,
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000536 clock_.TimeInMilliseconds(),
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000537 1200,
538 false);
539
stefan@webrtc.org88e0dda2014-07-04 09:20:42 +0000540 clock_.AdvanceTimeMilliseconds(500);
stefan@webrtc.orgdd393e72013-12-13 22:03:27 +0000541 EXPECT_EQ(500, send_bucket_->QueueInMs());
542 send_bucket_->Process();
543 EXPECT_EQ(0, send_bucket_->QueueInMs());
544}
pwestin@webrtc.orgdb418562013-03-22 23:39:29 +0000545} // namespace test
pwestin@webrtc.orgb5180172012-11-09 20:56:23 +0000546} // namespace webrtc