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