1 /* 2 * Copyright (c) 2013 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 11 #include <algorithm> 12 #include <iterator> 13 #include <list> 14 #include <set> 15 16 #include "testing/gtest/include/gtest/gtest.h" 17 #include "webrtc/common_types.h" 18 #include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h" 19 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" 20 #include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" 21 #include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h" 22 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" 23 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h" 24 #include "webrtc/system_wrappers/interface/scoped_ptr.h" 25 26 using namespace webrtc; 27 28 const int kVideoNackListSize = 30; 29 const int kTestId = 123; 30 const uint32_t kTestSsrc = 3456; 31 const uint16_t kTestSequenceNumber = 2345; 32 const uint32_t kTestNumberOfPackets = 1350; 33 const int kTestNumberOfRtxPackets = 149; 34 const int kNumFrames = 30; 35 36 class VerifyingRtxReceiver : public NullRtpData 37 { 38 public: 39 VerifyingRtxReceiver() {} 40 41 virtual int32_t OnReceivedPayloadData( 42 const uint8_t* data, 43 const uint16_t size, 44 const webrtc::WebRtcRTPHeader* rtp_header) { 45 if (!sequence_numbers_.empty()) 46 EXPECT_EQ(kTestSsrc, rtp_header->header.ssrc); 47 sequence_numbers_.push_back(rtp_header->header.sequenceNumber); 48 return 0; 49 } 50 std::list<uint16_t> sequence_numbers_; 51 }; 52 53 class TestRtpFeedback : public NullRtpFeedback { 54 public: 55 TestRtpFeedback(RtpRtcp* rtp_rtcp) : rtp_rtcp_(rtp_rtcp) {} 56 virtual ~TestRtpFeedback() {} 57 58 virtual void OnIncomingSSRCChanged(const int32_t id, 59 const uint32_t ssrc) { 60 rtp_rtcp_->SetRemoteSSRC(ssrc); 61 } 62 63 private: 64 RtpRtcp* rtp_rtcp_; 65 }; 66 67 class RtxLoopBackTransport : public webrtc::Transport { 68 public: 69 explicit RtxLoopBackTransport(uint32_t rtx_ssrc) 70 : count_(0), 71 packet_loss_(0), 72 consecutive_drop_start_(0), 73 consecutive_drop_end_(0), 74 rtx_ssrc_(rtx_ssrc), 75 count_rtx_ssrc_(0), 76 rtp_payload_registry_(NULL), 77 rtp_receiver_(NULL), 78 module_(NULL) {} 79 80 void SetSendModule(RtpRtcp* rtpRtcpModule, 81 RTPPayloadRegistry* rtp_payload_registry, 82 RtpReceiver* receiver) { 83 module_ = rtpRtcpModule; 84 rtp_payload_registry_ = rtp_payload_registry; 85 rtp_receiver_ = receiver; 86 } 87 88 void DropEveryNthPacket(int n) { 89 packet_loss_ = n; 90 } 91 92 void DropConsecutivePackets(int start, int total) { 93 consecutive_drop_start_ = start; 94 consecutive_drop_end_ = start + total; 95 packet_loss_ = 0; 96 } 97 98 virtual int SendPacket(int channel, const void *data, int len) { 99 count_++; 100 const unsigned char* ptr = static_cast<const unsigned char*>(data); 101 uint32_t ssrc = (ptr[8] << 24) + (ptr[9] << 16) + (ptr[10] << 8) + ptr[11]; 102 if (ssrc == rtx_ssrc_) count_rtx_ssrc_++; 103 uint16_t sequence_number = (ptr[2] << 8) + ptr[3]; 104 expected_sequence_numbers_.insert(expected_sequence_numbers_.end(), 105 sequence_number); 106 if (packet_loss_ > 0) { 107 if ((count_ % packet_loss_) == 0) { 108 return len; 109 } 110 } else if (count_ >= consecutive_drop_start_ && 111 count_ < consecutive_drop_end_) { 112 return len; 113 } 114 int packet_length = len; 115 uint8_t restored_packet[1500]; 116 uint8_t* restored_packet_ptr = restored_packet; 117 RTPHeader header; 118 scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create()); 119 if (!parser->Parse(ptr, len, &header)) { 120 return -1; 121 } 122 if (rtp_payload_registry_->IsRtx(header)) { 123 // Remove the RTX header and parse the original RTP header. 124 EXPECT_TRUE(rtp_payload_registry_->RestoreOriginalPacket( 125 &restored_packet_ptr, ptr, &packet_length, rtp_receiver_->SSRC(), 126 header)); 127 if (!parser->Parse(restored_packet_ptr, packet_length, &header)) { 128 return -1; 129 } 130 } 131 restored_packet_ptr += header.headerLength; 132 packet_length -= header.headerLength; 133 PayloadUnion payload_specific; 134 if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType, 135 &payload_specific)) { 136 return -1; 137 } 138 if (!rtp_receiver_->IncomingRtpPacket(header, restored_packet_ptr, 139 packet_length, payload_specific, 140 true)) { 141 return -1; 142 } 143 return len; 144 } 145 146 virtual int SendRTCPPacket(int channel, const void *data, int len) { 147 if (module_->IncomingRtcpPacket((const uint8_t*)data, len) == 0) { 148 return len; 149 } 150 return -1; 151 } 152 int count_; 153 int packet_loss_; 154 int consecutive_drop_start_; 155 int consecutive_drop_end_; 156 uint32_t rtx_ssrc_; 157 int count_rtx_ssrc_; 158 RTPPayloadRegistry* rtp_payload_registry_; 159 RtpReceiver* rtp_receiver_; 160 RtpRtcp* module_; 161 std::set<uint16_t> expected_sequence_numbers_; 162 }; 163 164 class RtpRtcpRtxNackTest : public ::testing::Test { 165 protected: 166 RtpRtcpRtxNackTest() 167 : rtp_payload_registry_(RTPPayloadStrategy::CreateStrategy(false)), 168 rtp_rtcp_module_(NULL), 169 transport_(kTestSsrc + 1), 170 receiver_(), 171 payload_data_length(sizeof(payload_data)), 172 fake_clock(123456) {} 173 ~RtpRtcpRtxNackTest() {} 174 175 virtual void SetUp() { 176 RtpRtcp::Configuration configuration; 177 configuration.id = kTestId; 178 configuration.audio = false; 179 configuration.clock = &fake_clock; 180 receive_statistics_.reset(ReceiveStatistics::Create(&fake_clock)); 181 configuration.receive_statistics = receive_statistics_.get(); 182 configuration.outgoing_transport = &transport_; 183 rtp_rtcp_module_ = RtpRtcp::CreateRtpRtcp(configuration); 184 185 rtp_feedback_.reset(new TestRtpFeedback(rtp_rtcp_module_)); 186 187 rtp_receiver_.reset(RtpReceiver::CreateVideoReceiver( 188 kTestId, &fake_clock, &receiver_, rtp_feedback_.get(), 189 &rtp_payload_registry_)); 190 191 rtp_rtcp_module_->SetSSRC(kTestSsrc); 192 EXPECT_EQ(0, rtp_rtcp_module_->SetRTCPStatus(kRtcpCompound)); 193 rtp_receiver_->SetNACKStatus(kNackRtcp); 194 EXPECT_EQ(0, rtp_rtcp_module_->SetStorePacketsStatus(true, 600)); 195 EXPECT_EQ(0, rtp_rtcp_module_->SetSendingStatus(true)); 196 EXPECT_EQ(0, rtp_rtcp_module_->SetSequenceNumber(kTestSequenceNumber)); 197 EXPECT_EQ(0, rtp_rtcp_module_->SetStartTimestamp(111111)); 198 199 transport_.SetSendModule(rtp_rtcp_module_, &rtp_payload_registry_, 200 rtp_receiver_.get()); 201 202 VideoCodec video_codec; 203 memset(&video_codec, 0, sizeof(video_codec)); 204 video_codec.plType = 123; 205 memcpy(video_codec.plName, "I420", 5); 206 207 EXPECT_EQ(0, rtp_rtcp_module_->RegisterSendPayload(video_codec)); 208 EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(video_codec.plName, 209 video_codec.plType, 210 90000, 211 0, 212 video_codec.maxBitrate)); 213 214 for (int n = 0; n < payload_data_length; n++) { 215 payload_data[n] = n % 10; 216 } 217 } 218 219 int BuildNackList(uint16_t* nack_list) { 220 receiver_.sequence_numbers_.sort(); 221 std::list<uint16_t> missing_sequence_numbers; 222 std::list<uint16_t>::iterator it = 223 receiver_.sequence_numbers_.begin(); 224 225 while (it != receiver_.sequence_numbers_.end()) { 226 uint16_t sequence_number_1 = *it; 227 ++it; 228 if (it != receiver_.sequence_numbers_.end()) { 229 uint16_t sequence_number_2 = *it; 230 // Add all missing sequence numbers to list 231 for (uint16_t i = sequence_number_1 + 1; i < sequence_number_2; 232 ++i) { 233 missing_sequence_numbers.push_back(i); 234 } 235 } 236 } 237 int n = 0; 238 for (it = missing_sequence_numbers.begin(); 239 it != missing_sequence_numbers.end(); ++it) { 240 nack_list[n++] = (*it); 241 } 242 return n; 243 } 244 245 bool ExpectedPacketsReceived() { 246 std::list<uint16_t> received_sorted; 247 std::copy(receiver_.sequence_numbers_.begin(), 248 receiver_.sequence_numbers_.end(), 249 std::back_inserter(received_sorted)); 250 received_sorted.sort(); 251 return std::equal(received_sorted.begin(), received_sorted.end(), 252 transport_.expected_sequence_numbers_.begin()); 253 } 254 255 void RunRtxTest(RtxMode rtx_method, int loss) { 256 rtp_payload_registry_.SetRtxSsrc(kTestSsrc + 1); 257 rtp_rtcp_module_->SetRTXSendStatus(rtx_method); 258 rtp_rtcp_module_->SetRtxSsrc(kTestSsrc + 1); 259 transport_.DropEveryNthPacket(loss); 260 uint32_t timestamp = 3000; 261 uint16_t nack_list[kVideoNackListSize]; 262 for (int frame = 0; frame < kNumFrames; ++frame) { 263 EXPECT_EQ(0, rtp_rtcp_module_->SendOutgoingData(webrtc::kVideoFrameDelta, 264 123, 265 timestamp, 266 timestamp / 90, 267 payload_data, 268 payload_data_length)); 269 int length = BuildNackList(nack_list); 270 if (length > 0) 271 rtp_rtcp_module_->SendNACK(nack_list, length); 272 fake_clock.AdvanceTimeMilliseconds(33); 273 rtp_rtcp_module_->Process(); 274 // Prepare next frame. 275 timestamp += 3000; 276 } 277 receiver_.sequence_numbers_.sort(); 278 } 279 280 virtual void TearDown() { 281 delete rtp_rtcp_module_; 282 } 283 284 scoped_ptr<ReceiveStatistics> receive_statistics_; 285 RTPPayloadRegistry rtp_payload_registry_; 286 scoped_ptr<RtpReceiver> rtp_receiver_; 287 RtpRtcp* rtp_rtcp_module_; 288 scoped_ptr<TestRtpFeedback> rtp_feedback_; 289 RtxLoopBackTransport transport_; 290 VerifyingRtxReceiver receiver_; 291 uint8_t payload_data[65000]; 292 int payload_data_length; 293 SimulatedClock fake_clock; 294 }; 295 296 TEST_F(RtpRtcpRtxNackTest, LongNackList) { 297 const int kNumPacketsToDrop = 900; 298 const int kNumRequiredRtcp = 4; 299 uint32_t timestamp = 3000; 300 uint16_t nack_list[kNumPacketsToDrop]; 301 // Disable StorePackets to be able to set a larger packet history. 302 EXPECT_EQ(0, rtp_rtcp_module_->SetStorePacketsStatus(false, 0)); 303 // Enable StorePackets with a packet history of 2000 packets. 304 EXPECT_EQ(0, rtp_rtcp_module_->SetStorePacketsStatus(true, 2000)); 305 // Drop 900 packets from the second one so that we get a NACK list which is 306 // big enough to require 4 RTCP packets to be fully transmitted to the sender. 307 transport_.DropConsecutivePackets(2, kNumPacketsToDrop); 308 // Send 30 frames which at the default size is roughly what we need to get 309 // enough packets. 310 for (int frame = 0; frame < kNumFrames; ++frame) { 311 EXPECT_EQ(0, rtp_rtcp_module_->SendOutgoingData(webrtc::kVideoFrameDelta, 312 123, 313 timestamp, 314 timestamp / 90, 315 payload_data, 316 payload_data_length)); 317 // Prepare next frame. 318 timestamp += 3000; 319 fake_clock.AdvanceTimeMilliseconds(33); 320 rtp_rtcp_module_->Process(); 321 } 322 EXPECT_FALSE(transport_.expected_sequence_numbers_.empty()); 323 EXPECT_FALSE(receiver_.sequence_numbers_.empty()); 324 size_t last_receive_count = receiver_.sequence_numbers_.size(); 325 int length = BuildNackList(nack_list); 326 for (int i = 0; i < kNumRequiredRtcp - 1; ++i) { 327 rtp_rtcp_module_->SendNACK(nack_list, length); 328 EXPECT_GT(receiver_.sequence_numbers_.size(), last_receive_count); 329 last_receive_count = receiver_.sequence_numbers_.size(); 330 EXPECT_FALSE(ExpectedPacketsReceived()); 331 } 332 rtp_rtcp_module_->SendNACK(nack_list, length); 333 EXPECT_GT(receiver_.sequence_numbers_.size(), last_receive_count); 334 EXPECT_TRUE(ExpectedPacketsReceived()); 335 } 336 337 TEST_F(RtpRtcpRtxNackTest, RtxNack) { 338 RunRtxTest(kRtxRetransmitted, 10); 339 EXPECT_EQ(kTestSequenceNumber, *(receiver_.sequence_numbers_.begin())); 340 EXPECT_EQ(kTestSequenceNumber + kTestNumberOfPackets - 1, 341 *(receiver_.sequence_numbers_.rbegin())); 342 EXPECT_EQ(kTestNumberOfPackets, receiver_.sequence_numbers_.size()); 343 EXPECT_EQ(kTestNumberOfRtxPackets, transport_.count_rtx_ssrc_); 344 EXPECT_TRUE(ExpectedPacketsReceived()); 345 } 346