tor-browser

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

rtp_sender_audio_unittest.cc (9686B)


      1 /*
      2 *  Copyright (c) 2019 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 "modules/rtp_rtcp/source/rtp_sender_audio.h"
     12 
     13 #include <cstdint>
     14 #include <memory>
     15 #include <vector>
     16 
     17 #include "api/array_view.h"
     18 #include "api/call/transport.h"
     19 #include "api/environment/environment.h"
     20 #include "api/environment/environment_factory.h"
     21 #include "api/rtp_headers.h"
     22 #include "api/units/timestamp.h"
     23 #include "modules/audio_coding/include/audio_coding_module_typedefs.h"
     24 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
     25 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
     26 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
     27 #include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h"
     28 #include "rtc_base/thread.h"
     29 #include "system_wrappers/include/clock.h"
     30 #include "system_wrappers/include/ntp_time.h"
     31 #include "test/gmock.h"
     32 #include "test/gtest.h"
     33 
     34 namespace webrtc {
     35 
     36 namespace {
     37 enum : int {  // The first valid value is 1.
     38  kAudioLevelExtensionId = 1,
     39  kAbsoluteCaptureTimeExtensionId = 2,
     40 };
     41 
     42 constexpr uint16_t kSeqNum = 33;
     43 constexpr uint32_t kSsrc = 725242;
     44 constexpr uint64_t kStartTime = 123456789;
     45 
     46 using ::testing::ElementsAreArray;
     47 
     48 class LoopbackTransportTest : public Transport {
     49 public:
     50  LoopbackTransportTest() {
     51    receivers_extensions_.Register<AudioLevelExtension>(kAudioLevelExtensionId);
     52    receivers_extensions_.Register<AbsoluteCaptureTimeExtension>(
     53        kAbsoluteCaptureTimeExtensionId);
     54  }
     55 
     56  bool SendRtp(ArrayView<const uint8_t> data,
     57               const PacketOptions& /*options*/) override {
     58    sent_packets_.push_back(RtpPacketReceived(&receivers_extensions_));
     59    EXPECT_TRUE(sent_packets_.back().Parse(data));
     60    return true;
     61  }
     62  bool SendRtcp(ArrayView<const uint8_t> /* data */,
     63                const PacketOptions& /* options */) override {
     64    return false;
     65  }
     66  const RtpPacketReceived& last_sent_packet() { return sent_packets_.back(); }
     67  int packets_sent() { return sent_packets_.size(); }
     68 
     69 private:
     70  RtpHeaderExtensionMap receivers_extensions_;
     71  std::vector<RtpPacketReceived> sent_packets_;
     72 };
     73 
     74 }  // namespace
     75 
     76 class RtpSenderAudioTest : public ::testing::Test {
     77 public:
     78  RtpSenderAudioTest()
     79      : fake_clock_(kStartTime),
     80        env_(CreateEnvironment(&fake_clock_)),
     81        rtp_module_(env_,
     82                    {.audio = true,
     83                     .outgoing_transport = &transport_,
     84                     .local_media_ssrc = kSsrc}),
     85        rtp_sender_audio_(
     86            std::make_unique<RTPSenderAudio>(&fake_clock_,
     87                                             rtp_module_.RtpSender())) {
     88    rtp_module_.SetSequenceNumber(kSeqNum);
     89  }
     90 
     91  AutoThread main_thread_;
     92  SimulatedClock fake_clock_;
     93  const Environment env_;
     94  LoopbackTransportTest transport_;
     95  ModuleRtpRtcpImpl2 rtp_module_;
     96  std::unique_ptr<RTPSenderAudio> rtp_sender_audio_;
     97 };
     98 
     99 TEST_F(RtpSenderAudioTest, SendAudio) {
    100  const char payload_name[] = "PAYLOAD_NAME";
    101  const uint8_t payload_type = 127;
    102  ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
    103                   payload_name, payload_type, 48000, 0, 1500));
    104  uint8_t payload[] = {47, 11, 32, 93, 89};
    105 
    106  ASSERT_TRUE(rtp_sender_audio_->SendAudio(
    107      {.payload = payload, .payload_id = payload_type}));
    108 
    109  auto sent_payload = transport_.last_sent_packet().payload();
    110  EXPECT_THAT(sent_payload, ElementsAreArray(payload));
    111 }
    112 
    113 TEST_F(RtpSenderAudioTest, SendAudioWithAudioLevelExtension) {
    114  const uint8_t kAudioLevel = 0x5a;
    115  rtp_module_.RegisterRtpHeaderExtension(AudioLevelExtension::Uri(),
    116                                         kAudioLevelExtensionId);
    117 
    118  const char payload_name[] = "PAYLOAD_NAME";
    119  const uint8_t payload_type = 127;
    120  ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
    121                   payload_name, payload_type, 48000, 0, 1500));
    122 
    123  uint8_t payload[] = {47, 11, 32, 93, 89};
    124 
    125  ASSERT_TRUE(
    126      rtp_sender_audio_->SendAudio({.type = AudioFrameType::kAudioFrameCN,
    127                                    .payload = payload,
    128                                    .payload_id = payload_type,
    129                                    .audio_level_dbov = kAudioLevel}));
    130 
    131  auto sent_payload = transport_.last_sent_packet().payload();
    132  EXPECT_THAT(sent_payload, ElementsAreArray(payload));
    133  // Verify AudioLevel extension.
    134  AudioLevel audio_level;
    135  EXPECT_TRUE(transport_.last_sent_packet().GetExtension<AudioLevelExtension>(
    136      &audio_level));
    137  EXPECT_EQ(kAudioLevel, audio_level.level());
    138  EXPECT_FALSE(audio_level.voice_activity());
    139 }
    140 
    141 TEST_F(RtpSenderAudioTest, SendAudioWithoutAbsoluteCaptureTime) {
    142  constexpr Timestamp kAbsoluteCaptureTimestamp = Timestamp::Millis(521);
    143  const char payload_name[] = "audio";
    144  const uint8_t payload_type = 127;
    145  ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
    146                   payload_name, payload_type, 48000, 0, 1500));
    147  uint8_t payload[] = {47, 11, 32, 93, 89};
    148 
    149  ASSERT_TRUE(rtp_sender_audio_->SendAudio(
    150      {.payload = payload,
    151       .payload_id = payload_type,
    152       .capture_time = kAbsoluteCaptureTimestamp}));
    153 
    154  // AbsoluteCaptureTimeExtension wasn't registered, thus can't be sent.
    155  EXPECT_FALSE(transport_.last_sent_packet()
    156                   .HasExtension<AbsoluteCaptureTimeExtension>());
    157 }
    158 
    159 TEST_F(RtpSenderAudioTest,
    160       SendAudioWithAbsoluteCaptureTimeWithCaptureClockOffset) {
    161  rtp_module_.RegisterRtpHeaderExtension(AbsoluteCaptureTimeExtension::Uri(),
    162                                         kAbsoluteCaptureTimeExtensionId);
    163  constexpr Timestamp kAbsoluteCaptureTimestamp = Timestamp::Millis(521);
    164  const char payload_name[] = "audio";
    165  const uint8_t payload_type = 127;
    166  ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
    167                   payload_name, payload_type, 48000, 0, 1500));
    168  uint8_t payload[] = {47, 11, 32, 93, 89};
    169 
    170  ASSERT_TRUE(rtp_sender_audio_->SendAudio(
    171      {.payload = payload,
    172       .payload_id = payload_type,
    173       .capture_time = kAbsoluteCaptureTimestamp}));
    174 
    175  auto absolute_capture_time =
    176      transport_.last_sent_packet()
    177          .GetExtension<AbsoluteCaptureTimeExtension>();
    178  ASSERT_TRUE(absolute_capture_time);
    179  EXPECT_EQ(NtpTime(absolute_capture_time->absolute_capture_timestamp),
    180            fake_clock_.ConvertTimestampToNtpTime(kAbsoluteCaptureTimestamp));
    181  EXPECT_EQ(absolute_capture_time->estimated_capture_clock_offset, 0);
    182 }
    183 
    184 // As RFC4733, named telephone events are carried as part of the audio stream
    185 // and must use the same sequence number and timestamp base as the regular
    186 // audio channel.
    187 // This test checks the marker bit for the first packet and the consequent
    188 // packets of the same telephone event. Since it is specifically for DTMF
    189 // events, ignoring audio packets and sending kEmptyFrame instead of those.
    190 TEST_F(RtpSenderAudioTest, CheckMarkerBitForTelephoneEvents) {
    191  const char* kDtmfPayloadName = "telephone-event";
    192  const uint32_t kPayloadFrequency = 8000;
    193  const uint8_t kPayloadType = 126;
    194  ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
    195                   kDtmfPayloadName, kPayloadType, kPayloadFrequency, 0, 0));
    196  // For Telephone events, payload is not added to the registered payload list,
    197  // it will register only the payload used for audio stream.
    198  // Registering the payload again for audio stream with different payload name.
    199  const char* kPayloadName = "payload_name";
    200  ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
    201                   kPayloadName, kPayloadType, kPayloadFrequency, 1, 0));
    202  // Start time is arbitrary.
    203  uint32_t capture_timestamp = 12345;
    204  // DTMF event key=9, duration=500 and attenuationdB=10
    205  rtp_sender_audio_->SendTelephoneEvent(9, 500, 10);
    206  // During start, it takes the starting timestamp as last sent timestamp.
    207  // The duration is calculated as the difference of current and last sent
    208  // timestamp. So for first call it will skip since the duration is zero.
    209  ASSERT_TRUE(
    210      rtp_sender_audio_->SendAudio({.type = AudioFrameType::kEmptyFrame,
    211                                    .payload_id = kPayloadType,
    212                                    .rtp_timestamp = capture_timestamp}));
    213 
    214  // DTMF Sample Length is (Frequency/1000) * Duration.
    215  // So in this case, it is (8000/1000) * 500 = 4000.
    216  // Sending it as two packets.
    217  ASSERT_TRUE(rtp_sender_audio_->SendAudio(
    218      {.type = AudioFrameType::kEmptyFrame,
    219       .payload_id = kPayloadType,
    220       .rtp_timestamp = capture_timestamp + 2000}));
    221 
    222  // Marker Bit should be set to 1 for first packet.
    223  EXPECT_TRUE(transport_.last_sent_packet().Marker());
    224 
    225  ASSERT_TRUE(rtp_sender_audio_->SendAudio(
    226      {.type = AudioFrameType::kEmptyFrame,
    227       .payload_id = kPayloadType,
    228       .rtp_timestamp = capture_timestamp + 4000}));
    229 
    230  // Marker Bit should be set to 0 for rest of the packets.
    231  EXPECT_FALSE(transport_.last_sent_packet().Marker());
    232 }
    233 
    234 TEST_F(RtpSenderAudioTest, SendsCsrcs) {
    235  const char payload_name[] = "audio";
    236  const uint8_t payload_type = 127;
    237  ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
    238                   payload_name, payload_type, 48000, 0, 1500));
    239  uint8_t payload[] = {47, 11, 32, 93, 89};
    240 
    241  std::vector<uint32_t> csrcs({123, 456, 789});
    242 
    243  ASSERT_TRUE(rtp_sender_audio_->SendAudio(
    244      {.payload = payload, .payload_id = payload_type, .csrcs = csrcs}));
    245 
    246  EXPECT_EQ(transport_.last_sent_packet().Csrcs(), csrcs);
    247 }
    248 
    249 }  // namespace webrtc