• 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/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(&timestamp));
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