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