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