blob: 98513325e1c2fbfde1adc20ec12c533ab1b0df8c [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;
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +020027using ::testing::SizeIs;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000028
29namespace webrtc {
30
edjee@google.com79b02892013-04-04 19:43:34 +000031TEST(NACKStringBuilderTest, TestCase1) {
32 NACKStringBuilder builder;
33 builder.PushNACK(5);
34 builder.PushNACK(7);
35 builder.PushNACK(9);
36 builder.PushNACK(10);
37 builder.PushNACK(11);
38 builder.PushNACK(12);
39 builder.PushNACK(15);
40 builder.PushNACK(18);
41 builder.PushNACK(19);
42 EXPECT_EQ(std::string("5,7,9-12,15,18-19"), builder.GetResult());
43}
44
45TEST(NACKStringBuilderTest, TestCase2) {
46 NACKStringBuilder builder;
47 builder.PushNACK(5);
48 builder.PushNACK(6);
49 builder.PushNACK(7);
50 builder.PushNACK(9);
51 builder.PushNACK(10);
52 builder.PushNACK(11);
53 builder.PushNACK(12);
54 builder.PushNACK(15);
55 builder.PushNACK(18);
56 builder.PushNACK(19);
57 EXPECT_EQ(std::string("5-7,9-12,15,18-19"), builder.GetResult());
58}
59
60TEST(NACKStringBuilderTest, TestCase3) {
61 NACKStringBuilder builder;
62 builder.PushNACK(5);
63 builder.PushNACK(7);
64 builder.PushNACK(9);
65 builder.PushNACK(10);
66 builder.PushNACK(11);
67 builder.PushNACK(12);
68 builder.PushNACK(15);
69 builder.PushNACK(18);
70 builder.PushNACK(19);
71 builder.PushNACK(21);
72 EXPECT_EQ(std::string("5,7,9-12,15,18-19,21"), builder.GetResult());
73}
74
75TEST(NACKStringBuilderTest, TestCase4) {
76 NACKStringBuilder builder;
77 builder.PushNACK(5);
78 builder.PushNACK(7);
79 builder.PushNACK(8);
80 builder.PushNACK(9);
81 builder.PushNACK(10);
82 builder.PushNACK(11);
83 builder.PushNACK(12);
84 builder.PushNACK(15);
85 builder.PushNACK(18);
86 builder.PushNACK(19);
87 EXPECT_EQ(std::string("5,7-12,15,18-19"), builder.GetResult());
88}
89
90TEST(NACKStringBuilderTest, TestCase5) {
91 NACKStringBuilder builder;
92 builder.PushNACK(5);
93 builder.PushNACK(7);
94 builder.PushNACK(9);
95 builder.PushNACK(10);
96 builder.PushNACK(11);
97 builder.PushNACK(12);
98 builder.PushNACK(15);
99 builder.PushNACK(16);
100 builder.PushNACK(18);
101 builder.PushNACK(19);
102 EXPECT_EQ(std::string("5,7,9-12,15-16,18-19"), builder.GetResult());
103}
104
105TEST(NACKStringBuilderTest, TestCase6) {
106 NACKStringBuilder builder;
107 builder.PushNACK(5);
108 builder.PushNACK(7);
109 builder.PushNACK(9);
110 builder.PushNACK(10);
111 builder.PushNACK(11);
112 builder.PushNACK(12);
113 builder.PushNACK(15);
114 builder.PushNACK(16);
115 builder.PushNACK(17);
116 builder.PushNACK(18);
117 builder.PushNACK(19);
118 EXPECT_EQ(std::string("5,7,9-12,15-19"), builder.GetResult());
119}
120
121TEST(NACKStringBuilderTest, TestCase7) {
122 NACKStringBuilder builder;
123 builder.PushNACK(5);
124 builder.PushNACK(6);
125 builder.PushNACK(7);
126 builder.PushNACK(8);
127 builder.PushNACK(11);
128 builder.PushNACK(12);
129 builder.PushNACK(13);
130 builder.PushNACK(14);
131 builder.PushNACK(15);
132 EXPECT_EQ(std::string("5-8,11-15"), builder.GetResult());
133}
134
135TEST(NACKStringBuilderTest, TestCase8) {
136 NACKStringBuilder builder;
137 builder.PushNACK(5);
138 builder.PushNACK(7);
139 builder.PushNACK(9);
140 builder.PushNACK(11);
141 builder.PushNACK(15);
142 builder.PushNACK(17);
143 builder.PushNACK(19);
144 EXPECT_EQ(std::string("5,7,9,11,15,17,19"), builder.GetResult());
145}
146
147TEST(NACKStringBuilderTest, TestCase9) {
148 NACKStringBuilder builder;
149 builder.PushNACK(5);
150 builder.PushNACK(6);
151 builder.PushNACK(7);
152 builder.PushNACK(8);
153 builder.PushNACK(9);
154 builder.PushNACK(10);
155 builder.PushNACK(11);
156 builder.PushNACK(12);
157 EXPECT_EQ(std::string("5-12"), builder.GetResult());
158}
159
160TEST(NACKStringBuilderTest, TestCase10) {
161 NACKStringBuilder builder;
162 builder.PushNACK(5);
163 EXPECT_EQ(std::string("5"), builder.GetResult());
164}
165
166TEST(NACKStringBuilderTest, TestCase11) {
167 NACKStringBuilder builder;
168 EXPECT_EQ(std::string(""), builder.GetResult());
169}
170
171TEST(NACKStringBuilderTest, TestCase12) {
172 NACKStringBuilder builder;
173 builder.PushNACK(5);
174 builder.PushNACK(6);
175 EXPECT_EQ(std::string("5-6"), builder.GetResult());
176}
177
178TEST(NACKStringBuilderTest, TestCase13) {
179 NACKStringBuilder builder;
180 builder.PushNACK(5);
181 builder.PushNACK(6);
182 builder.PushNACK(9);
183 EXPECT_EQ(std::string("5-6,9"), builder.GetResult());
184}
185
asapersson22ff75a2015-08-21 00:02:47 -0700186class RtcpPacketTypeCounterObserverImpl : public RtcpPacketTypeCounterObserver {
187 public:
188 RtcpPacketTypeCounterObserverImpl() : ssrc_(0) {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +0000189 ~RtcpPacketTypeCounterObserverImpl() override = default;
asapersson22ff75a2015-08-21 00:02:47 -0700190 void RtcpPacketTypesCounterUpdated(
191 uint32_t ssrc,
192 const RtcpPacketTypeCounter& packet_counter) override {
193 ssrc_ = ssrc;
194 counter_ = packet_counter;
195 }
196 uint32_t ssrc_;
197 RtcpPacketTypeCounter counter_;
198};
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000199
200class TestTransport : public Transport,
nisse7fcdb6d2017-06-01 00:30:55 -0700201 public RtpData {
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000202 public:
asapersson22ff75a2015-08-21 00:02:47 -0700203 TestTransport() {}
204
stefan1d8a5062015-10-02 03:39:33 -0700205 bool SendRtp(const uint8_t* /*data*/,
206 size_t /*len*/,
207 const PacketOptions& options) override {
pbos2d566682015-09-28 09:59:31 -0700208 return false;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000209 }
pbos2d566682015-09-28 09:59:31 -0700210 bool SendRtcp(const uint8_t* data, size_t len) override {
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200211 parser_.Parse(data, len);
pbos2d566682015-09-28 09:59:31 -0700212 return true;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000213 }
asapersson22ff75a2015-08-21 00:02:47 -0700214 int OnReceivedPayloadData(const uint8_t* payload_data,
perkj16ccfdf2017-02-28 14:41:05 -0800215 size_t payload_size,
asapersson22ff75a2015-08-21 00:02:47 -0700216 const WebRtcRTPHeader* rtp_header) override {
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +0000217 return 0;
218 }
asapersson22ff75a2015-08-21 00:02:47 -0700219 test::RtcpPacketParser parser_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000220};
221
Erik Språnga38233a2015-07-24 09:58:18 +0200222namespace {
asapersson22ff75a2015-08-21 00:02:47 -0700223static const uint32_t kSenderSsrc = 0x11111111;
224static const uint32_t kRemoteSsrc = 0x22222222;
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200225static const uint32_t kStartRtpTimestamp = 0x34567;
226static const uint32_t kRtpTimestamp = 0x45678;
Erik Språnga38233a2015-07-24 09:58:18 +0200227}
228
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000229class RtcpSenderTest : public ::testing::Test {
230 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000231 RtcpSenderTest()
asapersson22ff75a2015-08-21 00:02:47 -0700232 : clock_(1335900000),
Erik Språng737336d2016-07-29 12:59:36 +0200233 receive_statistics_(ReceiveStatistics::Create(&clock_)),
234 retransmission_rate_limiter_(&clock_, 1000) {
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +0000235 RtpRtcp::Configuration configuration;
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +0000236 configuration.audio = false;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000237 configuration.clock = &clock_;
asapersson22ff75a2015-08-21 00:02:47 -0700238 configuration.outgoing_transport = &test_transport_;
Erik Språng737336d2016-07-29 12:59:36 +0200239 configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +0000240
asapersson22ff75a2015-08-21 00:02:47 -0700241 rtp_rtcp_impl_.reset(new ModuleRtpRtcpImpl(configuration));
sprang86fd9ed2015-09-29 04:45:43 -0700242 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800243 nullptr, nullptr, &test_transport_,
244 configuration.rtcp_interval_config));
asapersson22ff75a2015-08-21 00:02:47 -0700245 rtcp_sender_->SetSSRC(kSenderSsrc);
246 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
danilchap71fead22016-08-18 02:01:49 -0700247 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200248 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000249 }
Erik Språnga38233a2015-07-24 09:58:18 +0200250
asapersson22ff75a2015-08-21 00:02:47 -0700251 void InsertIncomingPacket(uint32_t remote_ssrc, uint16_t seq_num) {
252 RTPHeader header;
253 header.ssrc = remote_ssrc;
254 header.sequenceNumber = seq_num;
255 header.timestamp = 12345;
256 header.headerLength = 12;
257 size_t kPacketLength = 100;
258 receive_statistics_->IncomingPacket(header, kPacketLength, false);
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000259 }
260
asapersson22ff75a2015-08-21 00:02:47 -0700261 test::RtcpPacketParser* parser() { return &test_transport_.parser_; }
262
263 RTCPSender::FeedbackState feedback_state() {
264 return rtp_rtcp_impl_->GetFeedbackState();
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000265 }
266
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000267 SimulatedClock clock_;
asapersson22ff75a2015-08-21 00:02:47 -0700268 TestTransport test_transport_;
kwiberg84be5112016-04-27 01:19:58 -0700269 std::unique_ptr<ReceiveStatistics> receive_statistics_;
270 std::unique_ptr<ModuleRtpRtcpImpl> rtp_rtcp_impl_;
271 std::unique_ptr<RTCPSender> rtcp_sender_;
Erik Språng737336d2016-07-29 12:59:36 +0200272 RateLimiter retransmission_rate_limiter_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000273};
274
asapersson22ff75a2015-08-21 00:02:47 -0700275TEST_F(RtcpSenderTest, SetRtcpStatus) {
pbosda903ea2015-10-02 02:36:56 -0700276 EXPECT_EQ(RtcpMode::kOff, rtcp_sender_->Status());
277 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
278 EXPECT_EQ(RtcpMode::kReducedSize, rtcp_sender_->Status());
asapersson22ff75a2015-08-21 00:02:47 -0700279}
280
281TEST_F(RtcpSenderTest, SetSendingStatus) {
282 EXPECT_FALSE(rtcp_sender_->Sending());
283 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
284 EXPECT_TRUE(rtcp_sender_->Sending());
285}
286
287TEST_F(RtcpSenderTest, NoPacketSentIfOff) {
pbosda903ea2015-10-02 02:36:56 -0700288 rtcp_sender_->SetRTCPStatus(RtcpMode::kOff);
asapersson22ff75a2015-08-21 00:02:47 -0700289 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000290}
291
asapersson22ff75a2015-08-21 00:02:47 -0700292TEST_F(RtcpSenderTest, SendSr) {
293 const uint32_t kPacketCount = 0x12345;
294 const uint32_t kOctetCount = 0x23456;
pbosda903ea2015-10-02 02:36:56 -0700295 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000296 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200297 rtcp_sender_->SetSendingStatus(feedback_state, true);
asapersson22ff75a2015-08-21 00:02:47 -0700298 feedback_state.packets_sent = kPacketCount;
299 feedback_state.media_bytes_sent = kOctetCount;
danilchap21dc1892017-03-07 02:51:09 -0800300 NtpTime ntp = clock_.CurrentNtpTime();
asapersson22ff75a2015-08-21 00:02:47 -0700301 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
302 EXPECT_EQ(1, parser()->sender_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200303 EXPECT_EQ(kSenderSsrc, parser()->sender_report()->sender_ssrc());
danilchap21dc1892017-03-07 02:51:09 -0800304 EXPECT_EQ(ntp, parser()->sender_report()->ntp());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200305 EXPECT_EQ(kPacketCount, parser()->sender_report()->sender_packet_count());
306 EXPECT_EQ(kOctetCount, parser()->sender_report()->sender_octet_count());
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200307 EXPECT_EQ(kStartRtpTimestamp + kRtpTimestamp,
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200308 parser()->sender_report()->rtp_timestamp());
309 EXPECT_EQ(0U, parser()->sender_report()->report_blocks().size());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000310}
311
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200312TEST_F(RtcpSenderTest, DoNotSendSrBeforeRtp) {
313 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800314 nullptr, nullptr, &test_transport_,
315 RtcpIntervalConfig{}));
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200316 rtcp_sender_->SetSSRC(kSenderSsrc);
317 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
318 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
319 rtcp_sender_->SetSendingStatus(feedback_state(), true);
320
321 // Sender Report shouldn't be send as an SR nor as a Report.
322 rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr);
323 EXPECT_EQ(0, parser()->sender_report()->num_packets());
324 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
325 EXPECT_EQ(0, parser()->sender_report()->num_packets());
326 // Other packets (e.g. Pli) are allowed, even if useless.
327 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
328 EXPECT_EQ(1, parser()->pli()->num_packets());
329}
330
331TEST_F(RtcpSenderTest, DoNotSendCompundBeforeRtp) {
332 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800333 nullptr, nullptr, &test_transport_,
334 RtcpIntervalConfig{}));
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200335 rtcp_sender_->SetSSRC(kSenderSsrc);
336 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
337 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
338 rtcp_sender_->SetSendingStatus(feedback_state(), true);
339
340 // In compound mode no packets are allowed (e.g. Pli) because compound mode
341 // should start with Sender Report.
342 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
343 EXPECT_EQ(0, parser()->pli()->num_packets());
344}
345
asapersson22ff75a2015-08-21 00:02:47 -0700346TEST_F(RtcpSenderTest, SendRr) {
pbosda903ea2015-10-02 02:36:56 -0700347 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700348 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
349 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200350 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
351 EXPECT_EQ(0U, parser()->receiver_report()->report_blocks().size());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000352}
353
asapersson22ff75a2015-08-21 00:02:47 -0700354TEST_F(RtcpSenderTest, SendRrWithOneReportBlock) {
355 const uint16_t kSeqNum = 11111;
356 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
pbosda903ea2015-10-02 02:36:56 -0700357 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700358 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
359 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200360 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
361 ASSERT_EQ(1U, parser()->receiver_report()->report_blocks().size());
362 const rtcp::ReportBlock& rb = parser()->receiver_report()->report_blocks()[0];
363 EXPECT_EQ(kRemoteSsrc, rb.source_ssrc());
364 EXPECT_EQ(0U, rb.fraction_lost());
Harald Alvestrand70206d62017-12-08 08:59:07 +0100365 EXPECT_EQ(0, rb.cumulative_lost_signed());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200366 EXPECT_EQ(kSeqNum, rb.extended_high_seq_num());
asapersson22ff75a2015-08-21 00:02:47 -0700367}
368
369TEST_F(RtcpSenderTest, SendRrWithTwoReportBlocks) {
370 const uint16_t kSeqNum = 11111;
371 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
372 InsertIncomingPacket(kRemoteSsrc + 1, kSeqNum + 1);
pbosda903ea2015-10-02 02:36:56 -0700373 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700374 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
375 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200376 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
377 EXPECT_EQ(2U, parser()->receiver_report()->report_blocks().size());
378 EXPECT_EQ(kRemoteSsrc,
379 parser()->receiver_report()->report_blocks()[0].source_ssrc());
380 EXPECT_EQ(kRemoteSsrc + 1,
381 parser()->receiver_report()->report_blocks()[1].source_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700382}
383
384TEST_F(RtcpSenderTest, SendSdes) {
pbosda903ea2015-10-02 02:36:56 -0700385 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700386 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
387 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
388 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200389 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
390 EXPECT_EQ(kSenderSsrc, parser()->sdes()->chunks()[0].ssrc);
391 EXPECT_EQ("alice@host", parser()->sdes()->chunks()[0].cname);
asapersson22ff75a2015-08-21 00:02:47 -0700392}
393
danilchap74e8df8f2017-03-16 08:04:08 -0700394TEST_F(RtcpSenderTest, SendSdesWithMaxChunks) {
395 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
396 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
397 const char cname[] = "smith@host";
398 for (size_t i = 0; i < 30; ++i) {
399 const uint32_t csrc = 0x1234 + i;
400 EXPECT_EQ(0, rtcp_sender_->AddMixedCNAME(csrc, cname));
401 }
402 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
403 EXPECT_EQ(1, parser()->sdes()->num_packets());
404 EXPECT_EQ(31U, parser()->sdes()->chunks().size());
405}
406
asapersson22ff75a2015-08-21 00:02:47 -0700407TEST_F(RtcpSenderTest, SdesIncludedInCompoundPacket) {
pbosda903ea2015-10-02 02:36:56 -0700408 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700409 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
410 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
411 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
412 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200413 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
asapersson22ff75a2015-08-21 00:02:47 -0700414}
415
416TEST_F(RtcpSenderTest, SendBye) {
pbosda903ea2015-10-02 02:36:56 -0700417 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700418 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
419 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200420 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700421}
422
423TEST_F(RtcpSenderTest, StopSendingTriggersBye) {
pbosda903ea2015-10-02 02:36:56 -0700424 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700425 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
426 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
427 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200428 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700429}
430
431TEST_F(RtcpSenderTest, SendApp) {
432 const uint8_t kSubType = 30;
433 uint32_t name = 'n' << 24;
434 name += 'a' << 16;
435 name += 'm' << 8;
436 name += 'e';
437 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
asapersson22ff75a2015-08-21 00:02:47 -0700438 EXPECT_EQ(0, rtcp_sender_->SetApplicationSpecificData(kSubType, name, kData,
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200439 sizeof(kData)));
pbosda903ea2015-10-02 02:36:56 -0700440 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700441 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
442 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200443 EXPECT_EQ(kSubType, parser()->app()->sub_type());
444 EXPECT_EQ(name, parser()->app()->name());
445 EXPECT_EQ(sizeof(kData), parser()->app()->data_size());
446 EXPECT_EQ(0, memcmp(kData, parser()->app()->data(), sizeof(kData)));
asapersson22ff75a2015-08-21 00:02:47 -0700447}
448
Erik Språng521875a2015-09-01 10:11:16 +0200449TEST_F(RtcpSenderTest, SendEmptyApp) {
450 const uint8_t kSubType = 30;
451 const uint32_t kName = 0x6E616D65;
452
453 EXPECT_EQ(
454 0, rtcp_sender_->SetApplicationSpecificData(kSubType, kName, nullptr, 0));
455
pbosda903ea2015-10-02 02:36:56 -0700456 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Erik Språng521875a2015-09-01 10:11:16 +0200457 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
458 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200459 EXPECT_EQ(kSubType, parser()->app()->sub_type());
460 EXPECT_EQ(kName, parser()->app()->name());
461 EXPECT_EQ(0U, parser()->app()->data_size());
Erik Språng521875a2015-09-01 10:11:16 +0200462}
463
asapersson22ff75a2015-08-21 00:02:47 -0700464TEST_F(RtcpSenderTest, SetInvalidApplicationSpecificData) {
465 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't'};
466 const uint16_t kInvalidDataLength = sizeof(kData) / sizeof(kData[0]);
467 EXPECT_EQ(-1, rtcp_sender_->SetApplicationSpecificData(
468 0, 0, kData, kInvalidDataLength)); // Should by multiple of 4.
469}
470
danilchap498ee8e2017-02-08 05:24:31 -0800471TEST_F(RtcpSenderTest, SendFir) {
pbosda903ea2015-10-02 02:36:56 -0700472 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700473 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
474 EXPECT_EQ(1, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200475 EXPECT_EQ(kSenderSsrc, parser()->fir()->sender_ssrc());
476 EXPECT_EQ(1U, parser()->fir()->requests().size());
477 EXPECT_EQ(kRemoteSsrc, parser()->fir()->requests()[0].ssrc);
478 uint8_t seq = parser()->fir()->requests()[0].seq_nr;
asapersson22ff75a2015-08-21 00:02:47 -0700479 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
480 EXPECT_EQ(2, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200481 EXPECT_EQ(seq + 1, parser()->fir()->requests()[0].seq_nr);
asapersson22ff75a2015-08-21 00:02:47 -0700482}
483
asapersson22ff75a2015-08-21 00:02:47 -0700484TEST_F(RtcpSenderTest, SendPli) {
pbosda903ea2015-10-02 02:36:56 -0700485 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700486 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
487 EXPECT_EQ(1, parser()->pli()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200488 EXPECT_EQ(kSenderSsrc, parser()->pli()->sender_ssrc());
489 EXPECT_EQ(kRemoteSsrc, parser()->pli()->media_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700490}
491
asapersson22ff75a2015-08-21 00:02:47 -0700492TEST_F(RtcpSenderTest, SendNack) {
pbosda903ea2015-10-02 02:36:56 -0700493 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700494 const uint16_t kList[] = {0, 1, 16};
495 const int32_t kListLength = sizeof(kList) / sizeof(kList[0]);
496 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpNack, kListLength,
497 kList));
498 EXPECT_EQ(1, parser()->nack()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200499 EXPECT_EQ(kSenderSsrc, parser()->nack()->sender_ssrc());
500 EXPECT_EQ(kRemoteSsrc, parser()->nack()->media_ssrc());
501 EXPECT_THAT(parser()->nack()->packet_ids(), ElementsAre(0, 1, 16));
asapersson22ff75a2015-08-21 00:02:47 -0700502}
503
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200504TEST_F(RtcpSenderTest, RembNotIncludedBeforeSet) {
505 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
506
507 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
508
509 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
510 EXPECT_EQ(0, parser()->remb()->num_packets());
511}
512
513TEST_F(RtcpSenderTest, RembNotIncludedAfterUnset) {
danilchapba6aa902017-04-18 06:57:02 -0700514 const uint64_t kBitrate = 261011;
515 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
516 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200517 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
danilchapba6aa902017-04-18 06:57:02 -0700518 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
519 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200520 EXPECT_EQ(1, parser()->remb()->num_packets());
danilchapba6aa902017-04-18 06:57:02 -0700521
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200522 // Turn off REMB. rtcp_sender no longer should send it.
523 rtcp_sender_->UnsetRemb();
danilchapba6aa902017-04-18 06:57:02 -0700524 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
525 ASSERT_EQ(2, parser()->receiver_report()->num_packets());
526 EXPECT_EQ(1, parser()->remb()->num_packets());
Danil Chapovalov857a8fb2016-09-06 11:41:46 +0200527}
528
asapersson22ff75a2015-08-21 00:02:47 -0700529TEST_F(RtcpSenderTest, SendRemb) {
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200530 const uint64_t kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200531 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700532 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200533 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
534
535 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRemb);
536
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200537 EXPECT_EQ(1, parser()->remb()->num_packets());
538 EXPECT_EQ(kSenderSsrc, parser()->remb()->sender_ssrc());
539 EXPECT_EQ(kBitrate, parser()->remb()->bitrate_bps());
540 EXPECT_THAT(parser()->remb()->ssrcs(),
asapersson22ff75a2015-08-21 00:02:47 -0700541 ElementsAre(kRemoteSsrc, kRemoteSsrc + 1));
542}
543
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200544TEST_F(RtcpSenderTest, RembIncludedInEachCompoundPacketAfterSet) {
asapersson22ff75a2015-08-21 00:02:47 -0700545 const int kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200546 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700547 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200548 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
549
550 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200551 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700552 // REMB should be included in each compound packet.
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200553 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200554 EXPECT_EQ(2, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700555}
556
asapersson22ff75a2015-08-21 00:02:47 -0700557TEST_F(RtcpSenderTest, SendXrWithVoipMetric) {
pbosda903ea2015-10-02 02:36:56 -0700558 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700559 RTCPVoIPMetric metric;
560 metric.lossRate = 1;
561 metric.discardRate = 2;
562 metric.burstDensity = 3;
563 metric.gapDensity = 4;
564 metric.burstDuration = 0x1111;
565 metric.gapDuration = 0x2222;
566 metric.roundTripDelay = 0x3333;
567 metric.endSystemDelay = 0x4444;
568 metric.signalLevel = 5;
569 metric.noiseLevel = 6;
570 metric.RERL = 7;
571 metric.Gmin = 8;
572 metric.Rfactor = 9;
573 metric.extRfactor = 10;
574 metric.MOSLQ = 11;
575 metric.MOSCQ = 12;
576 metric.RXconfig = 13;
577 metric.JBnominal = 0x5555;
578 metric.JBmax = 0x6666;
579 metric.JBabsMax = 0x7777;
580 EXPECT_EQ(0, rtcp_sender_->SetRTCPVoIPMetrics(&metric));
581 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpXrVoipMetric));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200582 EXPECT_EQ(1, parser()->xr()->num_packets());
583 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
danilchap80ac24d2016-10-31 08:40:47 -0700584 ASSERT_TRUE(parser()->xr()->voip_metric());
585 EXPECT_EQ(kRemoteSsrc, parser()->xr()->voip_metric()->ssrc());
586 const auto& parsed_metric = parser()->xr()->voip_metric()->voip_metric();
587 EXPECT_EQ(metric.lossRate, parsed_metric.lossRate);
588 EXPECT_EQ(metric.discardRate, parsed_metric.discardRate);
589 EXPECT_EQ(metric.burstDensity, parsed_metric.burstDensity);
590 EXPECT_EQ(metric.gapDensity, parsed_metric.gapDensity);
591 EXPECT_EQ(metric.burstDuration, parsed_metric.burstDuration);
592 EXPECT_EQ(metric.gapDuration, parsed_metric.gapDuration);
593 EXPECT_EQ(metric.roundTripDelay, parsed_metric.roundTripDelay);
594 EXPECT_EQ(metric.endSystemDelay, parsed_metric.endSystemDelay);
595 EXPECT_EQ(metric.signalLevel, parsed_metric.signalLevel);
596 EXPECT_EQ(metric.noiseLevel, parsed_metric.noiseLevel);
597 EXPECT_EQ(metric.RERL, parsed_metric.RERL);
598 EXPECT_EQ(metric.Gmin, parsed_metric.Gmin);
599 EXPECT_EQ(metric.Rfactor, parsed_metric.Rfactor);
600 EXPECT_EQ(metric.extRfactor, parsed_metric.extRfactor);
601 EXPECT_EQ(metric.MOSLQ, parsed_metric.MOSLQ);
602 EXPECT_EQ(metric.MOSCQ, parsed_metric.MOSCQ);
603 EXPECT_EQ(metric.RXconfig, parsed_metric.RXconfig);
604 EXPECT_EQ(metric.JBnominal, parsed_metric.JBnominal);
605 EXPECT_EQ(metric.JBmax, parsed_metric.JBmax);
606 EXPECT_EQ(metric.JBabsMax, parsed_metric.JBabsMax);
asapersson22ff75a2015-08-21 00:02:47 -0700607}
608
609TEST_F(RtcpSenderTest, SendXrWithDlrr) {
pbosda903ea2015-10-02 02:36:56 -0700610 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000611 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
danilchap798896a2016-09-28 02:54:25 -0700612 rtcp::ReceiveTimeInfo last_xr_rr;
613 last_xr_rr.ssrc = 0x11111111;
614 last_xr_rr.last_rr = 0x22222222;
615 last_xr_rr.delay_since_last_rr = 0x33333333;
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200616 feedback_state.last_xr_rtis.push_back(last_xr_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000617 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200618 EXPECT_EQ(1, parser()->xr()->num_packets());
619 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200620 ASSERT_THAT(parser()->xr()->dlrr().sub_blocks(), SizeIs(1));
danilchap80ac24d2016-10-31 08:40:47 -0700621 EXPECT_EQ(last_xr_rr.ssrc, parser()->xr()->dlrr().sub_blocks()[0].ssrc);
622 EXPECT_EQ(last_xr_rr.last_rr, parser()->xr()->dlrr().sub_blocks()[0].last_rr);
danilchap798896a2016-09-28 02:54:25 -0700623 EXPECT_EQ(last_xr_rr.delay_since_last_rr,
danilchap80ac24d2016-10-31 08:40:47 -0700624 parser()->xr()->dlrr().sub_blocks()[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000625}
626
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200627TEST_F(RtcpSenderTest, SendXrWithMultipleDlrrSubBlocks) {
628 const size_t kNumReceivers = 2;
629 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
630 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
631 for (size_t i = 0; i < kNumReceivers; ++i) {
632 rtcp::ReceiveTimeInfo last_xr_rr;
633 last_xr_rr.ssrc = i;
634 last_xr_rr.last_rr = (i + 1) * 100;
635 last_xr_rr.delay_since_last_rr = (i + 2) * 200;
636 feedback_state.last_xr_rtis.push_back(last_xr_rr);
637 }
638
639 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
640 EXPECT_EQ(1, parser()->xr()->num_packets());
641 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
642 ASSERT_THAT(parser()->xr()->dlrr().sub_blocks(), SizeIs(kNumReceivers));
643 for (size_t i = 0; i < kNumReceivers; ++i) {
644 EXPECT_EQ(feedback_state.last_xr_rtis[i].ssrc,
645 parser()->xr()->dlrr().sub_blocks()[i].ssrc);
646 EXPECT_EQ(feedback_state.last_xr_rtis[i].last_rr,
647 parser()->xr()->dlrr().sub_blocks()[i].last_rr);
648 EXPECT_EQ(feedback_state.last_xr_rtis[i].delay_since_last_rr,
649 parser()->xr()->dlrr().sub_blocks()[i].delay_since_last_rr);
650 }
651}
652
asapersson22ff75a2015-08-21 00:02:47 -0700653TEST_F(RtcpSenderTest, SendXrWithRrtr) {
pbosda903ea2015-10-02 02:36:56 -0700654 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700655 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000656 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
danilchap21dc1892017-03-07 02:51:09 -0800657 NtpTime ntp = clock_.CurrentNtpTime();
asapersson22ff75a2015-08-21 00:02:47 -0700658 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200659 EXPECT_EQ(1, parser()->xr()->num_packets());
660 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
danilchap80ac24d2016-10-31 08:40:47 -0700661 EXPECT_FALSE(parser()->xr()->dlrr());
662 EXPECT_FALSE(parser()->xr()->voip_metric());
663 ASSERT_TRUE(parser()->xr()->rrtr());
danilchap21dc1892017-03-07 02:51:09 -0800664 EXPECT_EQ(ntp, parser()->xr()->rrtr()->ntp());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000665}
666
asapersson22ff75a2015-08-21 00:02:47 -0700667TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfSending) {
pbosda903ea2015-10-02 02:36:56 -0700668 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700669 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
670 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
671 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200672 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700673}
674
675TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfNotEnabled) {
pbosda903ea2015-10-02 02:36:56 -0700676 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700677 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000678 rtcp_sender_->SendRtcpXrReceiverReferenceTime(false);
asapersson22ff75a2015-08-21 00:02:47 -0700679 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200680 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000681}
682
asapersson22ff75a2015-08-21 00:02:47 -0700683TEST_F(RtcpSenderTest, TestRegisterRtcpPacketTypeObserver) {
684 RtcpPacketTypeCounterObserverImpl observer;
sprang86fd9ed2015-09-29 04:45:43 -0700685 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800686 &observer, nullptr, &test_transport_,
687 RtcpIntervalConfig{}));
asapersson22ff75a2015-08-21 00:02:47 -0700688 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700689 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700690 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
691 EXPECT_EQ(1, parser()->pli()->num_packets());
692 EXPECT_EQ(kRemoteSsrc, observer.ssrc_);
693 EXPECT_EQ(1U, observer.counter_.pli_packets);
694 EXPECT_EQ(clock_.TimeInMilliseconds(),
695 observer.counter_.first_packet_time_ms);
696}
697
698TEST_F(RtcpSenderTest, SendTmmbr) {
699 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700700 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700701 rtcp_sender_->SetTargetBitrate(kBitrateBps);
702 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpTmmbr));
703 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200704 EXPECT_EQ(kSenderSsrc, parser()->tmmbr()->sender_ssrc());
705 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
706 EXPECT_EQ(kBitrateBps, parser()->tmmbr()->requests()[0].bitrate_bps());
asapersson22ff75a2015-08-21 00:02:47 -0700707 // TODO(asapersson): tmmbr_item()->Overhead() looks broken, always zero.
708}
709
710TEST_F(RtcpSenderTest, TmmbrIncludedInCompoundPacketIfEnabled) {
711 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700712 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700713 EXPECT_FALSE(rtcp_sender_->TMMBR());
714 rtcp_sender_->SetTMMBRStatus(true);
715 EXPECT_TRUE(rtcp_sender_->TMMBR());
716 rtcp_sender_->SetTargetBitrate(kBitrateBps);
717 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
718 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200719 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
asapersson22ff75a2015-08-21 00:02:47 -0700720 // TMMBR should be included in each compound packet.
721 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
722 EXPECT_EQ(2, parser()->tmmbr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700723
724 rtcp_sender_->SetTMMBRStatus(false);
725 EXPECT_FALSE(rtcp_sender_->TMMBR());
726}
727
728TEST_F(RtcpSenderTest, SendTmmbn) {
pbosda903ea2015-10-02 02:36:56 -0700729 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200730 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700731 std::vector<rtcp::TmmbItem> bounding_set;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200732 const uint32_t kBitrateBps = 32768000;
asapersson22ff75a2015-08-21 00:02:47 -0700733 const uint32_t kPacketOh = 40;
734 const uint32_t kSourceSsrc = 12345;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200735 const rtcp::TmmbItem tmmbn(kSourceSsrc, kBitrateBps, kPacketOh);
danilchap6eaa3a42016-05-09 10:59:50 -0700736 bounding_set.push_back(tmmbn);
danilchap853ecb22016-08-22 08:26:15 -0700737 rtcp_sender_->SetTmmbn(bounding_set);
danilchap6eaa3a42016-05-09 10:59:50 -0700738
asapersson22ff75a2015-08-21 00:02:47 -0700739 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
740 EXPECT_EQ(1, parser()->sender_report()->num_packets());
741 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200742 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
743 EXPECT_EQ(1U, parser()->tmmbn()->items().size());
744 EXPECT_EQ(kBitrateBps, parser()->tmmbn()->items()[0].bitrate_bps());
745 EXPECT_EQ(kPacketOh, parser()->tmmbn()->items()[0].packet_overhead());
746 EXPECT_EQ(kSourceSsrc, parser()->tmmbn()->items()[0].ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700747}
748
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000749// This test is written to verify actual behaviour. It does not seem
750// to make much sense to send an empty TMMBN, since there is no place
751// to put an actual limit here. It's just information that no limit
752// is set, which is kind of the starting assumption.
753// See http://code.google.com/p/webrtc/issues/detail?id=468 for one
754// situation where this caused confusion.
755TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndEmpty) {
pbosda903ea2015-10-02 02:36:56 -0700756 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200757 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700758 std::vector<rtcp::TmmbItem> bounding_set;
danilchap853ecb22016-08-22 08:26:15 -0700759 rtcp_sender_->SetTmmbn(bounding_set);
asapersson22ff75a2015-08-21 00:02:47 -0700760 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
761 EXPECT_EQ(1, parser()->sender_report()->num_packets());
762 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200763 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
764 EXPECT_EQ(0U, parser()->tmmbn()->items().size());
hta@webrtc.org65a4e4e2012-04-30 11:23:41 +0000765}
766
asapersson22ff75a2015-08-21 00:02:47 -0700767TEST_F(RtcpSenderTest, SendCompoundPliRemb) {
768 const int kBitrate = 261011;
769 std::vector<uint32_t> ssrcs;
770 ssrcs.push_back(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700771 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200772 rtcp_sender_->SetRemb(kBitrate, ssrcs);
asapersson22ff75a2015-08-21 00:02:47 -0700773 std::set<RTCPPacketType> packet_types;
774 packet_types.insert(kRtcpRemb);
775 packet_types.insert(kRtcpPli);
776 EXPECT_EQ(0, rtcp_sender_->SendCompoundRTCP(feedback_state(), packet_types));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200777 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700778 EXPECT_EQ(1, parser()->pli()->num_packets());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000779}
Erik Språnga38233a2015-07-24 09:58:18 +0200780
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800781// This test is written to verify that BYE is always the last packet
782// type in a RTCP compoud packet. The rtcp_sender_ is recreated with
783// mock_transport, which is used to check for whether BYE at the end
784// of a RTCP compound packet.
785TEST_F(RtcpSenderTest, ByeMustBeLast) {
786 MockTransport mock_transport;
787 EXPECT_CALL(mock_transport, SendRtcp(_, _))
788 .WillOnce(Invoke([](const uint8_t* data, size_t len) {
789 const uint8_t* next_packet = data;
danilchapb1ed6092016-11-01 06:38:37 -0700790 const uint8_t* const packet_end = data + len;
791 rtcp::CommonHeader packet;
792 while (next_packet < packet_end) {
793 EXPECT_TRUE(packet.Parse(next_packet, packet_end - next_packet));
794 next_packet = packet.NextPacket();
795 if (packet.type() == rtcp::Bye::kPacketType) // Main test expectation.
796 EXPECT_EQ(0, packet_end - next_packet)
797 << "Bye packet should be last in a compound RTCP packet.";
798 if (next_packet == packet_end) // Validate test was set correctly.
799 EXPECT_EQ(packet.type(), rtcp::Bye::kPacketType)
800 << "Last packet in this test expected to be Bye.";
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800801 }
802
803 return true;
804 }));
805
806 // Re-configure rtcp_sender_ with mock_transport_
807 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800808 nullptr, nullptr, &mock_transport,
809 RtcpIntervalConfig{}));
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800810 rtcp_sender_->SetSSRC(kSenderSsrc);
811 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
danilchap71fead22016-08-18 02:01:49 -0700812 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200813 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds());
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800814
815 // Set up XR VoIP metric to be included with BYE
816 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
817 RTCPVoIPMetric metric;
818 EXPECT_EQ(0, rtcp_sender_->SetRTCPVoIPMetrics(&metric));
819 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
820}
821
sprang5e38c962016-12-01 05:18:09 -0800822TEST_F(RtcpSenderTest, SendXrWithTargetBitrate) {
823 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
824 const size_t kNumSpatialLayers = 2;
825 const size_t kNumTemporalLayers = 2;
826 BitrateAllocation allocation;
827 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
828 uint32_t start_bitrate_bps = (sl + 1) * 100000;
829 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl)
830 allocation.SetBitrate(sl, tl, start_bitrate_bps + (tl * 20000));
831 }
832 rtcp_sender_->SetVideoBitrateAllocation(allocation);
833
834 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
835 EXPECT_EQ(1, parser()->xr()->num_packets());
836 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
837 const rtc::Optional<rtcp::TargetBitrate>& target_bitrate =
838 parser()->xr()->target_bitrate();
839 ASSERT_TRUE(target_bitrate);
840 const std::vector<rtcp::TargetBitrate::BitrateItem>& bitrates =
841 target_bitrate->GetTargetBitrates();
842 EXPECT_EQ(kNumSpatialLayers * kNumTemporalLayers, bitrates.size());
843
844 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
845 uint32_t start_bitrate_bps = (sl + 1) * 100000;
846 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl) {
847 size_t index = (sl * kNumSpatialLayers) + tl;
848 const rtcp::TargetBitrate::BitrateItem& item = bitrates[index];
849 EXPECT_EQ(sl, item.spatial_layer);
850 EXPECT_EQ(tl, item.temporal_layer);
851 EXPECT_EQ(start_bitrate_bps + (tl * 20000),
852 item.target_bitrate_kbps * 1000);
853 }
854 }
855}
856
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000857} // namespace webrtc