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 "webrtc/modules/rtp_rtcp/test/testAPI/test_api.h"
12
13 #include <algorithm>
14 #include <vector>
15
16 #include "webrtc/test/null_transport.h"
17
18 namespace webrtc {
19
SetSendModule(RtpRtcp * rtp_rtcp_module,RTPPayloadRegistry * payload_registry,RtpReceiver * receiver,ReceiveStatistics * receive_statistics)20 void LoopBackTransport::SetSendModule(RtpRtcp* rtp_rtcp_module,
21 RTPPayloadRegistry* payload_registry,
22 RtpReceiver* receiver,
23 ReceiveStatistics* receive_statistics) {
24 rtp_rtcp_module_ = rtp_rtcp_module;
25 rtp_payload_registry_ = payload_registry;
26 rtp_receiver_ = receiver;
27 receive_statistics_ = receive_statistics;
28 }
29
DropEveryNthPacket(int n)30 void LoopBackTransport::DropEveryNthPacket(int n) {
31 packet_loss_ = n;
32 }
33
SendRtp(const uint8_t * data,size_t len,const PacketOptions & options)34 bool LoopBackTransport::SendRtp(const uint8_t* data,
35 size_t len,
36 const PacketOptions& options) {
37 count_++;
38 if (packet_loss_ > 0) {
39 if ((count_ % packet_loss_) == 0) {
40 return true;
41 }
42 }
43 RTPHeader header;
44 rtc::scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
45 if (!parser->Parse(static_cast<const uint8_t*>(data), len, &header)) {
46 return false;
47 }
48 PayloadUnion payload_specific;
49 if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
50 &payload_specific)) {
51 return false;
52 }
53 receive_statistics_->IncomingPacket(header, len, false);
54 if (!rtp_receiver_->IncomingRtpPacket(header,
55 static_cast<const uint8_t*>(data), len,
56 payload_specific, true)) {
57 return false;
58 }
59 return true;
60 }
61
SendRtcp(const uint8_t * data,size_t len)62 bool LoopBackTransport::SendRtcp(const uint8_t* data, size_t len) {
63 if (rtp_rtcp_module_->IncomingRtcpPacket((const uint8_t*)data, len) < 0) {
64 return false;
65 }
66 return true;
67 }
68
OnReceivedPayloadData(const uint8_t * payload_data,const size_t payload_size,const webrtc::WebRtcRTPHeader * rtp_header)69 int32_t TestRtpReceiver::OnReceivedPayloadData(
70 const uint8_t* payload_data,
71 const size_t payload_size,
72 const webrtc::WebRtcRTPHeader* rtp_header) {
73 EXPECT_LE(payload_size, sizeof(payload_data_));
74 memcpy(payload_data_, payload_data, payload_size);
75 memcpy(&rtp_header_, rtp_header, sizeof(rtp_header_));
76 payload_size_ = payload_size;
77 return 0;
78 }
79
80 class RtpRtcpAPITest : public ::testing::Test {
81 protected:
RtpRtcpAPITest()82 RtpRtcpAPITest() : fake_clock_(123456) {
83 test_csrcs_.push_back(1234);
84 test_csrcs_.push_back(2345);
85 test_ssrc_ = 3456;
86 test_timestamp_ = 4567;
87 test_sequence_number_ = 2345;
88 }
~RtpRtcpAPITest()89 ~RtpRtcpAPITest() {}
90
SetUp()91 void SetUp() override {
92 RtpRtcp::Configuration configuration;
93 configuration.audio = true;
94 configuration.clock = &fake_clock_;
95 configuration.outgoing_transport = &null_transport_;
96 module_.reset(RtpRtcp::CreateRtpRtcp(configuration));
97 rtp_payload_registry_.reset(new RTPPayloadRegistry(
98 RTPPayloadStrategy::CreateStrategy(true)));
99 rtp_receiver_.reset(RtpReceiver::CreateAudioReceiver(
100 &fake_clock_, NULL, NULL, NULL, rtp_payload_registry_.get()));
101 }
102
103 rtc::scoped_ptr<RTPPayloadRegistry> rtp_payload_registry_;
104 rtc::scoped_ptr<RtpReceiver> rtp_receiver_;
105 rtc::scoped_ptr<RtpRtcp> module_;
106 uint32_t test_ssrc_;
107 uint32_t test_timestamp_;
108 uint16_t test_sequence_number_;
109 std::vector<uint32_t> test_csrcs_;
110 SimulatedClock fake_clock_;
111 test::NullTransport null_transport_;
112 };
113
TEST_F(RtpRtcpAPITest,Basic)114 TEST_F(RtpRtcpAPITest, Basic) {
115 module_->SetSequenceNumber(test_sequence_number_);
116 EXPECT_EQ(test_sequence_number_, module_->SequenceNumber());
117
118 module_->SetStartTimestamp(test_timestamp_);
119 EXPECT_EQ(test_timestamp_, module_->StartTimestamp());
120
121 EXPECT_FALSE(module_->Sending());
122 EXPECT_EQ(0, module_->SetSendingStatus(true));
123 EXPECT_TRUE(module_->Sending());
124 }
125
TEST_F(RtpRtcpAPITest,MTU)126 TEST_F(RtpRtcpAPITest, MTU) {
127 EXPECT_EQ(0, module_->SetMaxTransferUnit(1234));
128 EXPECT_EQ(1234 - 20 - 8, module_->MaxPayloadLength());
129
130 EXPECT_EQ(0, module_->SetTransportOverhead(true, true, 12));
131 EXPECT_EQ(1234 - 20 - 20 - 20 - 12, module_->MaxPayloadLength());
132
133 EXPECT_EQ(0, module_->SetTransportOverhead(false, false, 0));
134 EXPECT_EQ(1234 - 20 - 8, module_->MaxPayloadLength());
135 }
136
TEST_F(RtpRtcpAPITest,SSRC)137 TEST_F(RtpRtcpAPITest, SSRC) {
138 module_->SetSSRC(test_ssrc_);
139 EXPECT_EQ(test_ssrc_, module_->SSRC());
140 }
141
TEST_F(RtpRtcpAPITest,RTCP)142 TEST_F(RtpRtcpAPITest, RTCP) {
143 EXPECT_EQ(RtcpMode::kOff, module_->RTCP());
144 module_->SetRTCPStatus(RtcpMode::kCompound);
145 EXPECT_EQ(RtcpMode::kCompound, module_->RTCP());
146
147 EXPECT_EQ(0, module_->SetCNAME("john.doe@test.test"));
148
149 EXPECT_FALSE(module_->TMMBR());
150 module_->SetTMMBRStatus(true);
151 EXPECT_TRUE(module_->TMMBR());
152 module_->SetTMMBRStatus(false);
153 EXPECT_FALSE(module_->TMMBR());
154
155 EXPECT_EQ(kNackOff, rtp_receiver_->NACK());
156 rtp_receiver_->SetNACKStatus(kNackRtcp);
157 EXPECT_EQ(kNackRtcp, rtp_receiver_->NACK());
158 }
159
TEST_F(RtpRtcpAPITest,RtxSender)160 TEST_F(RtpRtcpAPITest, RtxSender) {
161 module_->SetRtxSendStatus(kRtxRetransmitted);
162 EXPECT_EQ(kRtxRetransmitted, module_->RtxSendStatus());
163
164 module_->SetRtxSendStatus(kRtxOff);
165 EXPECT_EQ(kRtxOff, module_->RtxSendStatus());
166
167 module_->SetRtxSendStatus(kRtxRetransmitted);
168 EXPECT_EQ(kRtxRetransmitted, module_->RtxSendStatus());
169 }
170
TEST_F(RtpRtcpAPITest,RtxReceiver)171 TEST_F(RtpRtcpAPITest, RtxReceiver) {
172 const uint32_t kRtxSsrc = 1;
173 const int kRtxPayloadType = 119;
174 const int kPayloadType = 100;
175 EXPECT_FALSE(rtp_payload_registry_->RtxEnabled());
176 rtp_payload_registry_->SetRtxSsrc(kRtxSsrc);
177 rtp_payload_registry_->SetRtxPayloadType(kRtxPayloadType, kPayloadType);
178 EXPECT_TRUE(rtp_payload_registry_->RtxEnabled());
179 RTPHeader rtx_header;
180 rtx_header.ssrc = kRtxSsrc;
181 rtx_header.payloadType = kRtxPayloadType;
182 EXPECT_TRUE(rtp_payload_registry_->IsRtx(rtx_header));
183 rtx_header.ssrc = 0;
184 EXPECT_FALSE(rtp_payload_registry_->IsRtx(rtx_header));
185 rtx_header.ssrc = kRtxSsrc;
186 rtx_header.payloadType = 0;
187 EXPECT_TRUE(rtp_payload_registry_->IsRtx(rtx_header));
188 }
189
190 } // namespace webrtc
191