1/* 2 * Copyright (c) 2012 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 <algorithm> 12#include <vector> 13#include "testing/gtest/include/gtest/gtest.h" 14 15#include "webrtc/modules/rtp_rtcp/test/testAPI/test_api.h" 16 17#include "webrtc/common_types.h" 18#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" 19#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 20#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h" 21 22namespace webrtc { 23namespace { 24#define test_rate 64000u 25 26class VerifyingAudioReceiver : public NullRtpData { 27 public: 28 int32_t OnReceivedPayloadData( 29 const uint8_t* payloadData, 30 const size_t payloadSize, 31 const webrtc::WebRtcRTPHeader* rtpHeader) override { 32 if (rtpHeader->header.payloadType == 98 || 33 rtpHeader->header.payloadType == 99) { 34 EXPECT_EQ(4u, payloadSize); 35 char str[5]; 36 memcpy(str, payloadData, payloadSize); 37 str[4] = 0; 38 // All our test vectors for payload type 96 and 97 even the stereo is on 39 // a per channel base equal to the 4 chars "test". 40 // Note there is no null termination so we add that to use the 41 // test EXPECT_STRCASEEQ. 42 EXPECT_STRCASEEQ("test", str); 43 return 0; 44 } 45 if (rtpHeader->header.payloadType == 100 || 46 rtpHeader->header.payloadType == 101 || 47 rtpHeader->header.payloadType == 102) { 48 if (rtpHeader->type.Audio.channel == 1) { 49 if (payloadData[0] == 0xff) { 50 // All our test vectors for payload type 100, 101 and 102 have the 51 // first channel data being equal to 0xff. 52 return 0; 53 } 54 } 55 ADD_FAILURE() << "This code path should never happen."; 56 return -1; 57 } 58 return 0; 59 } 60}; 61 62class RTPCallback : public NullRtpFeedback { 63 public: 64 int32_t OnInitializeDecoder(const int8_t payloadType, 65 const char payloadName[RTP_PAYLOAD_NAME_SIZE], 66 const int frequency, 67 const size_t channels, 68 const uint32_t rate) override { 69 if (payloadType == 96) { 70 EXPECT_EQ(test_rate, rate) << 71 "The rate should be 64K for this payloadType"; 72 } 73 return 0; 74 } 75}; 76 77class RtpRtcpAudioTest : public ::testing::Test { 78 protected: 79 RtpRtcpAudioTest() : fake_clock(123456) { 80 test_CSRC[0] = 1234; 81 test_CSRC[2] = 2345; 82 test_ssrc = 3456; 83 test_timestamp = 4567; 84 test_sequence_number = 2345; 85 } 86 ~RtpRtcpAudioTest() {} 87 88 void SetUp() override { 89 audioFeedback = new NullRtpAudioFeedback(); 90 data_receiver1 = new VerifyingAudioReceiver(); 91 data_receiver2 = new VerifyingAudioReceiver(); 92 rtp_callback = new RTPCallback(); 93 transport1 = new LoopBackTransport(); 94 transport2 = new LoopBackTransport(); 95 96 receive_statistics1_.reset(ReceiveStatistics::Create(&fake_clock)); 97 receive_statistics2_.reset(ReceiveStatistics::Create(&fake_clock)); 98 99 rtp_payload_registry1_.reset(new RTPPayloadRegistry( 100 RTPPayloadStrategy::CreateStrategy(true))); 101 rtp_payload_registry2_.reset(new RTPPayloadRegistry( 102 RTPPayloadStrategy::CreateStrategy(true))); 103 104 RtpRtcp::Configuration configuration; 105 configuration.audio = true; 106 configuration.clock = &fake_clock; 107 configuration.receive_statistics = receive_statistics1_.get(); 108 configuration.outgoing_transport = transport1; 109 configuration.audio_messages = audioFeedback; 110 111 module1 = RtpRtcp::CreateRtpRtcp(configuration); 112 rtp_receiver1_.reset(RtpReceiver::CreateAudioReceiver( 113 &fake_clock, audioFeedback, data_receiver1, NULL, 114 rtp_payload_registry1_.get())); 115 116 configuration.receive_statistics = receive_statistics2_.get(); 117 configuration.outgoing_transport = transport2; 118 configuration.audio_messages = audioFeedback; 119 120 module2 = RtpRtcp::CreateRtpRtcp(configuration); 121 rtp_receiver2_.reset(RtpReceiver::CreateAudioReceiver( 122 &fake_clock, audioFeedback, data_receiver2, NULL, 123 rtp_payload_registry2_.get())); 124 125 transport1->SetSendModule(module2, rtp_payload_registry2_.get(), 126 rtp_receiver2_.get(), receive_statistics2_.get()); 127 transport2->SetSendModule(module1, rtp_payload_registry1_.get(), 128 rtp_receiver1_.get(), receive_statistics1_.get()); 129 } 130 131 void TearDown() override { 132 delete module1; 133 delete module2; 134 delete transport1; 135 delete transport2; 136 delete audioFeedback; 137 delete data_receiver1; 138 delete data_receiver2; 139 delete rtp_callback; 140 } 141 142 RtpRtcp* module1; 143 RtpRtcp* module2; 144 rtc::scoped_ptr<ReceiveStatistics> receive_statistics1_; 145 rtc::scoped_ptr<ReceiveStatistics> receive_statistics2_; 146 rtc::scoped_ptr<RtpReceiver> rtp_receiver1_; 147 rtc::scoped_ptr<RtpReceiver> rtp_receiver2_; 148 rtc::scoped_ptr<RTPPayloadRegistry> rtp_payload_registry1_; 149 rtc::scoped_ptr<RTPPayloadRegistry> rtp_payload_registry2_; 150 VerifyingAudioReceiver* data_receiver1; 151 VerifyingAudioReceiver* data_receiver2; 152 LoopBackTransport* transport1; 153 LoopBackTransport* transport2; 154 NullRtpAudioFeedback* audioFeedback; 155 RTPCallback* rtp_callback; 156 uint32_t test_ssrc; 157 uint32_t test_timestamp; 158 uint16_t test_sequence_number; 159 uint32_t test_CSRC[webrtc::kRtpCsrcSize]; 160 SimulatedClock fake_clock; 161}; 162 163TEST_F(RtpRtcpAudioTest, Basic) { 164 module1->SetSSRC(test_ssrc); 165 module1->SetStartTimestamp(test_timestamp); 166 167 // Test detection at the end of a DTMF tone. 168 // EXPECT_EQ(0, module2->SetTelephoneEventForwardToDecoder(true)); 169 170 EXPECT_EQ(0, module1->SetSendingStatus(true)); 171 172 // Start basic RTP test. 173 174 // Send an empty RTP packet. 175 // Should fail since we have not registered the payload type. 176 EXPECT_EQ(-1, module1->SendOutgoingData(webrtc::kAudioFrameSpeech, 177 96, 0, -1, NULL, 0)); 178 179 CodecInst voice_codec; 180 memset(&voice_codec, 0, sizeof(voice_codec)); 181 voice_codec.pltype = 96; 182 voice_codec.plfreq = 8000; 183 memcpy(voice_codec.plname, "PCMU", 5); 184 185 EXPECT_EQ(0, module1->RegisterSendPayload(voice_codec)); 186 EXPECT_EQ(0, rtp_receiver1_->RegisterReceivePayload( 187 voice_codec.plname, 188 voice_codec.pltype, 189 voice_codec.plfreq, 190 voice_codec.channels, 191 (voice_codec.rate < 0) ? 0 : voice_codec.rate)); 192 EXPECT_EQ(0, module2->RegisterSendPayload(voice_codec)); 193 voice_codec.rate = test_rate; 194 EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload( 195 voice_codec.plname, 196 voice_codec.pltype, 197 voice_codec.plfreq, 198 voice_codec.channels, 199 (voice_codec.rate < 0) ? 0 : voice_codec.rate)); 200 201 const uint8_t test[5] = "test"; 202 EXPECT_EQ(0, module1->SendOutgoingData(webrtc::kAudioFrameSpeech, 96, 203 0, -1, test, 4)); 204 205 EXPECT_EQ(test_ssrc, rtp_receiver2_->SSRC()); 206 uint32_t timestamp; 207 EXPECT_TRUE(rtp_receiver2_->Timestamp(×tamp)); 208 EXPECT_EQ(test_timestamp, timestamp); 209} 210 211TEST_F(RtpRtcpAudioTest, RED) { 212 CodecInst voice_codec; 213 memset(&voice_codec, 0, sizeof(voice_codec)); 214 voice_codec.pltype = 96; 215 voice_codec.plfreq = 8000; 216 memcpy(voice_codec.plname, "PCMU", 5); 217 218 EXPECT_EQ(0, module1->RegisterSendPayload(voice_codec)); 219 EXPECT_EQ(0, rtp_receiver1_->RegisterReceivePayload( 220 voice_codec.plname, 221 voice_codec.pltype, 222 voice_codec.plfreq, 223 voice_codec.channels, 224 (voice_codec.rate < 0) ? 0 : voice_codec.rate)); 225 EXPECT_EQ(0, module2->RegisterSendPayload(voice_codec)); 226 voice_codec.rate = test_rate; 227 EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload( 228 voice_codec.plname, 229 voice_codec.pltype, 230 voice_codec.plfreq, 231 voice_codec.channels, 232 (voice_codec.rate < 0) ? 0 : voice_codec.rate)); 233 234 module1->SetSSRC(test_ssrc); 235 module1->SetStartTimestamp(test_timestamp); 236 EXPECT_EQ(0, module1->SetSendingStatus(true)); 237 238 voice_codec.pltype = 127; 239 voice_codec.plfreq = 8000; 240 memcpy(voice_codec.plname, "RED", 4); 241 242 EXPECT_EQ(0, module1->SetSendREDPayloadType(voice_codec.pltype)); 243 int8_t red = 0; 244 EXPECT_EQ(0, module1->SendREDPayloadType(&red)); 245 EXPECT_EQ(voice_codec.pltype, red); 246 EXPECT_EQ(0, rtp_receiver1_->RegisterReceivePayload( 247 voice_codec.plname, 248 voice_codec.pltype, 249 voice_codec.plfreq, 250 voice_codec.channels, 251 (voice_codec.rate < 0) ? 0 : voice_codec.rate)); 252 EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload( 253 voice_codec.plname, 254 voice_codec.pltype, 255 voice_codec.plfreq, 256 voice_codec.channels, 257 (voice_codec.rate < 0) ? 0 : voice_codec.rate)); 258 259 RTPFragmentationHeader fragmentation; 260 fragmentation.fragmentationVectorSize = 2; 261 fragmentation.fragmentationLength = new size_t[2]; 262 fragmentation.fragmentationLength[0] = 4; 263 fragmentation.fragmentationLength[1] = 4; 264 fragmentation.fragmentationOffset = new size_t[2]; 265 fragmentation.fragmentationOffset[0] = 0; 266 fragmentation.fragmentationOffset[1] = 4; 267 fragmentation.fragmentationTimeDiff = new uint16_t[2]; 268 fragmentation.fragmentationTimeDiff[0] = 0; 269 fragmentation.fragmentationTimeDiff[1] = 0; 270 fragmentation.fragmentationPlType = new uint8_t[2]; 271 fragmentation.fragmentationPlType[0] = 96; 272 fragmentation.fragmentationPlType[1] = 96; 273 274 const uint8_t test[5] = "test"; 275 // Send a RTP packet. 276 EXPECT_EQ(0, module1->SendOutgoingData(webrtc::kAudioFrameSpeech, 277 96, 160, -1, test, 4, 278 &fragmentation)); 279 280 EXPECT_EQ(0, module1->SetSendREDPayloadType(-1)); 281 EXPECT_EQ(-1, module1->SendREDPayloadType(&red)); 282} 283 284TEST_F(RtpRtcpAudioTest, DTMF) { 285 CodecInst voice_codec; 286 memset(&voice_codec, 0, sizeof(voice_codec)); 287 voice_codec.pltype = 96; 288 voice_codec.plfreq = 8000; 289 memcpy(voice_codec.plname, "PCMU", 5); 290 291 EXPECT_EQ(0, module1->RegisterSendPayload(voice_codec)); 292 EXPECT_EQ(0, rtp_receiver1_->RegisterReceivePayload( 293 voice_codec.plname, 294 voice_codec.pltype, 295 voice_codec.plfreq, 296 voice_codec.channels, 297 (voice_codec.rate < 0) ? 0 : voice_codec.rate)); 298 EXPECT_EQ(0, module2->RegisterSendPayload(voice_codec)); 299 voice_codec.rate = test_rate; 300 EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload( 301 voice_codec.plname, 302 voice_codec.pltype, 303 voice_codec.plfreq, 304 voice_codec.channels, 305 (voice_codec.rate < 0) ? 0 : voice_codec.rate)); 306 307 module1->SetSSRC(test_ssrc); 308 module1->SetStartTimestamp(test_timestamp); 309 EXPECT_EQ(0, module1->SetSendingStatus(true)); 310 311 // Prepare for DTMF. 312 voice_codec.pltype = 97; 313 voice_codec.plfreq = 8000; 314 memcpy(voice_codec.plname, "telephone-event", 16); 315 316 EXPECT_EQ(0, module1->RegisterSendPayload(voice_codec)); 317 EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload( 318 voice_codec.plname, 319 voice_codec.pltype, 320 voice_codec.plfreq, 321 voice_codec.channels, 322 (voice_codec.rate < 0) ? 0 : voice_codec.rate)); 323 324 // Start DTMF test. 325 uint32_t timeStamp = 160; 326 327 // Send a DTMF tone using RFC 2833 (4733). 328 for (int i = 0; i < 16; i++) { 329 EXPECT_EQ(0, module1->SendTelephoneEventOutband(i, timeStamp, 10)); 330 } 331 timeStamp += 160; // Prepare for next packet. 332 333 const uint8_t test[9] = "test"; 334 335 // Send RTP packets for 16 tones a 160 ms 100ms 336 // pause between = 2560ms + 1600ms = 4160ms 337 for (; timeStamp <= 250 * 160; timeStamp += 160) { 338 EXPECT_EQ(0, module1->SendOutgoingData(webrtc::kAudioFrameSpeech, 96, 339 timeStamp, -1, test, 4)); 340 fake_clock.AdvanceTimeMilliseconds(20); 341 module1->Process(); 342 } 343 EXPECT_EQ(0, module1->SendTelephoneEventOutband(32, 9000, 10)); 344 345 for (; timeStamp <= 740 * 160; timeStamp += 160) { 346 EXPECT_EQ(0, module1->SendOutgoingData(webrtc::kAudioFrameSpeech, 96, 347 timeStamp, -1, test, 4)); 348 fake_clock.AdvanceTimeMilliseconds(20); 349 module1->Process(); 350 } 351} 352 353} // namespace 354} // namespace webrtc 355