xref: /aosp_15_r20/external/webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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