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
22using namespace webrtc;
23
24#define test_rate 64000u
25
26class VerifyingAudioReceiver : public NullRtpData {
27 public:
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
62class RTPCallback : public NullRtpFeedback {
63 public:
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
79class AudioFeedback : public NullRtpAudioFeedback {
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
101class RtpRtcpAudioTest : public ::testing::Test {
102 protected:
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  }
111  ~RtpRtcpAudioTest() {}
112
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
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
191TEST_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
240TEST_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
313TEST_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