• 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 
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/include/receive_statistics.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 #include "webrtc/modules/rtp_rtcp/test/testAPI/test_api.h"
22 
23 namespace webrtc {
24 namespace {
25 
26 const uint64_t kTestPictureId = 12345678;
27 const uint8_t kSliPictureId = 156;
28 
29 class RtcpCallback : public RtcpIntraFrameObserver {
30  public:
SetModule(RtpRtcp * module)31   void SetModule(RtpRtcp* module) {
32     _rtpRtcpModule = module;
33   }
OnRTCPPacketTimeout(const int32_t id)34   virtual void OnRTCPPacketTimeout(const int32_t id) {
35   }
OnLipSyncUpdate(const int32_t id,const int32_t audioVideoOffset)36   virtual void OnLipSyncUpdate(const int32_t id,
37                                const int32_t audioVideoOffset) {}
OnReceivedIntraFrameRequest(uint32_t ssrc)38   virtual void OnReceivedIntraFrameRequest(uint32_t ssrc) {}
OnReceivedSLI(uint32_t ssrc,uint8_t pictureId)39   virtual void OnReceivedSLI(uint32_t ssrc,
40                              uint8_t pictureId) {
41     EXPECT_EQ(kSliPictureId & 0x3f, pictureId);
42   }
OnReceivedRPSI(uint32_t ssrc,uint64_t pictureId)43   virtual void OnReceivedRPSI(uint32_t ssrc,
44                               uint64_t pictureId) {
45     EXPECT_EQ(kTestPictureId, pictureId);
46   }
OnLocalSsrcChanged(uint32_t old_ssrc,uint32_t new_ssrc)47   virtual void OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc) {}
48 
49  private:
50   RtpRtcp* _rtpRtcpModule;
51 };
52 
53 class TestRtpFeedback : public NullRtpFeedback {
54  public:
TestRtpFeedback(RtpRtcp * rtp_rtcp)55   explicit TestRtpFeedback(RtpRtcp* rtp_rtcp) : rtp_rtcp_(rtp_rtcp) {}
~TestRtpFeedback()56   virtual ~TestRtpFeedback() {}
57 
OnIncomingSSRCChanged(const uint32_t ssrc)58   void OnIncomingSSRCChanged(const uint32_t ssrc) override {
59     rtp_rtcp_->SetRemoteSSRC(ssrc);
60   }
61 
62  private:
63   RtpRtcp* rtp_rtcp_;
64 };
65 
66 class RtpRtcpRtcpTest : public ::testing::Test {
67  protected:
RtpRtcpRtcpTest()68   RtpRtcpRtcpTest() : fake_clock(123456) {
69     test_csrcs.push_back(1234);
70     test_csrcs.push_back(2345);
71     test_ssrc = 3456;
72     test_timestamp = 4567;
73     test_sequence_number = 2345;
74   }
~RtpRtcpRtcpTest()75   ~RtpRtcpRtcpTest() {}
76 
SetUp()77   virtual void SetUp() {
78     receiver = new TestRtpReceiver();
79     transport1 = new LoopBackTransport();
80     transport2 = new LoopBackTransport();
81     myRTCPFeedback1 = new RtcpCallback();
82     myRTCPFeedback2 = new RtcpCallback();
83 
84     receive_statistics1_.reset(ReceiveStatistics::Create(&fake_clock));
85     receive_statistics2_.reset(ReceiveStatistics::Create(&fake_clock));
86 
87     RtpRtcp::Configuration configuration;
88     configuration.audio = true;
89     configuration.clock = &fake_clock;
90     configuration.receive_statistics = receive_statistics1_.get();
91     configuration.outgoing_transport = transport1;
92     configuration.intra_frame_callback = myRTCPFeedback1;
93 
94     rtp_payload_registry1_.reset(new RTPPayloadRegistry(
95             RTPPayloadStrategy::CreateStrategy(true)));
96     rtp_payload_registry2_.reset(new RTPPayloadRegistry(
97             RTPPayloadStrategy::CreateStrategy(true)));
98 
99     module1 = RtpRtcp::CreateRtpRtcp(configuration);
100 
101     rtp_feedback1_.reset(new TestRtpFeedback(module1));
102 
103     rtp_receiver1_.reset(RtpReceiver::CreateAudioReceiver(
104         &fake_clock, NULL, receiver, rtp_feedback1_.get(),
105         rtp_payload_registry1_.get()));
106 
107     configuration.receive_statistics = receive_statistics2_.get();
108     configuration.outgoing_transport = transport2;
109     configuration.intra_frame_callback = myRTCPFeedback2;
110 
111     module2 = RtpRtcp::CreateRtpRtcp(configuration);
112 
113     rtp_feedback2_.reset(new TestRtpFeedback(module2));
114 
115     rtp_receiver2_.reset(RtpReceiver::CreateAudioReceiver(
116         &fake_clock, NULL, receiver, rtp_feedback2_.get(),
117         rtp_payload_registry2_.get()));
118 
119     transport1->SetSendModule(module2, rtp_payload_registry2_.get(),
120                               rtp_receiver2_.get(), receive_statistics2_.get());
121     transport2->SetSendModule(module1, rtp_payload_registry1_.get(),
122                               rtp_receiver1_.get(), receive_statistics1_.get());
123     myRTCPFeedback1->SetModule(module1);
124     myRTCPFeedback2->SetModule(module2);
125 
126     module1->SetRTCPStatus(RtcpMode::kCompound);
127     module2->SetRTCPStatus(RtcpMode::kCompound);
128 
129     module2->SetSSRC(test_ssrc + 1);
130     module1->SetSSRC(test_ssrc);
131     module1->SetSequenceNumber(test_sequence_number);
132     module1->SetStartTimestamp(test_timestamp);
133 
134     module1->SetCsrcs(test_csrcs);
135     EXPECT_EQ(0, module1->SetCNAME("john.doe@test.test"));
136 
137     EXPECT_EQ(0, module1->SetSendingStatus(true));
138 
139     CodecInst voice_codec;
140     voice_codec.pltype = 96;
141     voice_codec.plfreq = 8000;
142     voice_codec.rate = 64000;
143     memcpy(voice_codec.plname, "PCMU", 5);
144 
145     EXPECT_EQ(0, module1->RegisterSendPayload(voice_codec));
146     EXPECT_EQ(0, rtp_receiver1_->RegisterReceivePayload(
147         voice_codec.plname,
148         voice_codec.pltype,
149         voice_codec.plfreq,
150         voice_codec.channels,
151         (voice_codec.rate < 0) ? 0 : voice_codec.rate));
152     EXPECT_EQ(0, module2->RegisterSendPayload(voice_codec));
153     EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload(
154         voice_codec.plname,
155         voice_codec.pltype,
156         voice_codec.plfreq,
157         voice_codec.channels,
158         (voice_codec.rate < 0) ? 0 : voice_codec.rate));
159 
160     // We need to send one RTP packet to get the RTCP packet to be accepted by
161     // the receiving module.
162     // send RTP packet with the data "testtest"
163     const uint8_t test[9] = "testtest";
164     EXPECT_EQ(0, module1->SendOutgoingData(webrtc::kAudioFrameSpeech, 96,
165                                            0, -1, test, 8));
166   }
167 
TearDown()168   virtual void TearDown() {
169     delete module1;
170     delete module2;
171     delete myRTCPFeedback1;
172     delete myRTCPFeedback2;
173     delete transport1;
174     delete transport2;
175     delete receiver;
176   }
177 
178   rtc::scoped_ptr<TestRtpFeedback> rtp_feedback1_;
179   rtc::scoped_ptr<TestRtpFeedback> rtp_feedback2_;
180   rtc::scoped_ptr<ReceiveStatistics> receive_statistics1_;
181   rtc::scoped_ptr<ReceiveStatistics> receive_statistics2_;
182   rtc::scoped_ptr<RTPPayloadRegistry> rtp_payload_registry1_;
183   rtc::scoped_ptr<RTPPayloadRegistry> rtp_payload_registry2_;
184   rtc::scoped_ptr<RtpReceiver> rtp_receiver1_;
185   rtc::scoped_ptr<RtpReceiver> rtp_receiver2_;
186   RtpRtcp* module1;
187   RtpRtcp* module2;
188   TestRtpReceiver* receiver;
189   LoopBackTransport* transport1;
190   LoopBackTransport* transport2;
191   RtcpCallback* myRTCPFeedback1;
192   RtcpCallback* myRTCPFeedback2;
193 
194   uint32_t test_ssrc;
195   uint32_t test_timestamp;
196   uint16_t test_sequence_number;
197   std::vector<uint32_t> test_csrcs;
198   SimulatedClock fake_clock;
199 };
200 
TEST_F(RtpRtcpRtcpTest,RTCP_PLI_RPSI)201 TEST_F(RtpRtcpRtcpTest, RTCP_PLI_RPSI) {
202   EXPECT_EQ(0, module1->SendRTCPReferencePictureSelection(kTestPictureId));
203   EXPECT_EQ(0, module1->SendRTCPSliceLossIndication(kSliPictureId));
204 }
205 
TEST_F(RtpRtcpRtcpTest,RTCP_CNAME)206 TEST_F(RtpRtcpRtcpTest, RTCP_CNAME) {
207   uint32_t testOfCSRC[webrtc::kRtpCsrcSize];
208   EXPECT_EQ(2, rtp_receiver2_->CSRCs(testOfCSRC));
209   EXPECT_EQ(test_csrcs[0], testOfCSRC[0]);
210   EXPECT_EQ(test_csrcs[1], testOfCSRC[1]);
211 
212   // Set cname of mixed.
213   EXPECT_EQ(0, module1->AddMixedCNAME(test_csrcs[0], "john@192.168.0.1"));
214   EXPECT_EQ(0, module1->AddMixedCNAME(test_csrcs[1], "jane@192.168.0.2"));
215 
216   EXPECT_EQ(-1, module1->RemoveMixedCNAME(test_csrcs[0] + 1));
217   EXPECT_EQ(0, module1->RemoveMixedCNAME(test_csrcs[1]));
218   EXPECT_EQ(0, module1->AddMixedCNAME(test_csrcs[1], "jane@192.168.0.2"));
219 
220   // send RTCP packet, triggered by timer
221   fake_clock.AdvanceTimeMilliseconds(7500);
222   module1->Process();
223   fake_clock.AdvanceTimeMilliseconds(100);
224   module2->Process();
225 
226   char cName[RTCP_CNAME_SIZE];
227   EXPECT_EQ(-1, module2->RemoteCNAME(rtp_receiver2_->SSRC() + 1, cName));
228 
229   // Check multiple CNAME.
230   EXPECT_EQ(0, module2->RemoteCNAME(rtp_receiver2_->SSRC(), cName));
231   EXPECT_EQ(0, strncmp(cName, "john.doe@test.test", RTCP_CNAME_SIZE));
232 
233   EXPECT_EQ(0, module2->RemoteCNAME(test_csrcs[0], cName));
234   EXPECT_EQ(0, strncmp(cName, "john@192.168.0.1", RTCP_CNAME_SIZE));
235 
236   EXPECT_EQ(0, module2->RemoteCNAME(test_csrcs[1], cName));
237   EXPECT_EQ(0, strncmp(cName, "jane@192.168.0.2", RTCP_CNAME_SIZE));
238 
239   EXPECT_EQ(0, module1->SetSendingStatus(false));
240 
241   // Test that BYE clears the CNAME
242   EXPECT_EQ(-1, module2->RemoteCNAME(rtp_receiver2_->SSRC(), cName));
243 }
244 
TEST_F(RtpRtcpRtcpTest,RemoteRTCPStatRemote)245 TEST_F(RtpRtcpRtcpTest, RemoteRTCPStatRemote) {
246   std::vector<RTCPReportBlock> report_blocks;
247 
248   EXPECT_EQ(0, module1->RemoteRTCPStat(&report_blocks));
249   EXPECT_EQ(0u, report_blocks.size());
250 
251   // send RTCP packet, triggered by timer
252   fake_clock.AdvanceTimeMilliseconds(7500);
253   module1->Process();
254   fake_clock.AdvanceTimeMilliseconds(100);
255   module2->Process();
256 
257   EXPECT_EQ(0, module1->RemoteRTCPStat(&report_blocks));
258   ASSERT_EQ(1u, report_blocks.size());
259 
260   // |test_ssrc+1| is the SSRC of module2 that send the report.
261   EXPECT_EQ(test_ssrc+1, report_blocks[0].remoteSSRC);
262   EXPECT_EQ(test_ssrc, report_blocks[0].sourceSSRC);
263 
264   EXPECT_EQ(0u, report_blocks[0].cumulativeLost);
265   EXPECT_LT(0u, report_blocks[0].delaySinceLastSR);
266   EXPECT_EQ(test_sequence_number, report_blocks[0].extendedHighSeqNum);
267   EXPECT_EQ(0u, report_blocks[0].fractionLost);
268 }
269 
270 }  // namespace
271 }  // namespace webrtc
272