tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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