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