tor-browser

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

channel_receive_unittest.cc (10126B)


      1 /*
      2 *  Copyright 2023 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 "audio/channel_receive.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 #include <cstring>
     16 #include <memory>
     17 #include <optional>
     18 #include <vector>
     19 
     20 #include "absl/strings/string_view.h"
     21 #include "api/array_view.h"
     22 #include "api/audio/audio_frame.h"
     23 #include "api/audio_codecs/audio_decoder_factory.h"
     24 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
     25 #include "api/call/transport.h"
     26 #include "api/crypto/crypto_options.h"
     27 #include "api/environment/environment_factory.h"
     28 #include "api/make_ref_counted.h"
     29 #include "api/scoped_refptr.h"
     30 #include "api/test/mock_frame_transformer.h"
     31 #include "api/units/time_delta.h"
     32 #include "api/units/timestamp.h"
     33 #include "modules/audio_device/include/mock_audio_device.h"
     34 #include "modules/rtp_rtcp/source/ntp_time_util.h"
     35 #include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
     36 #include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
     37 #include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
     38 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
     39 #include "rtc_base/logging.h"
     40 #include "rtc_base/string_encode.h"
     41 #include "system_wrappers/include/ntp_time.h"
     42 #include "test/gmock.h"
     43 #include "test/gtest.h"
     44 #include "test/mock_transport.h"
     45 #include "test/time_controller/simulated_time_controller.h"
     46 
     47 namespace webrtc {
     48 namespace voe {
     49 namespace {
     50 
     51 using ::testing::NiceMock;
     52 using ::testing::NotNull;
     53 using ::testing::Return;
     54 using ::testing::Test;
     55 
     56 constexpr uint32_t kLocalSsrc = 1111;
     57 constexpr uint32_t kRemoteSsrc = 2222;
     58 // We run RTP data with 8 kHz PCMA (fixed payload type 8).
     59 constexpr char kPayloadName[] = "PCMA";
     60 constexpr int kPayloadType = 8;
     61 constexpr int kSampleRateHz = 8000;
     62 
     63 class ChannelReceiveTest : public Test {
     64 public:
     65  ChannelReceiveTest()
     66      : time_controller_(Timestamp::Seconds(5555)),
     67        audio_device_module_(test::MockAudioDeviceModule::CreateNice()),
     68        audio_decoder_factory_(CreateBuiltinAudioDecoderFactory()) {
     69    ON_CALL(*audio_device_module_, PlayoutDelay).WillByDefault(Return(0));
     70  }
     71 
     72  std::unique_ptr<ChannelReceiveInterface> CreateTestChannelReceive() {
     73    CryptoOptions crypto_options;
     74    auto channel = CreateChannelReceive(
     75        CreateEnvironment(time_controller_.GetClock()),
     76        /* neteq_factory= */ nullptr, audio_device_module_.get(), &transport_,
     77        kLocalSsrc, kRemoteSsrc,
     78        /* jitter_buffer_max_packets= */ 0,
     79        /* jitter_buffer_fast_playout= */ false,
     80        /* jitter_buffer_min_delay_ms= */ 0,
     81        /* enable_non_sender_rtt= */ false, audio_decoder_factory_,
     82        /* codec_pair_id= */ std::nullopt,
     83        /* frame_decryptor_interface= */ nullptr, crypto_options,
     84        /* frame_transformer= */ nullptr);
     85    channel->SetReceiveCodecs(
     86        {{kPayloadType, {kPayloadName, kSampleRateHz, 1}}});
     87    return channel;
     88  }
     89 
     90  NtpTime NtpNow() { return time_controller_.GetClock()->CurrentNtpTime(); }
     91 
     92  uint32_t RtpNow() {
     93    // Note - the "random" offset of this timestamp is zero.
     94    return time_controller_.GetClock()->TimeInMilliseconds() * 1000 /
     95           kSampleRateHz;
     96  }
     97 
     98  RtpPacketReceived CreateRtpPacket() {
     99    RtpPacketReceived packet;
    100    packet.set_arrival_time(time_controller_.GetClock()->CurrentTime());
    101    packet.SetTimestamp(RtpNow());
    102    packet.SetSsrc(kLocalSsrc);
    103    packet.SetPayloadType(kPayloadType);
    104    // Packet size should be enough to give at least 10 ms of data.
    105    // For PCMA, that's 80 bytes; this should be enough.
    106    uint8_t* datapos = packet.SetPayloadSize(100);
    107    memset(datapos, 0, 100);
    108    return packet;
    109  }
    110 
    111  std::vector<uint8_t> CreateRtcpSenderReport() {
    112    std::vector<uint8_t> packet(1024);
    113    size_t pos = 0;
    114    rtcp::SenderReport report;
    115    report.SetSenderSsrc(kRemoteSsrc);
    116    report.SetNtp(NtpNow());
    117    report.SetRtpTimestamp(RtpNow());
    118    report.SetPacketCount(0);
    119    report.SetOctetCount(0);
    120    report.Create(&packet[0], &pos, packet.size(), nullptr);
    121    // No report blocks.
    122    packet.resize(pos);
    123    return packet;
    124  }
    125 
    126  std::vector<uint8_t> CreateRtcpReceiverReport() {
    127    rtcp::ReportBlock block;
    128    block.SetMediaSsrc(kLocalSsrc);
    129    // Middle 32 bits of the NTP timestamp from received SR
    130    block.SetLastSr(CompactNtp(NtpNow()));
    131    block.SetDelayLastSr(0);
    132 
    133    rtcp::ReceiverReport report;
    134    report.SetSenderSsrc(kRemoteSsrc);
    135    report.AddReportBlock(block);
    136 
    137    std::vector<uint8_t> packet(1024);
    138    size_t pos = 0;
    139    report.Create(&packet[0], &pos, packet.size(), nullptr);
    140    packet.resize(pos);
    141    return packet;
    142  }
    143 
    144  void HandleGeneratedRtcp(ChannelReceiveInterface& /* channel */,
    145                           ArrayView<const uint8_t> packet) {
    146    if (packet[1] == rtcp::ReceiverReport::kPacketType) {
    147      // Ignore RR, it requires no response
    148    } else {
    149      RTC_LOG(LS_ERROR) << "Unexpected RTCP packet generated";
    150      RTC_LOG(LS_ERROR) << "Packet content "
    151                        << hex_encode_with_delimiter(
    152                               absl::string_view(
    153                                   reinterpret_cast<char*>(packet.data()[0]),
    154                                   packet.size()),
    155                               ' ');
    156    }
    157  }
    158 
    159  int64_t ProbeCaptureStartNtpTime(ChannelReceiveInterface& channel) {
    160    // Computation of the capture_start_ntp_time_ms_ occurs when the
    161    // audio data is pulled, not when it is received. So we need to
    162    // inject an RTP packet, and then fetch its data.
    163    AudioFrame audio_frame;
    164    channel.OnRtpPacket(CreateRtpPacket());
    165    channel.GetAudioFrameWithInfo(kSampleRateHz, &audio_frame);
    166    ChannelReceiveStatistics stats = channel.GetRTCPStatistics();
    167    return stats.capture_start_ntp_time_ms;
    168  }
    169 
    170 protected:
    171  GlobalSimulatedTimeController time_controller_;
    172  scoped_refptr<test::MockAudioDeviceModule> audio_device_module_;
    173  scoped_refptr<AudioDecoderFactory> audio_decoder_factory_;
    174  MockTransport transport_;
    175 };
    176 
    177 TEST_F(ChannelReceiveTest, CreateAndDestroy) {
    178  auto channel = CreateTestChannelReceive();
    179  EXPECT_THAT(channel, NotNull());
    180 }
    181 
    182 TEST_F(ChannelReceiveTest, ReceiveReportGeneratedOnTime) {
    183  auto channel = CreateTestChannelReceive();
    184 
    185  bool receiver_report_sent = false;
    186  EXPECT_CALL(transport_, SendRtcp)
    187      .WillRepeatedly([&](ArrayView<const uint8_t> packet,
    188                          const PacketOptions& options) {
    189        if (packet.size() >= 2 &&
    190            packet[1] == rtcp::ReceiverReport::kPacketType) {
    191          receiver_report_sent = true;
    192        }
    193        return true;
    194      });
    195  // RFC 3550 section 6.2 mentions 5 seconds as a reasonable expectation
    196  // for the interval between RTCP packets.
    197  time_controller_.AdvanceTime(TimeDelta::Seconds(5));
    198 
    199  EXPECT_TRUE(receiver_report_sent);
    200 }
    201 
    202 TEST_F(ChannelReceiveTest, CaptureStartTimeBecomesValid) {
    203  auto channel = CreateTestChannelReceive();
    204 
    205  EXPECT_CALL(transport_, SendRtcp)
    206      .WillRepeatedly(
    207          [&](ArrayView<const uint8_t> packet, const PacketOptions& options) {
    208            HandleGeneratedRtcp(*channel, packet);
    209            return true;
    210          });
    211  // Before any packets are sent, CaptureStartTime is invalid.
    212  EXPECT_EQ(ProbeCaptureStartNtpTime(*channel), -1);
    213 
    214  // Must start playout, otherwise packet is discarded.
    215  channel->StartPlayout();
    216  // Send one RTP packet. This causes registration of the SSRC.
    217  channel->OnRtpPacket(CreateRtpPacket());
    218  EXPECT_EQ(ProbeCaptureStartNtpTime(*channel), -1);
    219 
    220  // Receive a sender report.
    221  auto rtcp_packet_1 = CreateRtcpSenderReport();
    222  channel->ReceivedRTCPPacket(rtcp_packet_1.data(), rtcp_packet_1.size());
    223  EXPECT_EQ(ProbeCaptureStartNtpTime(*channel), -1);
    224 
    225  time_controller_.AdvanceTime(TimeDelta::Seconds(5));
    226 
    227  // Receive a receiver report. This is necessary, which is odd.
    228  // Presumably it is because the receiver needs to know the RTT
    229  // before it can compute the capture start NTP time.
    230  // The receiver report must happen before the second sender report.
    231  auto rtcp_rr = CreateRtcpReceiverReport();
    232  channel->ReceivedRTCPPacket(rtcp_rr.data(), rtcp_rr.size());
    233  EXPECT_EQ(ProbeCaptureStartNtpTime(*channel), -1);
    234 
    235  // Receive another sender report after 5 seconds.
    236  // This should be enough to establish the capture start NTP time.
    237  auto rtcp_packet_2 = CreateRtcpSenderReport();
    238  channel->ReceivedRTCPPacket(rtcp_packet_2.data(), rtcp_packet_2.size());
    239 
    240  EXPECT_NE(ProbeCaptureStartNtpTime(*channel), -1);
    241 }
    242 
    243 TEST_F(ChannelReceiveTest, SettingFrameTransformer) {
    244  auto channel = CreateTestChannelReceive();
    245 
    246  scoped_refptr<MockFrameTransformer> mock_frame_transformer =
    247      make_ref_counted<MockFrameTransformer>();
    248 
    249  EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback);
    250  channel->SetDepacketizerToDecoderFrameTransformer(mock_frame_transformer);
    251 
    252  // Must start playout, otherwise packet is discarded.
    253  channel->StartPlayout();
    254 
    255  RtpPacketReceived packet = CreateRtpPacket();
    256 
    257  // Receive one RTP packet, this should be transformed.
    258  EXPECT_CALL(*mock_frame_transformer, Transform);
    259  channel->OnRtpPacket(packet);
    260 }
    261 
    262 TEST_F(ChannelReceiveTest, SettingFrameTransformerMultipleTimes) {
    263  auto channel = CreateTestChannelReceive();
    264 
    265  scoped_refptr<MockFrameTransformer> mock_frame_transformer =
    266      make_ref_counted<MockFrameTransformer>();
    267 
    268  EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback);
    269  channel->SetDepacketizerToDecoderFrameTransformer(mock_frame_transformer);
    270 
    271  // Set the same transformer again, shouldn't cause any additional callback
    272  // registration calls.
    273  EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback)
    274      .Times(0);
    275  channel->SetDepacketizerToDecoderFrameTransformer(mock_frame_transformer);
    276 }
    277 
    278 }  // namespace
    279 }  // namespace voe
    280 }  // namespace webrtc