blob: 589db34565a769d97788c016f1bbed5b466e3ef9 [file] [log] [blame]
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001/*
henrike@webrtc.orgd6d014f2012-02-16 02:18:09 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00003 *
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
kwiberg84be5112016-04-27 01:19:58 -070011#include <memory>
12
Mirko Bonadei71207422017-09-15 13:58:09 +020013#include "common_types.h" // NOLINT(build/include)
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
15#include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
16#include "modules/rtp_rtcp/source/rtcp_sender.h"
17#include "modules/rtp_rtcp/source/rtp_rtcp_impl.h"
18#include "rtc_base/rate_limiter.h"
19#include "test/gmock.h"
20#include "test/gtest.h"
21#include "test/mock_transport.h"
22#include "test/rtcp_packet_parser.h"
asapersson22ff75a2015-08-21 00:02:47 -070023
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -080024using ::testing::_;
asapersson22ff75a2015-08-21 00:02:47 -070025using ::testing::ElementsAre;
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -080026using ::testing::Invoke;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000027
28namespace webrtc {
29
edjee@google.com79b02892013-04-04 19:43:34 +000030TEST(NACKStringBuilderTest, TestCase1) {
31 NACKStringBuilder builder;
32 builder.PushNACK(5);
33 builder.PushNACK(7);
34 builder.PushNACK(9);
35 builder.PushNACK(10);
36 builder.PushNACK(11);
37 builder.PushNACK(12);
38 builder.PushNACK(15);
39 builder.PushNACK(18);
40 builder.PushNACK(19);
41 EXPECT_EQ(std::string("5,7,9-12,15,18-19"), builder.GetResult());
42}
43
44TEST(NACKStringBuilderTest, TestCase2) {
45 NACKStringBuilder builder;
46 builder.PushNACK(5);
47 builder.PushNACK(6);
48 builder.PushNACK(7);
49 builder.PushNACK(9);
50 builder.PushNACK(10);
51 builder.PushNACK(11);
52 builder.PushNACK(12);
53 builder.PushNACK(15);
54 builder.PushNACK(18);
55 builder.PushNACK(19);
56 EXPECT_EQ(std::string("5-7,9-12,15,18-19"), builder.GetResult());
57}
58
59TEST(NACKStringBuilderTest, TestCase3) {
60 NACKStringBuilder builder;
61 builder.PushNACK(5);
62 builder.PushNACK(7);
63 builder.PushNACK(9);
64 builder.PushNACK(10);
65 builder.PushNACK(11);
66 builder.PushNACK(12);
67 builder.PushNACK(15);
68 builder.PushNACK(18);
69 builder.PushNACK(19);
70 builder.PushNACK(21);
71 EXPECT_EQ(std::string("5,7,9-12,15,18-19,21"), builder.GetResult());
72}
73
74TEST(NACKStringBuilderTest, TestCase4) {
75 NACKStringBuilder builder;
76 builder.PushNACK(5);
77 builder.PushNACK(7);
78 builder.PushNACK(8);
79 builder.PushNACK(9);
80 builder.PushNACK(10);
81 builder.PushNACK(11);
82 builder.PushNACK(12);
83 builder.PushNACK(15);
84 builder.PushNACK(18);
85 builder.PushNACK(19);
86 EXPECT_EQ(std::string("5,7-12,15,18-19"), builder.GetResult());
87}
88
89TEST(NACKStringBuilderTest, TestCase5) {
90 NACKStringBuilder builder;
91 builder.PushNACK(5);
92 builder.PushNACK(7);
93 builder.PushNACK(9);
94 builder.PushNACK(10);
95 builder.PushNACK(11);
96 builder.PushNACK(12);
97 builder.PushNACK(15);
98 builder.PushNACK(16);
99 builder.PushNACK(18);
100 builder.PushNACK(19);
101 EXPECT_EQ(std::string("5,7,9-12,15-16,18-19"), builder.GetResult());
102}
103
104TEST(NACKStringBuilderTest, TestCase6) {
105 NACKStringBuilder builder;
106 builder.PushNACK(5);
107 builder.PushNACK(7);
108 builder.PushNACK(9);
109 builder.PushNACK(10);
110 builder.PushNACK(11);
111 builder.PushNACK(12);
112 builder.PushNACK(15);
113 builder.PushNACK(16);
114 builder.PushNACK(17);
115 builder.PushNACK(18);
116 builder.PushNACK(19);
117 EXPECT_EQ(std::string("5,7,9-12,15-19"), builder.GetResult());
118}
119
120TEST(NACKStringBuilderTest, TestCase7) {
121 NACKStringBuilder builder;
122 builder.PushNACK(5);
123 builder.PushNACK(6);
124 builder.PushNACK(7);
125 builder.PushNACK(8);
126 builder.PushNACK(11);
127 builder.PushNACK(12);
128 builder.PushNACK(13);
129 builder.PushNACK(14);
130 builder.PushNACK(15);
131 EXPECT_EQ(std::string("5-8,11-15"), builder.GetResult());
132}
133
134TEST(NACKStringBuilderTest, TestCase8) {
135 NACKStringBuilder builder;
136 builder.PushNACK(5);
137 builder.PushNACK(7);
138 builder.PushNACK(9);
139 builder.PushNACK(11);
140 builder.PushNACK(15);
141 builder.PushNACK(17);
142 builder.PushNACK(19);
143 EXPECT_EQ(std::string("5,7,9,11,15,17,19"), builder.GetResult());
144}
145
146TEST(NACKStringBuilderTest, TestCase9) {
147 NACKStringBuilder builder;
148 builder.PushNACK(5);
149 builder.PushNACK(6);
150 builder.PushNACK(7);
151 builder.PushNACK(8);
152 builder.PushNACK(9);
153 builder.PushNACK(10);
154 builder.PushNACK(11);
155 builder.PushNACK(12);
156 EXPECT_EQ(std::string("5-12"), builder.GetResult());
157}
158
159TEST(NACKStringBuilderTest, TestCase10) {
160 NACKStringBuilder builder;
161 builder.PushNACK(5);
162 EXPECT_EQ(std::string("5"), builder.GetResult());
163}
164
165TEST(NACKStringBuilderTest, TestCase11) {
166 NACKStringBuilder builder;
167 EXPECT_EQ(std::string(""), builder.GetResult());
168}
169
170TEST(NACKStringBuilderTest, TestCase12) {
171 NACKStringBuilder builder;
172 builder.PushNACK(5);
173 builder.PushNACK(6);
174 EXPECT_EQ(std::string("5-6"), builder.GetResult());
175}
176
177TEST(NACKStringBuilderTest, TestCase13) {
178 NACKStringBuilder builder;
179 builder.PushNACK(5);
180 builder.PushNACK(6);
181 builder.PushNACK(9);
182 EXPECT_EQ(std::string("5-6,9"), builder.GetResult());
183}
184
asapersson22ff75a2015-08-21 00:02:47 -0700185class RtcpPacketTypeCounterObserverImpl : public RtcpPacketTypeCounterObserver {
186 public:
187 RtcpPacketTypeCounterObserverImpl() : ssrc_(0) {}
188 virtual ~RtcpPacketTypeCounterObserverImpl() {}
189 void RtcpPacketTypesCounterUpdated(
190 uint32_t ssrc,
191 const RtcpPacketTypeCounter& packet_counter) override {
192 ssrc_ = ssrc;
193 counter_ = packet_counter;
194 }
195 uint32_t ssrc_;
196 RtcpPacketTypeCounter counter_;
197};
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000198
199class TestTransport : public Transport,
nisse7fcdb6d2017-06-01 00:30:55 -0700200 public RtpData {
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000201 public:
asapersson22ff75a2015-08-21 00:02:47 -0700202 TestTransport() {}
203
stefan1d8a5062015-10-02 03:39:33 -0700204 bool SendRtp(const uint8_t* /*data*/,
205 size_t /*len*/,
206 const PacketOptions& options) override {
pbos2d566682015-09-28 09:59:31 -0700207 return false;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000208 }
pbos2d566682015-09-28 09:59:31 -0700209 bool SendRtcp(const uint8_t* data, size_t len) override {
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200210 parser_.Parse(data, len);
pbos2d566682015-09-28 09:59:31 -0700211 return true;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000212 }
asapersson22ff75a2015-08-21 00:02:47 -0700213 int OnReceivedPayloadData(const uint8_t* payload_data,
perkj16ccfdf2017-02-28 14:41:05 -0800214 size_t payload_size,
asapersson22ff75a2015-08-21 00:02:47 -0700215 const WebRtcRTPHeader* rtp_header) override {
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +0000216 return 0;
217 }
asapersson22ff75a2015-08-21 00:02:47 -0700218 test::RtcpPacketParser parser_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000219};
220
Erik Språnga38233a2015-07-24 09:58:18 +0200221namespace {
asapersson22ff75a2015-08-21 00:02:47 -0700222static const uint32_t kSenderSsrc = 0x11111111;
223static const uint32_t kRemoteSsrc = 0x22222222;
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200224static const uint32_t kStartRtpTimestamp = 0x34567;
225static const uint32_t kRtpTimestamp = 0x45678;
Erik Språnga38233a2015-07-24 09:58:18 +0200226}
227
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000228class RtcpSenderTest : public ::testing::Test {
229 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000230 RtcpSenderTest()
asapersson22ff75a2015-08-21 00:02:47 -0700231 : clock_(1335900000),
Erik Språng737336d2016-07-29 12:59:36 +0200232 receive_statistics_(ReceiveStatistics::Create(&clock_)),
233 retransmission_rate_limiter_(&clock_, 1000) {
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +0000234 RtpRtcp::Configuration configuration;
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +0000235 configuration.audio = false;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000236 configuration.clock = &clock_;
asapersson22ff75a2015-08-21 00:02:47 -0700237 configuration.outgoing_transport = &test_transport_;
Erik Språng737336d2016-07-29 12:59:36 +0200238 configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +0000239
asapersson22ff75a2015-08-21 00:02:47 -0700240 rtp_rtcp_impl_.reset(new ModuleRtpRtcpImpl(configuration));
sprang86fd9ed2015-09-29 04:45:43 -0700241 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
terelius429c3452016-01-21 05:42:04 -0800242 nullptr, nullptr, &test_transport_));
asapersson22ff75a2015-08-21 00:02:47 -0700243 rtcp_sender_->SetSSRC(kSenderSsrc);
244 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
danilchap71fead22016-08-18 02:01:49 -0700245 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200246 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000247 }
Erik Språnga38233a2015-07-24 09:58:18 +0200248
asapersson22ff75a2015-08-21 00:02:47 -0700249 void InsertIncomingPacket(uint32_t remote_ssrc, uint16_t seq_num) {
250 RTPHeader header;
251 header.ssrc = remote_ssrc;
252 header.sequenceNumber = seq_num;
253 header.timestamp = 12345;
254 header.headerLength = 12;
255 size_t kPacketLength = 100;
256 receive_statistics_->IncomingPacket(header, kPacketLength, false);
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000257 }
258
asapersson22ff75a2015-08-21 00:02:47 -0700259 test::RtcpPacketParser* parser() { return &test_transport_.parser_; }
260
261 RTCPSender::FeedbackState feedback_state() {
262 return rtp_rtcp_impl_->GetFeedbackState();
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000263 }
264
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000265 SimulatedClock clock_;
asapersson22ff75a2015-08-21 00:02:47 -0700266 TestTransport test_transport_;
kwiberg84be5112016-04-27 01:19:58 -0700267 std::unique_ptr<ReceiveStatistics> receive_statistics_;
268 std::unique_ptr<ModuleRtpRtcpImpl> rtp_rtcp_impl_;
269 std::unique_ptr<RTCPSender> rtcp_sender_;
Erik Språng737336d2016-07-29 12:59:36 +0200270 RateLimiter retransmission_rate_limiter_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000271};
272
asapersson22ff75a2015-08-21 00:02:47 -0700273TEST_F(RtcpSenderTest, SetRtcpStatus) {
pbosda903ea2015-10-02 02:36:56 -0700274 EXPECT_EQ(RtcpMode::kOff, rtcp_sender_->Status());
275 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
276 EXPECT_EQ(RtcpMode::kReducedSize, rtcp_sender_->Status());
asapersson22ff75a2015-08-21 00:02:47 -0700277}
278
279TEST_F(RtcpSenderTest, SetSendingStatus) {
280 EXPECT_FALSE(rtcp_sender_->Sending());
281 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
282 EXPECT_TRUE(rtcp_sender_->Sending());
283}
284
285TEST_F(RtcpSenderTest, NoPacketSentIfOff) {
pbosda903ea2015-10-02 02:36:56 -0700286 rtcp_sender_->SetRTCPStatus(RtcpMode::kOff);
asapersson22ff75a2015-08-21 00:02:47 -0700287 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000288}
289
asapersson22ff75a2015-08-21 00:02:47 -0700290TEST_F(RtcpSenderTest, SendSr) {
291 const uint32_t kPacketCount = 0x12345;
292 const uint32_t kOctetCount = 0x23456;
pbosda903ea2015-10-02 02:36:56 -0700293 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000294 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200295 rtcp_sender_->SetSendingStatus(feedback_state, true);
asapersson22ff75a2015-08-21 00:02:47 -0700296 feedback_state.packets_sent = kPacketCount;
297 feedback_state.media_bytes_sent = kOctetCount;
danilchap21dc1892017-03-07 02:51:09 -0800298 NtpTime ntp = clock_.CurrentNtpTime();
asapersson22ff75a2015-08-21 00:02:47 -0700299 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
300 EXPECT_EQ(1, parser()->sender_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200301 EXPECT_EQ(kSenderSsrc, parser()->sender_report()->sender_ssrc());
danilchap21dc1892017-03-07 02:51:09 -0800302 EXPECT_EQ(ntp, parser()->sender_report()->ntp());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200303 EXPECT_EQ(kPacketCount, parser()->sender_report()->sender_packet_count());
304 EXPECT_EQ(kOctetCount, parser()->sender_report()->sender_octet_count());
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200305 EXPECT_EQ(kStartRtpTimestamp + kRtpTimestamp,
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200306 parser()->sender_report()->rtp_timestamp());
307 EXPECT_EQ(0U, parser()->sender_report()->report_blocks().size());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000308}
309
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200310TEST_F(RtcpSenderTest, DoNotSendSrBeforeRtp) {
311 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
312 nullptr, nullptr, &test_transport_));
313 rtcp_sender_->SetSSRC(kSenderSsrc);
314 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
315 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
316 rtcp_sender_->SetSendingStatus(feedback_state(), true);
317
318 // Sender Report shouldn't be send as an SR nor as a Report.
319 rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr);
320 EXPECT_EQ(0, parser()->sender_report()->num_packets());
321 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
322 EXPECT_EQ(0, parser()->sender_report()->num_packets());
323 // Other packets (e.g. Pli) are allowed, even if useless.
324 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
325 EXPECT_EQ(1, parser()->pli()->num_packets());
326}
327
328TEST_F(RtcpSenderTest, DoNotSendCompundBeforeRtp) {
329 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
330 nullptr, nullptr, &test_transport_));
331 rtcp_sender_->SetSSRC(kSenderSsrc);
332 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
333 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
334 rtcp_sender_->SetSendingStatus(feedback_state(), true);
335
336 // In compound mode no packets are allowed (e.g. Pli) because compound mode
337 // should start with Sender Report.
338 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
339 EXPECT_EQ(0, parser()->pli()->num_packets());
340}
341
asapersson22ff75a2015-08-21 00:02:47 -0700342TEST_F(RtcpSenderTest, SendRr) {
pbosda903ea2015-10-02 02:36:56 -0700343 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700344 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
345 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200346 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
347 EXPECT_EQ(0U, parser()->receiver_report()->report_blocks().size());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000348}
349
asapersson22ff75a2015-08-21 00:02:47 -0700350TEST_F(RtcpSenderTest, SendRrWithOneReportBlock) {
351 const uint16_t kSeqNum = 11111;
352 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
pbosda903ea2015-10-02 02:36:56 -0700353 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700354 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
355 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200356 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
357 ASSERT_EQ(1U, parser()->receiver_report()->report_blocks().size());
358 const rtcp::ReportBlock& rb = parser()->receiver_report()->report_blocks()[0];
359 EXPECT_EQ(kRemoteSsrc, rb.source_ssrc());
360 EXPECT_EQ(0U, rb.fraction_lost());
361 EXPECT_EQ(0U, rb.cumulative_lost());
362 EXPECT_EQ(kSeqNum, rb.extended_high_seq_num());
asapersson22ff75a2015-08-21 00:02:47 -0700363}
364
365TEST_F(RtcpSenderTest, SendRrWithTwoReportBlocks) {
366 const uint16_t kSeqNum = 11111;
367 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
368 InsertIncomingPacket(kRemoteSsrc + 1, kSeqNum + 1);
pbosda903ea2015-10-02 02:36:56 -0700369 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700370 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
371 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200372 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
373 EXPECT_EQ(2U, parser()->receiver_report()->report_blocks().size());
374 EXPECT_EQ(kRemoteSsrc,
375 parser()->receiver_report()->report_blocks()[0].source_ssrc());
376 EXPECT_EQ(kRemoteSsrc + 1,
377 parser()->receiver_report()->report_blocks()[1].source_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700378}
379
380TEST_F(RtcpSenderTest, SendSdes) {
pbosda903ea2015-10-02 02:36:56 -0700381 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700382 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
383 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
384 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200385 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
386 EXPECT_EQ(kSenderSsrc, parser()->sdes()->chunks()[0].ssrc);
387 EXPECT_EQ("alice@host", parser()->sdes()->chunks()[0].cname);
asapersson22ff75a2015-08-21 00:02:47 -0700388}
389
danilchap74e8df8f2017-03-16 08:04:08 -0700390TEST_F(RtcpSenderTest, SendSdesWithMaxChunks) {
391 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
392 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
393 const char cname[] = "smith@host";
394 for (size_t i = 0; i < 30; ++i) {
395 const uint32_t csrc = 0x1234 + i;
396 EXPECT_EQ(0, rtcp_sender_->AddMixedCNAME(csrc, cname));
397 }
398 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
399 EXPECT_EQ(1, parser()->sdes()->num_packets());
400 EXPECT_EQ(31U, parser()->sdes()->chunks().size());
401}
402
asapersson22ff75a2015-08-21 00:02:47 -0700403TEST_F(RtcpSenderTest, SdesIncludedInCompoundPacket) {
pbosda903ea2015-10-02 02:36:56 -0700404 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700405 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
406 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
407 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
408 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200409 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
asapersson22ff75a2015-08-21 00:02:47 -0700410}
411
412TEST_F(RtcpSenderTest, SendBye) {
pbosda903ea2015-10-02 02:36:56 -0700413 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700414 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
415 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200416 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700417}
418
419TEST_F(RtcpSenderTest, StopSendingTriggersBye) {
pbosda903ea2015-10-02 02:36:56 -0700420 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700421 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
422 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
423 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200424 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700425}
426
427TEST_F(RtcpSenderTest, SendApp) {
428 const uint8_t kSubType = 30;
429 uint32_t name = 'n' << 24;
430 name += 'a' << 16;
431 name += 'm' << 8;
432 name += 'e';
433 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
asapersson22ff75a2015-08-21 00:02:47 -0700434 EXPECT_EQ(0, rtcp_sender_->SetApplicationSpecificData(kSubType, name, kData,
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200435 sizeof(kData)));
pbosda903ea2015-10-02 02:36:56 -0700436 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700437 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
438 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200439 EXPECT_EQ(kSubType, parser()->app()->sub_type());
440 EXPECT_EQ(name, parser()->app()->name());
441 EXPECT_EQ(sizeof(kData), parser()->app()->data_size());
442 EXPECT_EQ(0, memcmp(kData, parser()->app()->data(), sizeof(kData)));
asapersson22ff75a2015-08-21 00:02:47 -0700443}
444
Erik Språng521875a2015-09-01 10:11:16 +0200445TEST_F(RtcpSenderTest, SendEmptyApp) {
446 const uint8_t kSubType = 30;
447 const uint32_t kName = 0x6E616D65;
448
449 EXPECT_EQ(
450 0, rtcp_sender_->SetApplicationSpecificData(kSubType, kName, nullptr, 0));
451
pbosda903ea2015-10-02 02:36:56 -0700452 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Erik Språng521875a2015-09-01 10:11:16 +0200453 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
454 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200455 EXPECT_EQ(kSubType, parser()->app()->sub_type());
456 EXPECT_EQ(kName, parser()->app()->name());
457 EXPECT_EQ(0U, parser()->app()->data_size());
Erik Språng521875a2015-09-01 10:11:16 +0200458}
459
asapersson22ff75a2015-08-21 00:02:47 -0700460TEST_F(RtcpSenderTest, SetInvalidApplicationSpecificData) {
461 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't'};
462 const uint16_t kInvalidDataLength = sizeof(kData) / sizeof(kData[0]);
463 EXPECT_EQ(-1, rtcp_sender_->SetApplicationSpecificData(
464 0, 0, kData, kInvalidDataLength)); // Should by multiple of 4.
465}
466
danilchap498ee8e2017-02-08 05:24:31 -0800467TEST_F(RtcpSenderTest, SendFir) {
pbosda903ea2015-10-02 02:36:56 -0700468 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700469 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
470 EXPECT_EQ(1, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200471 EXPECT_EQ(kSenderSsrc, parser()->fir()->sender_ssrc());
472 EXPECT_EQ(1U, parser()->fir()->requests().size());
473 EXPECT_EQ(kRemoteSsrc, parser()->fir()->requests()[0].ssrc);
474 uint8_t seq = parser()->fir()->requests()[0].seq_nr;
asapersson22ff75a2015-08-21 00:02:47 -0700475 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
476 EXPECT_EQ(2, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200477 EXPECT_EQ(seq + 1, parser()->fir()->requests()[0].seq_nr);
asapersson22ff75a2015-08-21 00:02:47 -0700478}
479
asapersson22ff75a2015-08-21 00:02:47 -0700480TEST_F(RtcpSenderTest, SendPli) {
pbosda903ea2015-10-02 02:36:56 -0700481 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700482 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
483 EXPECT_EQ(1, parser()->pli()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200484 EXPECT_EQ(kSenderSsrc, parser()->pli()->sender_ssrc());
485 EXPECT_EQ(kRemoteSsrc, parser()->pli()->media_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700486}
487
asapersson22ff75a2015-08-21 00:02:47 -0700488TEST_F(RtcpSenderTest, SendNack) {
pbosda903ea2015-10-02 02:36:56 -0700489 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700490 const uint16_t kList[] = {0, 1, 16};
491 const int32_t kListLength = sizeof(kList) / sizeof(kList[0]);
492 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpNack, kListLength,
493 kList));
494 EXPECT_EQ(1, parser()->nack()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200495 EXPECT_EQ(kSenderSsrc, parser()->nack()->sender_ssrc());
496 EXPECT_EQ(kRemoteSsrc, parser()->nack()->media_ssrc());
497 EXPECT_THAT(parser()->nack()->packet_ids(), ElementsAre(0, 1, 16));
asapersson22ff75a2015-08-21 00:02:47 -0700498}
499
Danil Chapovalov857a8fb2016-09-06 11:41:46 +0200500TEST_F(RtcpSenderTest, RembStatus) {
danilchapba6aa902017-04-18 06:57:02 -0700501 const uint64_t kBitrate = 261011;
502 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
503 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
504
Danil Chapovalov857a8fb2016-09-06 11:41:46 +0200505 EXPECT_FALSE(rtcp_sender_->REMB());
danilchapba6aa902017-04-18 06:57:02 -0700506 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
507 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
508 EXPECT_EQ(0, parser()->remb()->num_packets());
509
Danil Chapovalov857a8fb2016-09-06 11:41:46 +0200510 rtcp_sender_->SetREMBStatus(true);
511 EXPECT_TRUE(rtcp_sender_->REMB());
danilchapba6aa902017-04-18 06:57:02 -0700512 rtcp_sender_->SetREMBData(kBitrate, kSsrcs);
513 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
514 ASSERT_EQ(2, parser()->receiver_report()->num_packets());
515 EXPECT_EQ(1, parser()->remb()->num_packets());
516
517 // Sending another report sends remb again, even if no new remb data was set.
518 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
519 ASSERT_EQ(3, parser()->receiver_report()->num_packets());
520 EXPECT_EQ(2, parser()->remb()->num_packets());
521
522 // Turn off remb. rtcp_sender no longer should send it.
Danil Chapovalov857a8fb2016-09-06 11:41:46 +0200523 rtcp_sender_->SetREMBStatus(false);
524 EXPECT_FALSE(rtcp_sender_->REMB());
danilchapba6aa902017-04-18 06:57:02 -0700525 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
526 ASSERT_EQ(4, parser()->receiver_report()->num_packets());
527 EXPECT_EQ(2, parser()->remb()->num_packets());
Danil Chapovalov857a8fb2016-09-06 11:41:46 +0200528}
529
asapersson22ff75a2015-08-21 00:02:47 -0700530TEST_F(RtcpSenderTest, SendRemb) {
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200531 const uint64_t kBitrate = 261011;
asapersson22ff75a2015-08-21 00:02:47 -0700532 std::vector<uint32_t> ssrcs;
533 ssrcs.push_back(kRemoteSsrc);
534 ssrcs.push_back(kRemoteSsrc + 1);
pbosda903ea2015-10-02 02:36:56 -0700535 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700536 rtcp_sender_->SetREMBData(kBitrate, ssrcs);
537 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRemb));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200538 EXPECT_EQ(1, parser()->remb()->num_packets());
539 EXPECT_EQ(kSenderSsrc, parser()->remb()->sender_ssrc());
540 EXPECT_EQ(kBitrate, parser()->remb()->bitrate_bps());
541 EXPECT_THAT(parser()->remb()->ssrcs(),
asapersson22ff75a2015-08-21 00:02:47 -0700542 ElementsAre(kRemoteSsrc, kRemoteSsrc + 1));
543}
544
545TEST_F(RtcpSenderTest, RembIncludedInCompoundPacketIfEnabled) {
546 const int kBitrate = 261011;
547 std::vector<uint32_t> ssrcs;
548 ssrcs.push_back(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700549 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700550 rtcp_sender_->SetREMBStatus(true);
551 EXPECT_TRUE(rtcp_sender_->REMB());
552 rtcp_sender_->SetREMBData(kBitrate, ssrcs);
553 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200554 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700555 // REMB should be included in each compound packet.
556 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200557 EXPECT_EQ(2, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700558}
559
560TEST_F(RtcpSenderTest, RembNotIncludedInCompoundPacketIfNotEnabled) {
561 const int kBitrate = 261011;
562 std::vector<uint32_t> ssrcs;
563 ssrcs.push_back(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700564 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700565 rtcp_sender_->SetREMBData(kBitrate, ssrcs);
566 EXPECT_FALSE(rtcp_sender_->REMB());
567 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200568 EXPECT_EQ(0, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700569}
570
571TEST_F(RtcpSenderTest, SendXrWithVoipMetric) {
pbosda903ea2015-10-02 02:36:56 -0700572 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700573 RTCPVoIPMetric metric;
574 metric.lossRate = 1;
575 metric.discardRate = 2;
576 metric.burstDensity = 3;
577 metric.gapDensity = 4;
578 metric.burstDuration = 0x1111;
579 metric.gapDuration = 0x2222;
580 metric.roundTripDelay = 0x3333;
581 metric.endSystemDelay = 0x4444;
582 metric.signalLevel = 5;
583 metric.noiseLevel = 6;
584 metric.RERL = 7;
585 metric.Gmin = 8;
586 metric.Rfactor = 9;
587 metric.extRfactor = 10;
588 metric.MOSLQ = 11;
589 metric.MOSCQ = 12;
590 metric.RXconfig = 13;
591 metric.JBnominal = 0x5555;
592 metric.JBmax = 0x6666;
593 metric.JBabsMax = 0x7777;
594 EXPECT_EQ(0, rtcp_sender_->SetRTCPVoIPMetrics(&metric));
595 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpXrVoipMetric));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200596 EXPECT_EQ(1, parser()->xr()->num_packets());
597 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
danilchap80ac24d2016-10-31 08:40:47 -0700598 ASSERT_TRUE(parser()->xr()->voip_metric());
599 EXPECT_EQ(kRemoteSsrc, parser()->xr()->voip_metric()->ssrc());
600 const auto& parsed_metric = parser()->xr()->voip_metric()->voip_metric();
601 EXPECT_EQ(metric.lossRate, parsed_metric.lossRate);
602 EXPECT_EQ(metric.discardRate, parsed_metric.discardRate);
603 EXPECT_EQ(metric.burstDensity, parsed_metric.burstDensity);
604 EXPECT_EQ(metric.gapDensity, parsed_metric.gapDensity);
605 EXPECT_EQ(metric.burstDuration, parsed_metric.burstDuration);
606 EXPECT_EQ(metric.gapDuration, parsed_metric.gapDuration);
607 EXPECT_EQ(metric.roundTripDelay, parsed_metric.roundTripDelay);
608 EXPECT_EQ(metric.endSystemDelay, parsed_metric.endSystemDelay);
609 EXPECT_EQ(metric.signalLevel, parsed_metric.signalLevel);
610 EXPECT_EQ(metric.noiseLevel, parsed_metric.noiseLevel);
611 EXPECT_EQ(metric.RERL, parsed_metric.RERL);
612 EXPECT_EQ(metric.Gmin, parsed_metric.Gmin);
613 EXPECT_EQ(metric.Rfactor, parsed_metric.Rfactor);
614 EXPECT_EQ(metric.extRfactor, parsed_metric.extRfactor);
615 EXPECT_EQ(metric.MOSLQ, parsed_metric.MOSLQ);
616 EXPECT_EQ(metric.MOSCQ, parsed_metric.MOSCQ);
617 EXPECT_EQ(metric.RXconfig, parsed_metric.RXconfig);
618 EXPECT_EQ(metric.JBnominal, parsed_metric.JBnominal);
619 EXPECT_EQ(metric.JBmax, parsed_metric.JBmax);
620 EXPECT_EQ(metric.JBabsMax, parsed_metric.JBabsMax);
asapersson22ff75a2015-08-21 00:02:47 -0700621}
622
623TEST_F(RtcpSenderTest, SendXrWithDlrr) {
pbosda903ea2015-10-02 02:36:56 -0700624 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000625 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
asapersson22ff75a2015-08-21 00:02:47 -0700626 feedback_state.has_last_xr_rr = true;
danilchap798896a2016-09-28 02:54:25 -0700627 rtcp::ReceiveTimeInfo last_xr_rr;
628 last_xr_rr.ssrc = 0x11111111;
629 last_xr_rr.last_rr = 0x22222222;
630 last_xr_rr.delay_since_last_rr = 0x33333333;
asapersson22ff75a2015-08-21 00:02:47 -0700631 feedback_state.last_xr_rr = last_xr_rr;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000632 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200633 EXPECT_EQ(1, parser()->xr()->num_packets());
634 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
danilchap80ac24d2016-10-31 08:40:47 -0700635 EXPECT_EQ(1U, parser()->xr()->dlrr().sub_blocks().size());
636 EXPECT_EQ(last_xr_rr.ssrc, parser()->xr()->dlrr().sub_blocks()[0].ssrc);
637 EXPECT_EQ(last_xr_rr.last_rr, parser()->xr()->dlrr().sub_blocks()[0].last_rr);
danilchap798896a2016-09-28 02:54:25 -0700638 EXPECT_EQ(last_xr_rr.delay_since_last_rr,
danilchap80ac24d2016-10-31 08:40:47 -0700639 parser()->xr()->dlrr().sub_blocks()[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000640}
641
asapersson22ff75a2015-08-21 00:02:47 -0700642TEST_F(RtcpSenderTest, SendXrWithRrtr) {
pbosda903ea2015-10-02 02:36:56 -0700643 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700644 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000645 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
danilchap21dc1892017-03-07 02:51:09 -0800646 NtpTime ntp = clock_.CurrentNtpTime();
asapersson22ff75a2015-08-21 00:02:47 -0700647 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200648 EXPECT_EQ(1, parser()->xr()->num_packets());
649 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
danilchap80ac24d2016-10-31 08:40:47 -0700650 EXPECT_FALSE(parser()->xr()->dlrr());
651 EXPECT_FALSE(parser()->xr()->voip_metric());
652 ASSERT_TRUE(parser()->xr()->rrtr());
danilchap21dc1892017-03-07 02:51:09 -0800653 EXPECT_EQ(ntp, parser()->xr()->rrtr()->ntp());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000654}
655
asapersson22ff75a2015-08-21 00:02:47 -0700656TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfSending) {
pbosda903ea2015-10-02 02:36:56 -0700657 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700658 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
659 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
660 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200661 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700662}
663
664TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfNotEnabled) {
pbosda903ea2015-10-02 02:36:56 -0700665 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700666 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000667 rtcp_sender_->SendRtcpXrReceiverReferenceTime(false);
asapersson22ff75a2015-08-21 00:02:47 -0700668 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200669 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000670}
671
asapersson22ff75a2015-08-21 00:02:47 -0700672TEST_F(RtcpSenderTest, TestRegisterRtcpPacketTypeObserver) {
673 RtcpPacketTypeCounterObserverImpl observer;
sprang86fd9ed2015-09-29 04:45:43 -0700674 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
terelius429c3452016-01-21 05:42:04 -0800675 &observer, nullptr, &test_transport_));
asapersson22ff75a2015-08-21 00:02:47 -0700676 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700677 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700678 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
679 EXPECT_EQ(1, parser()->pli()->num_packets());
680 EXPECT_EQ(kRemoteSsrc, observer.ssrc_);
681 EXPECT_EQ(1U, observer.counter_.pli_packets);
682 EXPECT_EQ(clock_.TimeInMilliseconds(),
683 observer.counter_.first_packet_time_ms);
684}
685
686TEST_F(RtcpSenderTest, SendTmmbr) {
687 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700688 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700689 rtcp_sender_->SetTargetBitrate(kBitrateBps);
690 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpTmmbr));
691 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200692 EXPECT_EQ(kSenderSsrc, parser()->tmmbr()->sender_ssrc());
693 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
694 EXPECT_EQ(kBitrateBps, parser()->tmmbr()->requests()[0].bitrate_bps());
asapersson22ff75a2015-08-21 00:02:47 -0700695 // TODO(asapersson): tmmbr_item()->Overhead() looks broken, always zero.
696}
697
698TEST_F(RtcpSenderTest, TmmbrIncludedInCompoundPacketIfEnabled) {
699 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700700 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700701 EXPECT_FALSE(rtcp_sender_->TMMBR());
702 rtcp_sender_->SetTMMBRStatus(true);
703 EXPECT_TRUE(rtcp_sender_->TMMBR());
704 rtcp_sender_->SetTargetBitrate(kBitrateBps);
705 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
706 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200707 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
asapersson22ff75a2015-08-21 00:02:47 -0700708 // TMMBR should be included in each compound packet.
709 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
710 EXPECT_EQ(2, parser()->tmmbr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700711
712 rtcp_sender_->SetTMMBRStatus(false);
713 EXPECT_FALSE(rtcp_sender_->TMMBR());
714}
715
716TEST_F(RtcpSenderTest, SendTmmbn) {
pbosda903ea2015-10-02 02:36:56 -0700717 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200718 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700719 std::vector<rtcp::TmmbItem> bounding_set;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200720 const uint32_t kBitrateBps = 32768000;
asapersson22ff75a2015-08-21 00:02:47 -0700721 const uint32_t kPacketOh = 40;
722 const uint32_t kSourceSsrc = 12345;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200723 const rtcp::TmmbItem tmmbn(kSourceSsrc, kBitrateBps, kPacketOh);
danilchap6eaa3a42016-05-09 10:59:50 -0700724 bounding_set.push_back(tmmbn);
danilchap853ecb22016-08-22 08:26:15 -0700725 rtcp_sender_->SetTmmbn(bounding_set);
danilchap6eaa3a42016-05-09 10:59:50 -0700726
asapersson22ff75a2015-08-21 00:02:47 -0700727 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
728 EXPECT_EQ(1, parser()->sender_report()->num_packets());
729 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200730 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
731 EXPECT_EQ(1U, parser()->tmmbn()->items().size());
732 EXPECT_EQ(kBitrateBps, parser()->tmmbn()->items()[0].bitrate_bps());
733 EXPECT_EQ(kPacketOh, parser()->tmmbn()->items()[0].packet_overhead());
734 EXPECT_EQ(kSourceSsrc, parser()->tmmbn()->items()[0].ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700735}
736
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000737// This test is written to verify actual behaviour. It does not seem
738// to make much sense to send an empty TMMBN, since there is no place
739// to put an actual limit here. It's just information that no limit
740// is set, which is kind of the starting assumption.
741// See http://code.google.com/p/webrtc/issues/detail?id=468 for one
742// situation where this caused confusion.
743TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndEmpty) {
pbosda903ea2015-10-02 02:36:56 -0700744 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200745 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700746 std::vector<rtcp::TmmbItem> bounding_set;
danilchap853ecb22016-08-22 08:26:15 -0700747 rtcp_sender_->SetTmmbn(bounding_set);
asapersson22ff75a2015-08-21 00:02:47 -0700748 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
749 EXPECT_EQ(1, parser()->sender_report()->num_packets());
750 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200751 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
752 EXPECT_EQ(0U, parser()->tmmbn()->items().size());
hta@webrtc.org65a4e4e2012-04-30 11:23:41 +0000753}
754
asapersson22ff75a2015-08-21 00:02:47 -0700755TEST_F(RtcpSenderTest, SendCompoundPliRemb) {
756 const int kBitrate = 261011;
757 std::vector<uint32_t> ssrcs;
758 ssrcs.push_back(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700759 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700760 rtcp_sender_->SetREMBData(kBitrate, ssrcs);
761 std::set<RTCPPacketType> packet_types;
762 packet_types.insert(kRtcpRemb);
763 packet_types.insert(kRtcpPli);
764 EXPECT_EQ(0, rtcp_sender_->SendCompoundRTCP(feedback_state(), packet_types));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200765 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700766 EXPECT_EQ(1, parser()->pli()->num_packets());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000767}
Erik Språnga38233a2015-07-24 09:58:18 +0200768
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800769
770// This test is written to verify that BYE is always the last packet
771// type in a RTCP compoud packet. The rtcp_sender_ is recreated with
772// mock_transport, which is used to check for whether BYE at the end
773// of a RTCP compound packet.
774TEST_F(RtcpSenderTest, ByeMustBeLast) {
775 MockTransport mock_transport;
776 EXPECT_CALL(mock_transport, SendRtcp(_, _))
777 .WillOnce(Invoke([](const uint8_t* data, size_t len) {
778 const uint8_t* next_packet = data;
danilchapb1ed6092016-11-01 06:38:37 -0700779 const uint8_t* const packet_end = data + len;
780 rtcp::CommonHeader packet;
781 while (next_packet < packet_end) {
782 EXPECT_TRUE(packet.Parse(next_packet, packet_end - next_packet));
783 next_packet = packet.NextPacket();
784 if (packet.type() == rtcp::Bye::kPacketType) // Main test expectation.
785 EXPECT_EQ(0, packet_end - next_packet)
786 << "Bye packet should be last in a compound RTCP packet.";
787 if (next_packet == packet_end) // Validate test was set correctly.
788 EXPECT_EQ(packet.type(), rtcp::Bye::kPacketType)
789 << "Last packet in this test expected to be Bye.";
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800790 }
791
792 return true;
793 }));
794
795 // Re-configure rtcp_sender_ with mock_transport_
796 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
797 nullptr, nullptr, &mock_transport));
798 rtcp_sender_->SetSSRC(kSenderSsrc);
799 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
danilchap71fead22016-08-18 02:01:49 -0700800 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200801 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds());
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800802
803 // Set up XR VoIP metric to be included with BYE
804 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
805 RTCPVoIPMetric metric;
806 EXPECT_EQ(0, rtcp_sender_->SetRTCPVoIPMetrics(&metric));
807 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
808}
809
sprang5e38c962016-12-01 05:18:09 -0800810TEST_F(RtcpSenderTest, SendXrWithTargetBitrate) {
811 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
812 const size_t kNumSpatialLayers = 2;
813 const size_t kNumTemporalLayers = 2;
814 BitrateAllocation allocation;
815 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
816 uint32_t start_bitrate_bps = (sl + 1) * 100000;
817 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl)
818 allocation.SetBitrate(sl, tl, start_bitrate_bps + (tl * 20000));
819 }
820 rtcp_sender_->SetVideoBitrateAllocation(allocation);
821
822 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
823 EXPECT_EQ(1, parser()->xr()->num_packets());
824 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
825 const rtc::Optional<rtcp::TargetBitrate>& target_bitrate =
826 parser()->xr()->target_bitrate();
827 ASSERT_TRUE(target_bitrate);
828 const std::vector<rtcp::TargetBitrate::BitrateItem>& bitrates =
829 target_bitrate->GetTargetBitrates();
830 EXPECT_EQ(kNumSpatialLayers * kNumTemporalLayers, bitrates.size());
831
832 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
833 uint32_t start_bitrate_bps = (sl + 1) * 100000;
834 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl) {
835 size_t index = (sl * kNumSpatialLayers) + tl;
836 const rtcp::TargetBitrate::BitrateItem& item = bitrates[index];
837 EXPECT_EQ(sl, item.spatial_layer);
838 EXPECT_EQ(tl, item.temporal_layer);
839 EXPECT_EQ(start_bitrate_bps + (tl * 20000),
840 item.target_bitrate_kbps * 1000);
841 }
842 }
843}
844
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000845} // namespace webrtc