blob: 77423746f17225696a5ed4f3e01528fffc1933ac [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) {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +0000188 ~RtcpPacketTypeCounterObserverImpl() override = default;
asapersson22ff75a2015-08-21 00:02:47 -0700189 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(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800242 nullptr, nullptr, &test_transport_,
243 configuration.rtcp_interval_config));
asapersson22ff75a2015-08-21 00:02:47 -0700244 rtcp_sender_->SetSSRC(kSenderSsrc);
245 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
danilchap71fead22016-08-18 02:01:49 -0700246 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200247 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000248 }
Erik Språnga38233a2015-07-24 09:58:18 +0200249
asapersson22ff75a2015-08-21 00:02:47 -0700250 void InsertIncomingPacket(uint32_t remote_ssrc, uint16_t seq_num) {
251 RTPHeader header;
252 header.ssrc = remote_ssrc;
253 header.sequenceNumber = seq_num;
254 header.timestamp = 12345;
255 header.headerLength = 12;
256 size_t kPacketLength = 100;
257 receive_statistics_->IncomingPacket(header, kPacketLength, false);
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000258 }
259
asapersson22ff75a2015-08-21 00:02:47 -0700260 test::RtcpPacketParser* parser() { return &test_transport_.parser_; }
261
262 RTCPSender::FeedbackState feedback_state() {
263 return rtp_rtcp_impl_->GetFeedbackState();
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000264 }
265
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000266 SimulatedClock clock_;
asapersson22ff75a2015-08-21 00:02:47 -0700267 TestTransport test_transport_;
kwiberg84be5112016-04-27 01:19:58 -0700268 std::unique_ptr<ReceiveStatistics> receive_statistics_;
269 std::unique_ptr<ModuleRtpRtcpImpl> rtp_rtcp_impl_;
270 std::unique_ptr<RTCPSender> rtcp_sender_;
Erik Språng737336d2016-07-29 12:59:36 +0200271 RateLimiter retransmission_rate_limiter_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000272};
273
asapersson22ff75a2015-08-21 00:02:47 -0700274TEST_F(RtcpSenderTest, SetRtcpStatus) {
pbosda903ea2015-10-02 02:36:56 -0700275 EXPECT_EQ(RtcpMode::kOff, rtcp_sender_->Status());
276 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
277 EXPECT_EQ(RtcpMode::kReducedSize, rtcp_sender_->Status());
asapersson22ff75a2015-08-21 00:02:47 -0700278}
279
280TEST_F(RtcpSenderTest, SetSendingStatus) {
281 EXPECT_FALSE(rtcp_sender_->Sending());
282 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
283 EXPECT_TRUE(rtcp_sender_->Sending());
284}
285
286TEST_F(RtcpSenderTest, NoPacketSentIfOff) {
pbosda903ea2015-10-02 02:36:56 -0700287 rtcp_sender_->SetRTCPStatus(RtcpMode::kOff);
asapersson22ff75a2015-08-21 00:02:47 -0700288 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000289}
290
asapersson22ff75a2015-08-21 00:02:47 -0700291TEST_F(RtcpSenderTest, SendSr) {
292 const uint32_t kPacketCount = 0x12345;
293 const uint32_t kOctetCount = 0x23456;
pbosda903ea2015-10-02 02:36:56 -0700294 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000295 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200296 rtcp_sender_->SetSendingStatus(feedback_state, true);
asapersson22ff75a2015-08-21 00:02:47 -0700297 feedback_state.packets_sent = kPacketCount;
298 feedback_state.media_bytes_sent = kOctetCount;
danilchap21dc1892017-03-07 02:51:09 -0800299 NtpTime ntp = clock_.CurrentNtpTime();
asapersson22ff75a2015-08-21 00:02:47 -0700300 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
301 EXPECT_EQ(1, parser()->sender_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200302 EXPECT_EQ(kSenderSsrc, parser()->sender_report()->sender_ssrc());
danilchap21dc1892017-03-07 02:51:09 -0800303 EXPECT_EQ(ntp, parser()->sender_report()->ntp());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200304 EXPECT_EQ(kPacketCount, parser()->sender_report()->sender_packet_count());
305 EXPECT_EQ(kOctetCount, parser()->sender_report()->sender_octet_count());
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200306 EXPECT_EQ(kStartRtpTimestamp + kRtpTimestamp,
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200307 parser()->sender_report()->rtp_timestamp());
308 EXPECT_EQ(0U, parser()->sender_report()->report_blocks().size());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000309}
310
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200311TEST_F(RtcpSenderTest, DoNotSendSrBeforeRtp) {
312 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800313 nullptr, nullptr, &test_transport_,
314 RtcpIntervalConfig{}));
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200315 rtcp_sender_->SetSSRC(kSenderSsrc);
316 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
317 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
318 rtcp_sender_->SetSendingStatus(feedback_state(), true);
319
320 // Sender Report shouldn't be send as an SR nor as a Report.
321 rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr);
322 EXPECT_EQ(0, parser()->sender_report()->num_packets());
323 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
324 EXPECT_EQ(0, parser()->sender_report()->num_packets());
325 // Other packets (e.g. Pli) are allowed, even if useless.
326 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
327 EXPECT_EQ(1, parser()->pli()->num_packets());
328}
329
330TEST_F(RtcpSenderTest, DoNotSendCompundBeforeRtp) {
331 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800332 nullptr, nullptr, &test_transport_,
333 RtcpIntervalConfig{}));
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200334 rtcp_sender_->SetSSRC(kSenderSsrc);
335 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
336 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
337 rtcp_sender_->SetSendingStatus(feedback_state(), true);
338
339 // In compound mode no packets are allowed (e.g. Pli) because compound mode
340 // should start with Sender Report.
341 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
342 EXPECT_EQ(0, parser()->pli()->num_packets());
343}
344
asapersson22ff75a2015-08-21 00:02:47 -0700345TEST_F(RtcpSenderTest, SendRr) {
pbosda903ea2015-10-02 02:36:56 -0700346 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700347 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
348 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200349 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
350 EXPECT_EQ(0U, parser()->receiver_report()->report_blocks().size());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000351}
352
asapersson22ff75a2015-08-21 00:02:47 -0700353TEST_F(RtcpSenderTest, SendRrWithOneReportBlock) {
354 const uint16_t kSeqNum = 11111;
355 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
pbosda903ea2015-10-02 02:36:56 -0700356 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700357 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
358 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200359 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
360 ASSERT_EQ(1U, parser()->receiver_report()->report_blocks().size());
361 const rtcp::ReportBlock& rb = parser()->receiver_report()->report_blocks()[0];
362 EXPECT_EQ(kRemoteSsrc, rb.source_ssrc());
363 EXPECT_EQ(0U, rb.fraction_lost());
Harald Alvestrand70206d62017-12-08 08:59:07 +0100364 EXPECT_EQ(0, rb.cumulative_lost_signed());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200365 EXPECT_EQ(kSeqNum, rb.extended_high_seq_num());
asapersson22ff75a2015-08-21 00:02:47 -0700366}
367
368TEST_F(RtcpSenderTest, SendRrWithTwoReportBlocks) {
369 const uint16_t kSeqNum = 11111;
370 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
371 InsertIncomingPacket(kRemoteSsrc + 1, kSeqNum + 1);
pbosda903ea2015-10-02 02:36:56 -0700372 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700373 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
374 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200375 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
376 EXPECT_EQ(2U, parser()->receiver_report()->report_blocks().size());
377 EXPECT_EQ(kRemoteSsrc,
378 parser()->receiver_report()->report_blocks()[0].source_ssrc());
379 EXPECT_EQ(kRemoteSsrc + 1,
380 parser()->receiver_report()->report_blocks()[1].source_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700381}
382
383TEST_F(RtcpSenderTest, SendSdes) {
pbosda903ea2015-10-02 02:36:56 -0700384 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700385 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
386 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
387 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200388 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
389 EXPECT_EQ(kSenderSsrc, parser()->sdes()->chunks()[0].ssrc);
390 EXPECT_EQ("alice@host", parser()->sdes()->chunks()[0].cname);
asapersson22ff75a2015-08-21 00:02:47 -0700391}
392
danilchap74e8df8f2017-03-16 08:04:08 -0700393TEST_F(RtcpSenderTest, SendSdesWithMaxChunks) {
394 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
395 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
396 const char cname[] = "smith@host";
397 for (size_t i = 0; i < 30; ++i) {
398 const uint32_t csrc = 0x1234 + i;
399 EXPECT_EQ(0, rtcp_sender_->AddMixedCNAME(csrc, cname));
400 }
401 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
402 EXPECT_EQ(1, parser()->sdes()->num_packets());
403 EXPECT_EQ(31U, parser()->sdes()->chunks().size());
404}
405
asapersson22ff75a2015-08-21 00:02:47 -0700406TEST_F(RtcpSenderTest, SdesIncludedInCompoundPacket) {
pbosda903ea2015-10-02 02:36:56 -0700407 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700408 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
409 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
410 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
411 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200412 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
asapersson22ff75a2015-08-21 00:02:47 -0700413}
414
415TEST_F(RtcpSenderTest, SendBye) {
pbosda903ea2015-10-02 02:36:56 -0700416 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700417 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
418 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200419 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700420}
421
422TEST_F(RtcpSenderTest, StopSendingTriggersBye) {
pbosda903ea2015-10-02 02:36:56 -0700423 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700424 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
425 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
426 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200427 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700428}
429
430TEST_F(RtcpSenderTest, SendApp) {
431 const uint8_t kSubType = 30;
432 uint32_t name = 'n' << 24;
433 name += 'a' << 16;
434 name += 'm' << 8;
435 name += 'e';
436 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
asapersson22ff75a2015-08-21 00:02:47 -0700437 EXPECT_EQ(0, rtcp_sender_->SetApplicationSpecificData(kSubType, name, kData,
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200438 sizeof(kData)));
pbosda903ea2015-10-02 02:36:56 -0700439 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700440 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
441 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200442 EXPECT_EQ(kSubType, parser()->app()->sub_type());
443 EXPECT_EQ(name, parser()->app()->name());
444 EXPECT_EQ(sizeof(kData), parser()->app()->data_size());
445 EXPECT_EQ(0, memcmp(kData, parser()->app()->data(), sizeof(kData)));
asapersson22ff75a2015-08-21 00:02:47 -0700446}
447
Erik Språng521875a2015-09-01 10:11:16 +0200448TEST_F(RtcpSenderTest, SendEmptyApp) {
449 const uint8_t kSubType = 30;
450 const uint32_t kName = 0x6E616D65;
451
452 EXPECT_EQ(
453 0, rtcp_sender_->SetApplicationSpecificData(kSubType, kName, nullptr, 0));
454
pbosda903ea2015-10-02 02:36:56 -0700455 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Erik Språng521875a2015-09-01 10:11:16 +0200456 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
457 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200458 EXPECT_EQ(kSubType, parser()->app()->sub_type());
459 EXPECT_EQ(kName, parser()->app()->name());
460 EXPECT_EQ(0U, parser()->app()->data_size());
Erik Språng521875a2015-09-01 10:11:16 +0200461}
462
asapersson22ff75a2015-08-21 00:02:47 -0700463TEST_F(RtcpSenderTest, SetInvalidApplicationSpecificData) {
464 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't'};
465 const uint16_t kInvalidDataLength = sizeof(kData) / sizeof(kData[0]);
466 EXPECT_EQ(-1, rtcp_sender_->SetApplicationSpecificData(
467 0, 0, kData, kInvalidDataLength)); // Should by multiple of 4.
468}
469
danilchap498ee8e2017-02-08 05:24:31 -0800470TEST_F(RtcpSenderTest, SendFir) {
pbosda903ea2015-10-02 02:36:56 -0700471 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700472 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
473 EXPECT_EQ(1, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200474 EXPECT_EQ(kSenderSsrc, parser()->fir()->sender_ssrc());
475 EXPECT_EQ(1U, parser()->fir()->requests().size());
476 EXPECT_EQ(kRemoteSsrc, parser()->fir()->requests()[0].ssrc);
477 uint8_t seq = parser()->fir()->requests()[0].seq_nr;
asapersson22ff75a2015-08-21 00:02:47 -0700478 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
479 EXPECT_EQ(2, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200480 EXPECT_EQ(seq + 1, parser()->fir()->requests()[0].seq_nr);
asapersson22ff75a2015-08-21 00:02:47 -0700481}
482
asapersson22ff75a2015-08-21 00:02:47 -0700483TEST_F(RtcpSenderTest, SendPli) {
pbosda903ea2015-10-02 02:36:56 -0700484 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700485 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
486 EXPECT_EQ(1, parser()->pli()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200487 EXPECT_EQ(kSenderSsrc, parser()->pli()->sender_ssrc());
488 EXPECT_EQ(kRemoteSsrc, parser()->pli()->media_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700489}
490
asapersson22ff75a2015-08-21 00:02:47 -0700491TEST_F(RtcpSenderTest, SendNack) {
pbosda903ea2015-10-02 02:36:56 -0700492 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700493 const uint16_t kList[] = {0, 1, 16};
494 const int32_t kListLength = sizeof(kList) / sizeof(kList[0]);
495 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpNack, kListLength,
496 kList));
497 EXPECT_EQ(1, parser()->nack()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200498 EXPECT_EQ(kSenderSsrc, parser()->nack()->sender_ssrc());
499 EXPECT_EQ(kRemoteSsrc, parser()->nack()->media_ssrc());
500 EXPECT_THAT(parser()->nack()->packet_ids(), ElementsAre(0, 1, 16));
asapersson22ff75a2015-08-21 00:02:47 -0700501}
502
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200503TEST_F(RtcpSenderTest, RembNotIncludedBeforeSet) {
504 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
505
506 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
507
508 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
509 EXPECT_EQ(0, parser()->remb()->num_packets());
510}
511
512TEST_F(RtcpSenderTest, RembNotIncludedAfterUnset) {
danilchapba6aa902017-04-18 06:57:02 -0700513 const uint64_t kBitrate = 261011;
514 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
515 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200516 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
danilchapba6aa902017-04-18 06:57:02 -0700517 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
518 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200519 EXPECT_EQ(1, parser()->remb()->num_packets());
danilchapba6aa902017-04-18 06:57:02 -0700520
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200521 // Turn off REMB. rtcp_sender no longer should send it.
522 rtcp_sender_->UnsetRemb();
danilchapba6aa902017-04-18 06:57:02 -0700523 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
524 ASSERT_EQ(2, parser()->receiver_report()->num_packets());
525 EXPECT_EQ(1, parser()->remb()->num_packets());
Danil Chapovalov857a8fb2016-09-06 11:41:46 +0200526}
527
asapersson22ff75a2015-08-21 00:02:47 -0700528TEST_F(RtcpSenderTest, SendRemb) {
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200529 const uint64_t kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200530 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700531 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200532 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
533
534 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRemb);
535
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200536 EXPECT_EQ(1, parser()->remb()->num_packets());
537 EXPECT_EQ(kSenderSsrc, parser()->remb()->sender_ssrc());
538 EXPECT_EQ(kBitrate, parser()->remb()->bitrate_bps());
539 EXPECT_THAT(parser()->remb()->ssrcs(),
asapersson22ff75a2015-08-21 00:02:47 -0700540 ElementsAre(kRemoteSsrc, kRemoteSsrc + 1));
541}
542
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200543TEST_F(RtcpSenderTest, RembIncludedInEachCompoundPacketAfterSet) {
asapersson22ff75a2015-08-21 00:02:47 -0700544 const int kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200545 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700546 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200547 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
548
549 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200550 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700551 // REMB should be included in each compound packet.
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200552 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200553 EXPECT_EQ(2, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700554}
555
asapersson22ff75a2015-08-21 00:02:47 -0700556TEST_F(RtcpSenderTest, SendXrWithVoipMetric) {
pbosda903ea2015-10-02 02:36:56 -0700557 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700558 RTCPVoIPMetric metric;
559 metric.lossRate = 1;
560 metric.discardRate = 2;
561 metric.burstDensity = 3;
562 metric.gapDensity = 4;
563 metric.burstDuration = 0x1111;
564 metric.gapDuration = 0x2222;
565 metric.roundTripDelay = 0x3333;
566 metric.endSystemDelay = 0x4444;
567 metric.signalLevel = 5;
568 metric.noiseLevel = 6;
569 metric.RERL = 7;
570 metric.Gmin = 8;
571 metric.Rfactor = 9;
572 metric.extRfactor = 10;
573 metric.MOSLQ = 11;
574 metric.MOSCQ = 12;
575 metric.RXconfig = 13;
576 metric.JBnominal = 0x5555;
577 metric.JBmax = 0x6666;
578 metric.JBabsMax = 0x7777;
579 EXPECT_EQ(0, rtcp_sender_->SetRTCPVoIPMetrics(&metric));
580 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpXrVoipMetric));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200581 EXPECT_EQ(1, parser()->xr()->num_packets());
582 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
danilchap80ac24d2016-10-31 08:40:47 -0700583 ASSERT_TRUE(parser()->xr()->voip_metric());
584 EXPECT_EQ(kRemoteSsrc, parser()->xr()->voip_metric()->ssrc());
585 const auto& parsed_metric = parser()->xr()->voip_metric()->voip_metric();
586 EXPECT_EQ(metric.lossRate, parsed_metric.lossRate);
587 EXPECT_EQ(metric.discardRate, parsed_metric.discardRate);
588 EXPECT_EQ(metric.burstDensity, parsed_metric.burstDensity);
589 EXPECT_EQ(metric.gapDensity, parsed_metric.gapDensity);
590 EXPECT_EQ(metric.burstDuration, parsed_metric.burstDuration);
591 EXPECT_EQ(metric.gapDuration, parsed_metric.gapDuration);
592 EXPECT_EQ(metric.roundTripDelay, parsed_metric.roundTripDelay);
593 EXPECT_EQ(metric.endSystemDelay, parsed_metric.endSystemDelay);
594 EXPECT_EQ(metric.signalLevel, parsed_metric.signalLevel);
595 EXPECT_EQ(metric.noiseLevel, parsed_metric.noiseLevel);
596 EXPECT_EQ(metric.RERL, parsed_metric.RERL);
597 EXPECT_EQ(metric.Gmin, parsed_metric.Gmin);
598 EXPECT_EQ(metric.Rfactor, parsed_metric.Rfactor);
599 EXPECT_EQ(metric.extRfactor, parsed_metric.extRfactor);
600 EXPECT_EQ(metric.MOSLQ, parsed_metric.MOSLQ);
601 EXPECT_EQ(metric.MOSCQ, parsed_metric.MOSCQ);
602 EXPECT_EQ(metric.RXconfig, parsed_metric.RXconfig);
603 EXPECT_EQ(metric.JBnominal, parsed_metric.JBnominal);
604 EXPECT_EQ(metric.JBmax, parsed_metric.JBmax);
605 EXPECT_EQ(metric.JBabsMax, parsed_metric.JBabsMax);
asapersson22ff75a2015-08-21 00:02:47 -0700606}
607
608TEST_F(RtcpSenderTest, SendXrWithDlrr) {
pbosda903ea2015-10-02 02:36:56 -0700609 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000610 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
asapersson22ff75a2015-08-21 00:02:47 -0700611 feedback_state.has_last_xr_rr = true;
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;
asapersson22ff75a2015-08-21 00:02:47 -0700616 feedback_state.last_xr_rr = 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());
danilchap80ac24d2016-10-31 08:40:47 -0700620 EXPECT_EQ(1U, parser()->xr()->dlrr().sub_blocks().size());
621 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
asapersson22ff75a2015-08-21 00:02:47 -0700627TEST_F(RtcpSenderTest, SendXrWithRrtr) {
pbosda903ea2015-10-02 02:36:56 -0700628 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700629 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000630 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
danilchap21dc1892017-03-07 02:51:09 -0800631 NtpTime ntp = clock_.CurrentNtpTime();
asapersson22ff75a2015-08-21 00:02:47 -0700632 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_FALSE(parser()->xr()->dlrr());
636 EXPECT_FALSE(parser()->xr()->voip_metric());
637 ASSERT_TRUE(parser()->xr()->rrtr());
danilchap21dc1892017-03-07 02:51:09 -0800638 EXPECT_EQ(ntp, parser()->xr()->rrtr()->ntp());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000639}
640
asapersson22ff75a2015-08-21 00:02:47 -0700641TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfSending) {
pbosda903ea2015-10-02 02:36:56 -0700642 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700643 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
644 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
645 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200646 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700647}
648
649TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfNotEnabled) {
pbosda903ea2015-10-02 02:36:56 -0700650 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700651 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000652 rtcp_sender_->SendRtcpXrReceiverReferenceTime(false);
asapersson22ff75a2015-08-21 00:02:47 -0700653 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200654 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000655}
656
asapersson22ff75a2015-08-21 00:02:47 -0700657TEST_F(RtcpSenderTest, TestRegisterRtcpPacketTypeObserver) {
658 RtcpPacketTypeCounterObserverImpl observer;
sprang86fd9ed2015-09-29 04:45:43 -0700659 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800660 &observer, nullptr, &test_transport_,
661 RtcpIntervalConfig{}));
asapersson22ff75a2015-08-21 00:02:47 -0700662 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700663 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700664 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
665 EXPECT_EQ(1, parser()->pli()->num_packets());
666 EXPECT_EQ(kRemoteSsrc, observer.ssrc_);
667 EXPECT_EQ(1U, observer.counter_.pli_packets);
668 EXPECT_EQ(clock_.TimeInMilliseconds(),
669 observer.counter_.first_packet_time_ms);
670}
671
672TEST_F(RtcpSenderTest, SendTmmbr) {
673 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700674 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700675 rtcp_sender_->SetTargetBitrate(kBitrateBps);
676 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpTmmbr));
677 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200678 EXPECT_EQ(kSenderSsrc, parser()->tmmbr()->sender_ssrc());
679 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
680 EXPECT_EQ(kBitrateBps, parser()->tmmbr()->requests()[0].bitrate_bps());
asapersson22ff75a2015-08-21 00:02:47 -0700681 // TODO(asapersson): tmmbr_item()->Overhead() looks broken, always zero.
682}
683
684TEST_F(RtcpSenderTest, TmmbrIncludedInCompoundPacketIfEnabled) {
685 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700686 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700687 EXPECT_FALSE(rtcp_sender_->TMMBR());
688 rtcp_sender_->SetTMMBRStatus(true);
689 EXPECT_TRUE(rtcp_sender_->TMMBR());
690 rtcp_sender_->SetTargetBitrate(kBitrateBps);
691 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
692 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200693 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
asapersson22ff75a2015-08-21 00:02:47 -0700694 // TMMBR should be included in each compound packet.
695 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
696 EXPECT_EQ(2, parser()->tmmbr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700697
698 rtcp_sender_->SetTMMBRStatus(false);
699 EXPECT_FALSE(rtcp_sender_->TMMBR());
700}
701
702TEST_F(RtcpSenderTest, SendTmmbn) {
pbosda903ea2015-10-02 02:36:56 -0700703 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200704 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700705 std::vector<rtcp::TmmbItem> bounding_set;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200706 const uint32_t kBitrateBps = 32768000;
asapersson22ff75a2015-08-21 00:02:47 -0700707 const uint32_t kPacketOh = 40;
708 const uint32_t kSourceSsrc = 12345;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200709 const rtcp::TmmbItem tmmbn(kSourceSsrc, kBitrateBps, kPacketOh);
danilchap6eaa3a42016-05-09 10:59:50 -0700710 bounding_set.push_back(tmmbn);
danilchap853ecb22016-08-22 08:26:15 -0700711 rtcp_sender_->SetTmmbn(bounding_set);
danilchap6eaa3a42016-05-09 10:59:50 -0700712
asapersson22ff75a2015-08-21 00:02:47 -0700713 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
714 EXPECT_EQ(1, parser()->sender_report()->num_packets());
715 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200716 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
717 EXPECT_EQ(1U, parser()->tmmbn()->items().size());
718 EXPECT_EQ(kBitrateBps, parser()->tmmbn()->items()[0].bitrate_bps());
719 EXPECT_EQ(kPacketOh, parser()->tmmbn()->items()[0].packet_overhead());
720 EXPECT_EQ(kSourceSsrc, parser()->tmmbn()->items()[0].ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700721}
722
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000723// This test is written to verify actual behaviour. It does not seem
724// to make much sense to send an empty TMMBN, since there is no place
725// to put an actual limit here. It's just information that no limit
726// is set, which is kind of the starting assumption.
727// See http://code.google.com/p/webrtc/issues/detail?id=468 for one
728// situation where this caused confusion.
729TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndEmpty) {
pbosda903ea2015-10-02 02:36:56 -0700730 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200731 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700732 std::vector<rtcp::TmmbItem> bounding_set;
danilchap853ecb22016-08-22 08:26:15 -0700733 rtcp_sender_->SetTmmbn(bounding_set);
asapersson22ff75a2015-08-21 00:02:47 -0700734 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
735 EXPECT_EQ(1, parser()->sender_report()->num_packets());
736 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200737 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
738 EXPECT_EQ(0U, parser()->tmmbn()->items().size());
hta@webrtc.org65a4e4e2012-04-30 11:23:41 +0000739}
740
asapersson22ff75a2015-08-21 00:02:47 -0700741TEST_F(RtcpSenderTest, SendCompoundPliRemb) {
742 const int kBitrate = 261011;
743 std::vector<uint32_t> ssrcs;
744 ssrcs.push_back(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700745 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200746 rtcp_sender_->SetRemb(kBitrate, ssrcs);
asapersson22ff75a2015-08-21 00:02:47 -0700747 std::set<RTCPPacketType> packet_types;
748 packet_types.insert(kRtcpRemb);
749 packet_types.insert(kRtcpPli);
750 EXPECT_EQ(0, rtcp_sender_->SendCompoundRTCP(feedback_state(), packet_types));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200751 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700752 EXPECT_EQ(1, parser()->pli()->num_packets());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000753}
Erik Språnga38233a2015-07-24 09:58:18 +0200754
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800755// This test is written to verify that BYE is always the last packet
756// type in a RTCP compoud packet. The rtcp_sender_ is recreated with
757// mock_transport, which is used to check for whether BYE at the end
758// of a RTCP compound packet.
759TEST_F(RtcpSenderTest, ByeMustBeLast) {
760 MockTransport mock_transport;
761 EXPECT_CALL(mock_transport, SendRtcp(_, _))
762 .WillOnce(Invoke([](const uint8_t* data, size_t len) {
763 const uint8_t* next_packet = data;
danilchapb1ed6092016-11-01 06:38:37 -0700764 const uint8_t* const packet_end = data + len;
765 rtcp::CommonHeader packet;
766 while (next_packet < packet_end) {
767 EXPECT_TRUE(packet.Parse(next_packet, packet_end - next_packet));
768 next_packet = packet.NextPacket();
769 if (packet.type() == rtcp::Bye::kPacketType) // Main test expectation.
770 EXPECT_EQ(0, packet_end - next_packet)
771 << "Bye packet should be last in a compound RTCP packet.";
772 if (next_packet == packet_end) // Validate test was set correctly.
773 EXPECT_EQ(packet.type(), rtcp::Bye::kPacketType)
774 << "Last packet in this test expected to be Bye.";
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800775 }
776
777 return true;
778 }));
779
780 // Re-configure rtcp_sender_ with mock_transport_
781 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800782 nullptr, nullptr, &mock_transport,
783 RtcpIntervalConfig{}));
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800784 rtcp_sender_->SetSSRC(kSenderSsrc);
785 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
danilchap71fead22016-08-18 02:01:49 -0700786 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200787 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds());
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800788
789 // Set up XR VoIP metric to be included with BYE
790 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
791 RTCPVoIPMetric metric;
792 EXPECT_EQ(0, rtcp_sender_->SetRTCPVoIPMetrics(&metric));
793 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
794}
795
sprang5e38c962016-12-01 05:18:09 -0800796TEST_F(RtcpSenderTest, SendXrWithTargetBitrate) {
797 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
798 const size_t kNumSpatialLayers = 2;
799 const size_t kNumTemporalLayers = 2;
800 BitrateAllocation allocation;
801 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
802 uint32_t start_bitrate_bps = (sl + 1) * 100000;
803 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl)
804 allocation.SetBitrate(sl, tl, start_bitrate_bps + (tl * 20000));
805 }
806 rtcp_sender_->SetVideoBitrateAllocation(allocation);
807
808 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
809 EXPECT_EQ(1, parser()->xr()->num_packets());
810 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
811 const rtc::Optional<rtcp::TargetBitrate>& target_bitrate =
812 parser()->xr()->target_bitrate();
813 ASSERT_TRUE(target_bitrate);
814 const std::vector<rtcp::TargetBitrate::BitrateItem>& bitrates =
815 target_bitrate->GetTargetBitrates();
816 EXPECT_EQ(kNumSpatialLayers * kNumTemporalLayers, bitrates.size());
817
818 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
819 uint32_t start_bitrate_bps = (sl + 1) * 100000;
820 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl) {
821 size_t index = (sl * kNumSpatialLayers) + tl;
822 const rtcp::TargetBitrate::BitrateItem& item = bitrates[index];
823 EXPECT_EQ(sl, item.spatial_layer);
824 EXPECT_EQ(tl, item.temporal_layer);
825 EXPECT_EQ(start_bitrate_bps + (tl * 20000),
826 item.target_bitrate_kbps * 1000);
827 }
828 }
829}
830
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000831} // namespace webrtc