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
22 namespace webrtc {
23 namespace {
24 #define test_rate 64000u
25
26 class VerifyingAudioReceiver : public NullRtpData {
27 public:
OnReceivedPayloadData(const uint8_t * payloadData,const size_t payloadSize,const webrtc::WebRtcRTPHeader * rtpHeader)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
62 class RTPCallback : public NullRtpFeedback {
63 public:
OnInitializeDecoder(const int8_t payloadType,const char payloadName[RTP_PAYLOAD_NAME_SIZE],const int frequency,const size_t channels,const uint32_t rate)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
77 class RtpRtcpAudioTest : public ::testing::Test {
78 protected:
RtpRtcpAudioTest()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 }
~RtpRtcpAudioTest()86 ~RtpRtcpAudioTest() {}
87
SetUp()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
TearDown()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
TEST_F(RtpRtcpAudioTest,Basic)163 TEST_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
TEST_F(RtpRtcpAudioTest,RED)211 TEST_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
TEST_F(RtpRtcpAudioTest,DTMF)284 TEST_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