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
22namespace webrtc {
23namespace {
24#define test_rate 64000u
25
26class VerifyingAudioReceiver : public NullRtpData {
27 public:
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
62class RTPCallback : public NullRtpFeedback {
63 public:
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
77class RtpRtcpAudioTest : public ::testing::Test {
78 protected:
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  }
86  ~RtpRtcpAudioTest() {}
87
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
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
163TEST_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
211TEST_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
284TEST_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