• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&timestamp));
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