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
22 using namespace webrtc;
23
24 #define test_rate 64000u
25
26 class VerifyingAudioReceiver : public NullRtpData {
27 public:
OnReceivedPayloadData(const uint8_t * payloadData,const uint16_t payloadSize,const webrtc::WebRtcRTPHeader * rtpHeader)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
62 class RTPCallback : public NullRtpFeedback {
63 public:
OnInitializeDecoder(const int32_t id,const int8_t payloadType,const char payloadName[RTP_PAYLOAD_NAME_SIZE],const int frequency,const uint8_t channels,const uint32_t rate)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
79 class AudioFeedback : public NullRtpAudioFeedback {
OnReceivedTelephoneEvent(const int32_t id,const uint8_t event,const bool end)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
101 class RtpRtcpAudioTest : public ::testing::Test {
102 protected:
RtpRtcpAudioTest()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 }
~RtpRtcpAudioTest()111 ~RtpRtcpAudioTest() {}
112
SetUp()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
TearDown()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
TEST_F(RtpRtcpAudioTest,Basic)191 TEST_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
TEST_F(RtpRtcpAudioTest,RED)240 TEST_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
TEST_F(RtpRtcpAudioTest,DTMF)313 TEST_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