test_api_rtcp.cc revision d16e839c6d29831e79312180085b6a19149df43f
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
14#include "testing/gmock/include/gmock/gmock.h"
15#include "testing/gtest/include/gtest/gtest.h"
16#include "webrtc/common_types.h"
17#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.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#include "webrtc/modules/rtp_rtcp/test/testAPI/test_api.h"
22
23using namespace webrtc;
24
25const uint64_t kTestPictureId = 12345678;
26
27class RtcpCallback : public RtcpIntraFrameObserver {
28 public:
29  void SetModule(RtpRtcp* module) {
30    _rtpRtcpModule = module;
31  };
32  virtual void OnRTCPPacketTimeout(const int32_t id) {
33  }
34  virtual void OnLipSyncUpdate(const int32_t id,
35                               const int32_t audioVideoOffset) {
36  };
37  virtual void OnReceivedIntraFrameRequest(uint32_t ssrc) {
38  };
39  virtual void OnReceivedSLI(uint32_t ssrc,
40                             uint8_t pictureId) {
41    EXPECT_EQ(28, pictureId);
42  };
43  virtual void OnReceivedRPSI(uint32_t ssrc,
44                              uint64_t pictureId) {
45    EXPECT_EQ(kTestPictureId, pictureId);
46  };
47  virtual void OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc) {};
48 private:
49  RtpRtcp* _rtpRtcpModule;
50};
51
52class TestRtpFeedback : public NullRtpFeedback {
53 public:
54  TestRtpFeedback(RtpRtcp* rtp_rtcp) : rtp_rtcp_(rtp_rtcp) {}
55  virtual ~TestRtpFeedback() {}
56
57  virtual void OnIncomingSSRCChanged(const int32_t id,
58                                     const uint32_t ssrc) {
59    rtp_rtcp_->SetRemoteSSRC(ssrc);
60  }
61
62 private:
63  RtpRtcp* rtp_rtcp_;
64};
65
66class RtpRtcpRtcpTest : public ::testing::Test {
67 protected:
68  RtpRtcpRtcpTest() : fake_clock(123456) {
69    test_csrcs.push_back(1234);
70    test_csrcs.push_back(2345);
71    test_id = 123;
72    test_ssrc = 3456;
73    test_timestamp = 4567;
74    test_sequence_number = 2345;
75  }
76  ~RtpRtcpRtcpTest() {}
77
78  virtual void SetUp() {
79    receiver = new TestRtpReceiver();
80    transport1 = new LoopBackTransport();
81    transport2 = new LoopBackTransport();
82    myRTCPFeedback1 = new RtcpCallback();
83    myRTCPFeedback2 = new RtcpCallback();
84
85    receive_statistics1_.reset(ReceiveStatistics::Create(&fake_clock));
86    receive_statistics2_.reset(ReceiveStatistics::Create(&fake_clock));
87
88    RtpRtcp::Configuration configuration;
89    configuration.id = test_id;
90    configuration.audio = true;
91    configuration.clock = &fake_clock;
92    configuration.receive_statistics = receive_statistics1_.get();
93    configuration.outgoing_transport = transport1;
94    configuration.intra_frame_callback = myRTCPFeedback1;
95
96    rtp_payload_registry1_.reset(new RTPPayloadRegistry(
97            RTPPayloadStrategy::CreateStrategy(true)));
98    rtp_payload_registry2_.reset(new RTPPayloadRegistry(
99            RTPPayloadStrategy::CreateStrategy(true)));
100
101    module1 = RtpRtcp::CreateRtpRtcp(configuration);
102
103    rtp_feedback1_.reset(new TestRtpFeedback(module1));
104
105    rtp_receiver1_.reset(RtpReceiver::CreateAudioReceiver(
106        test_id, &fake_clock, NULL, receiver, rtp_feedback1_.get(),
107        rtp_payload_registry1_.get()));
108
109    configuration.receive_statistics = receive_statistics2_.get();
110    configuration.id = test_id + 1;
111    configuration.outgoing_transport = transport2;
112    configuration.intra_frame_callback = myRTCPFeedback2;
113
114    module2 = RtpRtcp::CreateRtpRtcp(configuration);
115
116    rtp_feedback2_.reset(new TestRtpFeedback(module2));
117
118    rtp_receiver2_.reset(RtpReceiver::CreateAudioReceiver(
119        test_id + 1, &fake_clock, NULL, receiver, rtp_feedback2_.get(),
120        rtp_payload_registry2_.get()));
121
122    transport1->SetSendModule(module2, rtp_payload_registry2_.get(),
123                              rtp_receiver2_.get(), receive_statistics2_.get());
124    transport2->SetSendModule(module1, rtp_payload_registry1_.get(),
125                              rtp_receiver1_.get(), receive_statistics1_.get());
126    myRTCPFeedback1->SetModule(module1);
127    myRTCPFeedback2->SetModule(module2);
128
129    module1->SetRTCPStatus(kRtcpCompound);
130    module2->SetRTCPStatus(kRtcpCompound);
131
132    module2->SetSSRC(test_ssrc + 1);
133    module1->SetSSRC(test_ssrc);
134    module1->SetSequenceNumber(test_sequence_number);
135    module1->SetStartTimestamp(test_timestamp);
136
137    module1->SetCsrcs(test_csrcs);
138    EXPECT_EQ(0, module1->SetCNAME("john.doe@test.test"));
139
140    EXPECT_EQ(0, module1->SetSendingStatus(true));
141
142    CodecInst voice_codec;
143    voice_codec.pltype = 96;
144    voice_codec.plfreq = 8000;
145    voice_codec.rate = 64000;
146    memcpy(voice_codec.plname, "PCMU", 5);
147
148    EXPECT_EQ(0, module1->RegisterSendPayload(voice_codec));
149    EXPECT_EQ(0, rtp_receiver1_->RegisterReceivePayload(
150        voice_codec.plname,
151        voice_codec.pltype,
152        voice_codec.plfreq,
153        voice_codec.channels,
154        (voice_codec.rate < 0) ? 0 : voice_codec.rate));
155    EXPECT_EQ(0, module2->RegisterSendPayload(voice_codec));
156    EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload(
157        voice_codec.plname,
158        voice_codec.pltype,
159        voice_codec.plfreq,
160        voice_codec.channels,
161        (voice_codec.rate < 0) ? 0 : voice_codec.rate));
162
163    // We need to send one RTP packet to get the RTCP packet to be accepted by
164    // the receiving module.
165    // send RTP packet with the data "testtest"
166    const uint8_t test[9] = "testtest";
167    EXPECT_EQ(0, module1->SendOutgoingData(webrtc::kAudioFrameSpeech, 96,
168                                           0, -1, test, 8));
169  }
170
171  virtual void TearDown() {
172    delete module1;
173    delete module2;
174    delete myRTCPFeedback1;
175    delete myRTCPFeedback2;
176    delete transport1;
177    delete transport2;
178    delete receiver;
179  }
180
181  int test_id;
182  scoped_ptr<TestRtpFeedback> rtp_feedback1_;
183  scoped_ptr<TestRtpFeedback> rtp_feedback2_;
184  scoped_ptr<ReceiveStatistics> receive_statistics1_;
185  scoped_ptr<ReceiveStatistics> receive_statistics2_;
186  scoped_ptr<RTPPayloadRegistry> rtp_payload_registry1_;
187  scoped_ptr<RTPPayloadRegistry> rtp_payload_registry2_;
188  scoped_ptr<RtpReceiver> rtp_receiver1_;
189  scoped_ptr<RtpReceiver> rtp_receiver2_;
190  RtpRtcp* module1;
191  RtpRtcp* module2;
192  TestRtpReceiver* receiver;
193  LoopBackTransport* transport1;
194  LoopBackTransport* transport2;
195  RtcpCallback* myRTCPFeedback1;
196  RtcpCallback* myRTCPFeedback2;
197
198  uint32_t test_ssrc;
199  uint32_t test_timestamp;
200  uint16_t test_sequence_number;
201  std::vector<uint32_t> test_csrcs;
202  SimulatedClock fake_clock;
203};
204
205TEST_F(RtpRtcpRtcpTest, RTCP_PLI_RPSI) {
206  EXPECT_EQ(0, module1->SendRTCPReferencePictureSelection(kTestPictureId));
207  EXPECT_EQ(0, module1->SendRTCPSliceLossIndication(156));
208}
209
210TEST_F(RtpRtcpRtcpTest, RTCP_CNAME) {
211  uint32_t testOfCSRC[webrtc::kRtpCsrcSize];
212  EXPECT_EQ(2, rtp_receiver2_->CSRCs(testOfCSRC));
213  EXPECT_EQ(test_csrcs[0], testOfCSRC[0]);
214  EXPECT_EQ(test_csrcs[1], testOfCSRC[1]);
215
216  // Set cname of mixed.
217  EXPECT_EQ(0, module1->AddMixedCNAME(test_csrcs[0], "john@192.168.0.1"));
218  EXPECT_EQ(0, module1->AddMixedCNAME(test_csrcs[1], "jane@192.168.0.2"));
219
220  EXPECT_EQ(-1, module1->RemoveMixedCNAME(test_csrcs[0] + 1));
221  EXPECT_EQ(0, module1->RemoveMixedCNAME(test_csrcs[1]));
222  EXPECT_EQ(0, module1->AddMixedCNAME(test_csrcs[1], "jane@192.168.0.2"));
223
224  // send RTCP packet, triggered by timer
225  fake_clock.AdvanceTimeMilliseconds(7500);
226  module1->Process();
227  fake_clock.AdvanceTimeMilliseconds(100);
228  module2->Process();
229
230  char cName[RTCP_CNAME_SIZE];
231  EXPECT_EQ(-1, module2->RemoteCNAME(rtp_receiver2_->SSRC() + 1, cName));
232
233  // Check multiple CNAME.
234  EXPECT_EQ(0, module2->RemoteCNAME(rtp_receiver2_->SSRC(), cName));
235  EXPECT_EQ(0, strncmp(cName, "john.doe@test.test", RTCP_CNAME_SIZE));
236
237  EXPECT_EQ(0, module2->RemoteCNAME(test_csrcs[0], cName));
238  EXPECT_EQ(0, strncmp(cName, "john@192.168.0.1", RTCP_CNAME_SIZE));
239
240  EXPECT_EQ(0, module2->RemoteCNAME(test_csrcs[1], cName));
241  EXPECT_EQ(0, strncmp(cName, "jane@192.168.0.2", RTCP_CNAME_SIZE));
242
243  EXPECT_EQ(0, module1->SetSendingStatus(false));
244
245  // Test that BYE clears the CNAME
246  EXPECT_EQ(-1, module2->RemoteCNAME(rtp_receiver2_->SSRC(), cName));
247}
248
249TEST_F(RtpRtcpRtcpTest, RTCP) {
250  RTCPReportBlock reportBlock;
251  reportBlock.remoteSSRC = 1;
252  reportBlock.sourceSSRC = 2;
253  reportBlock.cumulativeLost = 1;
254  reportBlock.delaySinceLastSR = 2;
255  reportBlock.extendedHighSeqNum = 3;
256  reportBlock.fractionLost= 4;
257  reportBlock.jitter = 5;
258  reportBlock.lastSR = 6;
259
260  // Set report blocks.
261  EXPECT_EQ(0, module1->AddRTCPReportBlock(test_csrcs[0], &reportBlock));
262
263  reportBlock.lastSR= 7;
264  EXPECT_EQ(0, module1->AddRTCPReportBlock(test_csrcs[1], &reportBlock));
265
266  uint32_t name = 't' << 24;
267  name += 'e' << 16;
268  name += 's' << 8;
269  name += 't';
270  EXPECT_EQ(0, module1->SetRTCPApplicationSpecificData(
271      3,
272      name,
273      (const uint8_t *)"test test test test test test test test test"\
274          " test test test test test test test test test test test test test"\
275          " test test test test test test test test test test test test test"\
276          " test test test test test test test test test test test test test"\
277          " test test test test test test test test test test test test ",
278          300));
279
280  // send RTCP packet, triggered by timer
281  fake_clock.AdvanceTimeMilliseconds(7500);
282  module1->Process();
283  fake_clock.AdvanceTimeMilliseconds(100);
284  module2->Process();
285
286  uint32_t receivedNTPsecs = 0;
287  uint32_t receivedNTPfrac = 0;
288  uint32_t RTCPArrivalTimeSecs = 0;
289  uint32_t RTCPArrivalTimeFrac = 0;
290  EXPECT_EQ(0, module2->RemoteNTP(&receivedNTPsecs,
291                                  &receivedNTPfrac,
292                                  &RTCPArrivalTimeSecs,
293                                  &RTCPArrivalTimeFrac,
294                                  NULL));
295
296
297  // get all report blocks
298  std::vector<RTCPReportBlock> report_blocks;
299  EXPECT_EQ(0, module1->RemoteRTCPStat(&report_blocks));
300  ASSERT_EQ(1u, report_blocks.size());
301  const RTCPReportBlock& reportBlockReceived = report_blocks[0];
302
303  float secSinceLastReport =
304      static_cast<float>(reportBlockReceived.delaySinceLastSR) / 65536.0f;
305  EXPECT_GE(0.101f, secSinceLastReport);
306  EXPECT_LE(0.100f, secSinceLastReport);
307  EXPECT_EQ(test_sequence_number, reportBlockReceived.extendedHighSeqNum);
308  EXPECT_EQ(0, reportBlockReceived.fractionLost);
309
310  EXPECT_EQ(static_cast<uint32_t>(0),
311            reportBlockReceived.cumulativeLost);
312
313  StreamStatistician *statistician =
314      receive_statistics2_->GetStatistician(reportBlockReceived.sourceSSRC);
315  RtcpStatistics stats;
316  EXPECT_TRUE(statistician->GetStatistics(&stats, true));
317  EXPECT_EQ(0, stats.fraction_lost);
318  EXPECT_EQ((uint32_t)0, stats.cumulative_lost);
319  EXPECT_EQ(test_sequence_number, stats.extended_max_sequence_number);
320  EXPECT_EQ(reportBlockReceived.jitter, stats.jitter);
321
322  uint16_t RTT;
323  uint16_t avgRTT;
324  uint16_t minRTT;
325  uint16_t maxRTT;
326
327  // Get RoundTripTime.
328  EXPECT_EQ(0, module1->RTT(test_ssrc + 1, &RTT, &avgRTT, &minRTT, &maxRTT));
329  EXPECT_GE(10, RTT);
330  EXPECT_GE(10, avgRTT);
331  EXPECT_GE(10, minRTT);
332  EXPECT_GE(10, maxRTT);
333
334  // Set report blocks.
335  EXPECT_EQ(0, module1->AddRTCPReportBlock(test_csrcs[0], &reportBlock));
336
337  // Test receive report.
338  EXPECT_EQ(0, module1->SetSendingStatus(false));
339
340  // Send RTCP packet, triggered by timer.
341  fake_clock.AdvanceTimeMilliseconds(5000);
342  module1->Process();
343  module2->Process();
344}
345
346TEST_F(RtpRtcpRtcpTest, RemoteRTCPStatRemote) {
347  std::vector<RTCPReportBlock> report_blocks;
348
349  EXPECT_EQ(0, module1->RemoteRTCPStat(&report_blocks));
350  EXPECT_EQ(0u, report_blocks.size());
351
352  // send RTCP packet, triggered by timer
353  fake_clock.AdvanceTimeMilliseconds(7500);
354  module1->Process();
355  fake_clock.AdvanceTimeMilliseconds(100);
356  module2->Process();
357
358  EXPECT_EQ(0, module1->RemoteRTCPStat(&report_blocks));
359  ASSERT_EQ(1u, report_blocks.size());
360
361  // |test_ssrc+1| is the SSRC of module2 that send the report.
362  EXPECT_EQ(test_ssrc+1, report_blocks[0].remoteSSRC);
363  EXPECT_EQ(test_ssrc, report_blocks[0].sourceSSRC);
364
365  EXPECT_EQ(0u, report_blocks[0].cumulativeLost);
366  EXPECT_LT(0u, report_blocks[0].delaySinceLastSR);
367  EXPECT_EQ(test_sequence_number, report_blocks[0].extendedHighSeqNum);
368  EXPECT_EQ(0u, report_blocks[0].fractionLost);
369}
370