1/* 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 * This file includes unit tests for the RTPPacketHistory. 11 */ 12 13#include "testing/gtest/include/gtest/gtest.h" 14 15#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 16#include "webrtc/modules/rtp_rtcp/source/rtp_packet_history.h" 17#include "webrtc/system_wrappers/include/clock.h" 18#include "webrtc/typedefs.h" 19 20namespace webrtc { 21 22class RtpPacketHistoryTest : public ::testing::Test { 23 protected: 24 RtpPacketHistoryTest() 25 : fake_clock_(123456), 26 hist_(new RTPPacketHistory(&fake_clock_)) { 27 } 28 ~RtpPacketHistoryTest() { 29 delete hist_; 30 } 31 32 SimulatedClock fake_clock_; 33 RTPPacketHistory* hist_; 34 enum {kPayload = 127}; 35 enum {kSsrc = 12345678}; 36 enum {kSeqNum = 88}; 37 enum {kTimestamp = 127}; 38 enum {kMaxPacketLength = 1500}; 39 uint8_t packet_[kMaxPacketLength]; 40 uint8_t packet_out_[kMaxPacketLength]; 41 42 void CreateRtpPacket(uint16_t seq_num, uint32_t ssrc, uint8_t payload, 43 uint32_t timestamp, uint8_t* array, size_t* cur_pos) { 44 array[(*cur_pos)++] = 0x80; 45 array[(*cur_pos)++] = payload; 46 array[(*cur_pos)++] = seq_num >> 8; 47 array[(*cur_pos)++] = seq_num; 48 array[(*cur_pos)++] = timestamp >> 24; 49 array[(*cur_pos)++] = timestamp >> 16; 50 array[(*cur_pos)++] = timestamp >> 8; 51 array[(*cur_pos)++] = timestamp; 52 array[(*cur_pos)++] = ssrc >> 24; 53 array[(*cur_pos)++] = ssrc >> 16; 54 array[(*cur_pos)++] = ssrc >> 8; 55 array[(*cur_pos)++] = ssrc; 56 } 57}; 58 59TEST_F(RtpPacketHistoryTest, SetStoreStatus) { 60 EXPECT_FALSE(hist_->StorePackets()); 61 hist_->SetStorePacketsStatus(true, 10); 62 EXPECT_TRUE(hist_->StorePackets()); 63 hist_->SetStorePacketsStatus(false, 0); 64 EXPECT_FALSE(hist_->StorePackets()); 65} 66 67TEST_F(RtpPacketHistoryTest, NoStoreStatus) { 68 EXPECT_FALSE(hist_->StorePackets()); 69 size_t len = 0; 70 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds(); 71 CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len); 72 EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, capture_time_ms, 73 kAllowRetransmission)); 74 // Packet should not be stored. 75 len = kMaxPacketLength; 76 int64_t time; 77 EXPECT_FALSE(hist_->GetPacketAndSetSendTime(kSeqNum, 0, false, packet_, &len, 78 &time)); 79} 80 81TEST_F(RtpPacketHistoryTest, PutRtpPacket_TooLargePacketLength) { 82 hist_->SetStorePacketsStatus(true, 10); 83 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds(); 84 EXPECT_EQ(-1, hist_->PutRTPPacket(packet_, kMaxPacketLength + 1, 85 capture_time_ms, kAllowRetransmission)); 86} 87 88TEST_F(RtpPacketHistoryTest, GetRtpPacket_NotStored) { 89 hist_->SetStorePacketsStatus(true, 10); 90 size_t len = kMaxPacketLength; 91 int64_t time; 92 EXPECT_FALSE(hist_->GetPacketAndSetSendTime(0, 0, false, packet_, &len, 93 &time)); 94} 95 96TEST_F(RtpPacketHistoryTest, PutRtpPacket) { 97 hist_->SetStorePacketsStatus(true, 10); 98 size_t len = 0; 99 CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len); 100 101 EXPECT_FALSE(hist_->HasRTPPacket(kSeqNum)); 102 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds(); 103 EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, capture_time_ms, 104 kAllowRetransmission)); 105 EXPECT_TRUE(hist_->HasRTPPacket(kSeqNum)); 106} 107 108TEST_F(RtpPacketHistoryTest, GetRtpPacket) { 109 hist_->SetStorePacketsStatus(true, 10); 110 size_t len = 0; 111 int64_t capture_time_ms = 1; 112 CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len); 113 EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, capture_time_ms, 114 kAllowRetransmission)); 115 116 size_t len_out = kMaxPacketLength; 117 int64_t time; 118 EXPECT_TRUE(hist_->GetPacketAndSetSendTime(kSeqNum, 0, false, packet_out_, 119 &len_out, &time)); 120 EXPECT_EQ(len, len_out); 121 EXPECT_EQ(capture_time_ms, time); 122 for (size_t i = 0; i < len; i++) { 123 EXPECT_EQ(packet_[i], packet_out_[i]); 124 } 125} 126 127TEST_F(RtpPacketHistoryTest, NoCaptureTime) { 128 hist_->SetStorePacketsStatus(true, 10); 129 size_t len = 0; 130 fake_clock_.AdvanceTimeMilliseconds(1); 131 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds(); 132 CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len); 133 EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, -1, kAllowRetransmission)); 134 135 size_t len_out = kMaxPacketLength; 136 int64_t time; 137 EXPECT_TRUE(hist_->GetPacketAndSetSendTime(kSeqNum, 0, false, packet_out_, 138 &len_out, &time)); 139 EXPECT_EQ(len, len_out); 140 EXPECT_EQ(capture_time_ms, time); 141 for (size_t i = 0; i < len; i++) { 142 EXPECT_EQ(packet_[i], packet_out_[i]); 143 } 144} 145 146TEST_F(RtpPacketHistoryTest, DontRetransmit) { 147 hist_->SetStorePacketsStatus(true, 10); 148 size_t len = 0; 149 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds(); 150 CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len); 151 EXPECT_EQ( 152 0, hist_->PutRTPPacket(packet_, len, capture_time_ms, kDontRetransmit)); 153 154 size_t len_out = kMaxPacketLength; 155 int64_t time; 156 EXPECT_TRUE(hist_->GetPacketAndSetSendTime(kSeqNum, 0, false, packet_out_, 157 &len_out, &time)); 158 EXPECT_EQ(len, len_out); 159 EXPECT_EQ(capture_time_ms, time); 160} 161 162TEST_F(RtpPacketHistoryTest, MinResendTime) { 163 static const int64_t kMinRetransmitIntervalMs = 100; 164 165 hist_->SetStorePacketsStatus(true, 10); 166 size_t len = 0; 167 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds(); 168 CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len); 169 EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, capture_time_ms, 170 kAllowRetransmission)); 171 172 // First transmission: TimeToSendPacket() call from pacer. 173 int64_t time; 174 len = kMaxPacketLength; 175 EXPECT_TRUE( 176 hist_->GetPacketAndSetSendTime(kSeqNum, 0, false, packet_, &len, &time)); 177 178 fake_clock_.AdvanceTimeMilliseconds(kMinRetransmitIntervalMs); 179 // Time has elapsed. 180 len = kMaxPacketLength; 181 EXPECT_TRUE(hist_->GetPacketAndSetSendTime(kSeqNum, kMinRetransmitIntervalMs, 182 true, packet_, &len, &time)); 183 EXPECT_GT(len, 0u); 184 EXPECT_EQ(capture_time_ms, time); 185 186 fake_clock_.AdvanceTimeMilliseconds(kMinRetransmitIntervalMs - 1); 187 // Time has not elapsed. Packet should be found, but no bytes copied. 188 len = kMaxPacketLength; 189 EXPECT_FALSE(hist_->GetPacketAndSetSendTime(kSeqNum, kMinRetransmitIntervalMs, 190 true, packet_, &len, &time)); 191} 192 193TEST_F(RtpPacketHistoryTest, EarlyFirstResend) { 194 static const int64_t kMinRetransmitIntervalMs = 100; 195 196 hist_->SetStorePacketsStatus(true, 10); 197 size_t len = 0; 198 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds(); 199 CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len); 200 EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, capture_time_ms, 201 kAllowRetransmission)); 202 203 // First transmission: TimeToSendPacket() call from pacer. 204 int64_t time; 205 len = kMaxPacketLength; 206 EXPECT_TRUE( 207 hist_->GetPacketAndSetSendTime(kSeqNum, 0, false, packet_, &len, &time)); 208 209 fake_clock_.AdvanceTimeMilliseconds(kMinRetransmitIntervalMs - 1); 210 // Time has not elapsed, but this is the first retransmission request so 211 // allow anyway. 212 len = kMaxPacketLength; 213 EXPECT_TRUE(hist_->GetPacketAndSetSendTime(kSeqNum, kMinRetransmitIntervalMs, 214 true, packet_, &len, &time)); 215 EXPECT_GT(len, 0u); 216 EXPECT_EQ(capture_time_ms, time); 217 218 fake_clock_.AdvanceTimeMilliseconds(kMinRetransmitIntervalMs - 1); 219 // Time has not elapsed. Packet should be found, but no bytes copied. 220 len = kMaxPacketLength; 221 EXPECT_FALSE(hist_->GetPacketAndSetSendTime(kSeqNum, kMinRetransmitIntervalMs, 222 true, packet_, &len, &time)); 223} 224 225TEST_F(RtpPacketHistoryTest, DynamicExpansion) { 226 hist_->SetStorePacketsStatus(true, 10); 227 size_t len; 228 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds(); 229 int64_t time; 230 231 // Add 4 packets, and then send them. 232 for (int i = 0; i < 4; ++i) { 233 len = 0; 234 CreateRtpPacket(kSeqNum + i, kSsrc, kPayload, kTimestamp, packet_, &len); 235 EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, capture_time_ms, 236 kAllowRetransmission)); 237 } 238 for (int i = 0; i < 4; ++i) { 239 len = kMaxPacketLength; 240 EXPECT_TRUE(hist_->GetPacketAndSetSendTime(kSeqNum + i, 100, false, packet_, 241 &len, &time)); 242 } 243 capture_time_ms += 33; 244 245 // Add 16 packets, and then send them. History should expand to make this 246 // work. 247 for (int i = 4; i < 20; ++i) { 248 len = 0; 249 CreateRtpPacket(kSeqNum + i, kSsrc, kPayload, kTimestamp, packet_, &len); 250 EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, capture_time_ms, 251 kAllowRetransmission)); 252 } 253 for (int i = 4; i < 20; ++i) { 254 len = kMaxPacketLength; 255 EXPECT_TRUE(hist_->GetPacketAndSetSendTime(kSeqNum + i, 100, false, packet_, 256 &len, &time)); 257 } 258 259 fake_clock_.AdvanceTimeMilliseconds(100); 260 261 // Retransmit last 16 packets. 262 for (int i = 4; i < 20; ++i) { 263 len = kMaxPacketLength; 264 EXPECT_TRUE(hist_->GetPacketAndSetSendTime(kSeqNum + i, 100, false, packet_, 265 &len, &time)); 266 } 267} 268 269TEST_F(RtpPacketHistoryTest, FullExpansion) { 270 static const int kSendSidePacketHistorySize = 600; 271 hist_->SetStorePacketsStatus(true, kSendSidePacketHistorySize); 272 size_t len; 273 int64_t capture_time_ms = fake_clock_.TimeInMilliseconds(); 274 int64_t time; 275 for (size_t i = 0; i < kMaxHistoryCapacity + 1; ++i) { 276 len = 0; 277 CreateRtpPacket(kSeqNum + i, kSsrc, kPayload, kTimestamp, packet_, &len); 278 EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, capture_time_ms, 279 kAllowRetransmission)); 280 } 281 282 fake_clock_.AdvanceTimeMilliseconds(100); 283 284 // Retransmit all packets currently in buffer. 285 for (size_t i = 1; i < kMaxHistoryCapacity + 1; ++i) { 286 len = kMaxPacketLength; 287 EXPECT_TRUE(hist_->GetPacketAndSetSendTime(kSeqNum + i, 100, false, packet_, 288 &len, &time)); 289 } 290} 291 292} // namespace webrtc 293