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 23namespace webrtc { 24namespace { 25 26const uint64_t kTestPictureId = 12345678; 27const uint8_t kSliPictureId = 156; 28 29class RtcpCallback : public RtcpIntraFrameObserver { 30 public: 31 void SetModule(RtpRtcp* module) { 32 _rtpRtcpModule = module; 33 } 34 virtual void OnRTCPPacketTimeout(const int32_t id) { 35 } 36 virtual void OnLipSyncUpdate(const int32_t id, 37 const int32_t audioVideoOffset) {} 38 virtual void OnReceivedIntraFrameRequest(uint32_t ssrc) {} 39 virtual void OnReceivedSLI(uint32_t ssrc, 40 uint8_t pictureId) { 41 EXPECT_EQ(kSliPictureId & 0x3f, 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 49 private: 50 RtpRtcp* _rtpRtcpModule; 51}; 52 53class TestRtpFeedback : public NullRtpFeedback { 54 public: 55 explicit TestRtpFeedback(RtpRtcp* rtp_rtcp) : rtp_rtcp_(rtp_rtcp) {} 56 virtual ~TestRtpFeedback() {} 57 58 void OnIncomingSSRCChanged(const uint32_t ssrc) override { 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_ssrc = 3456; 72 test_timestamp = 4567; 73 test_sequence_number = 2345; 74 } 75 ~RtpRtcpRtcpTest() {} 76 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 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 201TEST_F(RtpRtcpRtcpTest, RTCP_PLI_RPSI) { 202 EXPECT_EQ(0, module1->SendRTCPReferencePictureSelection(kTestPictureId)); 203 EXPECT_EQ(0, module1->SendRTCPSliceLossIndication(kSliPictureId)); 204} 205 206TEST_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 245TEST_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