nack_rtx_unittest.cc (11741B)
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 <cstddef> 12 #include <cstdint> 13 #include <iterator> 14 #include <list> 15 #include <map> 16 #include <memory> 17 #include <set> 18 19 #include "absl/algorithm/container.h" 20 #include "api/array_view.h" 21 #include "api/call/transport.h" 22 #include "api/environment/environment.h" 23 #include "api/environment/environment_factory.h" 24 #include "api/rtp_headers.h" 25 #include "api/units/time_delta.h" 26 #include "api/units/timestamp.h" 27 #include "api/video/video_codec_type.h" 28 #include "api/video/video_frame_type.h" 29 #include "call/rtp_packet_sink_interface.h" 30 #include "call/rtp_stream_receiver_controller.h" 31 #include "call/rtp_stream_receiver_controller_interface.h" 32 #include "call/rtx_receive_stream.h" 33 #include "modules/rtp_rtcp/include/receive_statistics.h" 34 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" 35 #include "modules/rtp_rtcp/source/rtp_packet_received.h" 36 #include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h" 37 #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" 38 #include "modules/rtp_rtcp/source/rtp_sender_video.h" 39 #include "rtc_base/rate_limiter.h" 40 #include "rtc_base/thread.h" 41 #include "system_wrappers/include/clock.h" 42 #include "test/gtest.h" 43 44 namespace webrtc { 45 46 constexpr int kVideoNackListSize = 30; 47 constexpr uint32_t kTestSsrc = 3456; 48 constexpr uint32_t kTestRtxSsrc = kTestSsrc + 1; 49 constexpr uint16_t kTestSequenceNumber = 2345; 50 constexpr uint32_t kTestNumberOfPackets = 1350; 51 constexpr int kTestNumberOfRtxPackets = 149; 52 constexpr int kNumFrames = 30; 53 constexpr int kPayloadType = 123; 54 constexpr int kRtxPayloadType = 98; 55 constexpr int64_t kMaxRttMs = 1000; 56 57 class VerifyingMediaStream : public RtpPacketSinkInterface { 58 public: 59 VerifyingMediaStream() {} 60 61 void OnRtpPacket(const RtpPacketReceived& packet) override { 62 if (!sequence_numbers_.empty()) 63 EXPECT_EQ(kTestSsrc, packet.Ssrc()); 64 65 sequence_numbers_.push_back(packet.SequenceNumber()); 66 } 67 std::list<uint16_t> sequence_numbers_; 68 }; 69 70 class RtxLoopBackTransport : public Transport { 71 public: 72 explicit RtxLoopBackTransport(uint32_t rtx_ssrc) 73 : count_(0), 74 packet_loss_(0), 75 consecutive_drop_start_(0), 76 consecutive_drop_end_(0), 77 rtx_ssrc_(rtx_ssrc), 78 count_rtx_ssrc_(0), 79 module_(nullptr) {} 80 81 void SetSendModule(RtpRtcpInterface* rtpRtcpModule) { 82 module_ = rtpRtcpModule; 83 } 84 85 void DropEveryNthPacket(int n) { packet_loss_ = n; } 86 87 void DropConsecutivePackets(int start, int total) { 88 consecutive_drop_start_ = start; 89 consecutive_drop_end_ = start + total; 90 packet_loss_ = 0; 91 } 92 93 bool SendRtp(ArrayView<const uint8_t> data, 94 const PacketOptions& /* options */) override { 95 count_++; 96 RtpPacketReceived packet; 97 if (!packet.Parse(data)) 98 return false; 99 if (packet.Ssrc() == rtx_ssrc_) { 100 count_rtx_ssrc_++; 101 } else { 102 // For non-RTX packets only. 103 expected_sequence_numbers_.insert(expected_sequence_numbers_.end(), 104 packet.SequenceNumber()); 105 } 106 if (packet_loss_ > 0) { 107 if ((count_ % packet_loss_) == 0) { 108 return true; 109 } 110 } else if (count_ >= consecutive_drop_start_ && 111 count_ < consecutive_drop_end_) { 112 return true; 113 } 114 EXPECT_TRUE(stream_receiver_controller_.OnRtpPacket(packet)); 115 return true; 116 } 117 118 bool SendRtcp(ArrayView<const uint8_t> data, 119 const PacketOptions& /* options */) override { 120 module_->IncomingRtcpPacket(data); 121 return true; 122 } 123 int count_; 124 int packet_loss_; 125 int consecutive_drop_start_; 126 int consecutive_drop_end_; 127 uint32_t rtx_ssrc_; 128 int count_rtx_ssrc_; 129 RtpRtcpInterface* module_; 130 RtpStreamReceiverController stream_receiver_controller_; 131 std::set<uint16_t> expected_sequence_numbers_; 132 }; 133 134 class RtpRtcpRtxNackTest : public ::testing::Test { 135 protected: 136 RtpRtcpRtxNackTest() 137 : fake_clock_(123456), 138 env_(CreateEnvironment(&fake_clock_)), 139 transport_(kTestRtxSsrc), 140 rtx_stream_(&media_stream_, rtx_associated_payload_types_, kTestSsrc), 141 retransmission_rate_limiter_(&fake_clock_, kMaxRttMs) {} 142 ~RtpRtcpRtxNackTest() override {} 143 144 void SetUp() override { 145 RtpRtcpInterface::Configuration configuration; 146 configuration.audio = false; 147 receive_statistics_ = ReceiveStatistics::Create(&fake_clock_); 148 configuration.receive_statistics = receive_statistics_.get(); 149 configuration.outgoing_transport = &transport_; 150 configuration.retransmission_rate_limiter = &retransmission_rate_limiter_; 151 configuration.local_media_ssrc = kTestSsrc; 152 configuration.rtx_send_ssrc = kTestRtxSsrc; 153 rtp_rtcp_module_ = 154 std::make_unique<ModuleRtpRtcpImpl2>(env_, configuration); 155 RTPSenderVideo::Config video_config; 156 video_config.clock = &fake_clock_; 157 video_config.rtp_sender = rtp_rtcp_module_->RtpSender(); 158 video_config.field_trials = &env_.field_trials(); 159 rtp_sender_video_ = std::make_unique<RTPSenderVideo>(video_config); 160 rtp_rtcp_module_->SetRTCPStatus(RtcpMode::kCompound); 161 rtp_rtcp_module_->SetStorePacketsStatus(true, 600); 162 EXPECT_EQ(0, rtp_rtcp_module_->SetSendingStatus(true)); 163 rtp_rtcp_module_->SetSequenceNumber(kTestSequenceNumber); 164 rtp_rtcp_module_->SetStartTimestamp(111111); 165 166 // Used for NACK processing. 167 rtp_rtcp_module_->SetRemoteSSRC(kTestSsrc); 168 169 rtp_rtcp_module_->SetRtxSendPayloadType(kRtxPayloadType, kPayloadType); 170 transport_.SetSendModule(rtp_rtcp_module_.get()); 171 media_receiver_ = transport_.stream_receiver_controller_.CreateReceiver( 172 kTestSsrc, &media_stream_); 173 174 for (size_t n = 0; n < sizeof(payload_data); n++) { 175 payload_data[n] = n % 10; 176 } 177 } 178 179 int BuildNackList(uint16_t* nack_list) { 180 media_stream_.sequence_numbers_.sort(); 181 std::list<uint16_t> missing_sequence_numbers; 182 std::list<uint16_t>::iterator it = media_stream_.sequence_numbers_.begin(); 183 184 while (it != media_stream_.sequence_numbers_.end()) { 185 uint16_t sequence_number_1 = *it; 186 ++it; 187 if (it != media_stream_.sequence_numbers_.end()) { 188 uint16_t sequence_number_2 = *it; 189 // Add all missing sequence numbers to list 190 for (uint16_t i = sequence_number_1 + 1; i < sequence_number_2; ++i) { 191 missing_sequence_numbers.push_back(i); 192 } 193 } 194 } 195 int n = 0; 196 for (it = missing_sequence_numbers.begin(); 197 it != missing_sequence_numbers.end(); ++it) { 198 nack_list[n++] = (*it); 199 } 200 return n; 201 } 202 203 bool ExpectedPacketsReceived() { 204 std::list<uint16_t> received_sorted; 205 absl::c_copy(media_stream_.sequence_numbers_, 206 std::back_inserter(received_sorted)); 207 received_sorted.sort(); 208 return absl::c_equal(received_sorted, 209 transport_.expected_sequence_numbers_); 210 } 211 212 void RunRtxTest(RtxMode rtx_method, int loss) { 213 rtx_receiver_ = transport_.stream_receiver_controller_.CreateReceiver( 214 kTestRtxSsrc, &rtx_stream_); 215 rtp_rtcp_module_->SetRtxSendStatus(rtx_method); 216 transport_.DropEveryNthPacket(loss); 217 uint32_t timestamp = 3000; 218 uint16_t nack_list[kVideoNackListSize]; 219 for (int frame = 0; frame < kNumFrames; ++frame) { 220 RTPVideoHeader video_header; 221 EXPECT_TRUE(rtp_rtcp_module_->OnSendingRtpFrame(timestamp, timestamp / 90, 222 kPayloadType, false)); 223 video_header.frame_type = VideoFrameType::kVideoFrameDelta; 224 EXPECT_TRUE(rtp_sender_video_->SendVideo( 225 kPayloadType, VideoCodecType::kVideoCodecGeneric, timestamp, 226 /*capture_time=*/Timestamp::Millis(timestamp / 90), payload_data, 227 sizeof(payload_data), video_header, TimeDelta::Zero(), {})); 228 // Min required delay until retransmit = 5 + RTT ms (RTT = 0). 229 fake_clock_.AdvanceTimeMilliseconds(5); 230 int length = BuildNackList(nack_list); 231 if (length > 0) 232 rtp_rtcp_module_->SendNACK(nack_list, length); 233 fake_clock_.AdvanceTimeMilliseconds(28); // 33ms - 5ms delay. 234 // Prepare next frame. 235 timestamp += 3000; 236 } 237 media_stream_.sequence_numbers_.sort(); 238 } 239 240 AutoThread main_thread_; 241 SimulatedClock fake_clock_; 242 const Environment env_; 243 std::unique_ptr<ReceiveStatistics> receive_statistics_; 244 std::unique_ptr<ModuleRtpRtcpImpl2> rtp_rtcp_module_; 245 std::unique_ptr<RTPSenderVideo> rtp_sender_video_; 246 RtxLoopBackTransport transport_; 247 const std::map<int, int> rtx_associated_payload_types_ = { 248 {kRtxPayloadType, kPayloadType}}; 249 VerifyingMediaStream media_stream_; 250 RtxReceiveStream rtx_stream_; 251 uint8_t payload_data[65000]; 252 RateLimiter retransmission_rate_limiter_; 253 std::unique_ptr<RtpStreamReceiverInterface> media_receiver_; 254 std::unique_ptr<RtpStreamReceiverInterface> rtx_receiver_; 255 }; 256 257 TEST_F(RtpRtcpRtxNackTest, LongNackList) { 258 const int kNumPacketsToDrop = 900; 259 const int kNumRequiredRtcp = 4; 260 uint32_t timestamp = 3000; 261 uint16_t nack_list[kNumPacketsToDrop]; 262 // Disable StorePackets to be able to set a larger packet history. 263 rtp_rtcp_module_->SetStorePacketsStatus(false, 0); 264 // Enable StorePackets with a packet history of 2000 packets. 265 rtp_rtcp_module_->SetStorePacketsStatus(true, 2000); 266 // Drop 900 packets from the second one so that we get a NACK list which is 267 // big enough to require 4 RTCP packets to be fully transmitted to the sender. 268 transport_.DropConsecutivePackets(2, kNumPacketsToDrop); 269 // Send 30 frames which at the default size is roughly what we need to get 270 // enough packets. 271 for (int frame = 0; frame < kNumFrames; ++frame) { 272 RTPVideoHeader video_header; 273 EXPECT_TRUE(rtp_rtcp_module_->OnSendingRtpFrame(timestamp, timestamp / 90, 274 kPayloadType, false)); 275 video_header.frame_type = VideoFrameType::kVideoFrameDelta; 276 EXPECT_TRUE(rtp_sender_video_->SendVideo( 277 kPayloadType, VideoCodecType::kVideoCodecGeneric, timestamp, 278 Timestamp::Millis(timestamp / 90), payload_data, sizeof(payload_data), 279 video_header, TimeDelta::Zero(), {})); 280 // Prepare next frame. 281 timestamp += 3000; 282 fake_clock_.AdvanceTimeMilliseconds(33); 283 } 284 EXPECT_FALSE(transport_.expected_sequence_numbers_.empty()); 285 EXPECT_FALSE(media_stream_.sequence_numbers_.empty()); 286 size_t last_receive_count = media_stream_.sequence_numbers_.size(); 287 int length = BuildNackList(nack_list); 288 for (int i = 0; i < kNumRequiredRtcp - 1; ++i) { 289 rtp_rtcp_module_->SendNACK(nack_list, length); 290 EXPECT_GT(media_stream_.sequence_numbers_.size(), last_receive_count); 291 last_receive_count = media_stream_.sequence_numbers_.size(); 292 EXPECT_FALSE(ExpectedPacketsReceived()); 293 } 294 rtp_rtcp_module_->SendNACK(nack_list, length); 295 EXPECT_GT(media_stream_.sequence_numbers_.size(), last_receive_count); 296 EXPECT_TRUE(ExpectedPacketsReceived()); 297 } 298 299 TEST_F(RtpRtcpRtxNackTest, RtxNack) { 300 RunRtxTest(kRtxRetransmitted, 10); 301 EXPECT_EQ(kTestSequenceNumber, *(media_stream_.sequence_numbers_.begin())); 302 EXPECT_EQ(kTestSequenceNumber + kTestNumberOfPackets - 1, 303 *(media_stream_.sequence_numbers_.rbegin())); 304 EXPECT_EQ(kTestNumberOfPackets, media_stream_.sequence_numbers_.size()); 305 EXPECT_EQ(kTestNumberOfRtxPackets, transport_.count_rtx_ssrc_); 306 EXPECT_TRUE(ExpectedPacketsReceived()); 307 } 308 309 } // namespace webrtc