blob: 03faf0d5ced9721a5c1fb9b26fb5a568a5972da2 [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());
Harald Alvestrand4c34f432017-12-07 15:59:27 +0100361 EXPECT_EQ(0, rb.cumulative_lost());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200362 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 Chapovalovf74d6412017-10-18 13:32:57 +0200500TEST_F(RtcpSenderTest, RembNotIncludedBeforeSet) {
501 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
502
503 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
504
505 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
506 EXPECT_EQ(0, parser()->remb()->num_packets());
507}
508
509TEST_F(RtcpSenderTest, RembNotIncludedAfterUnset) {
danilchapba6aa902017-04-18 06:57:02 -0700510 const uint64_t kBitrate = 261011;
511 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
512 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200513 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
danilchapba6aa902017-04-18 06:57:02 -0700514 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
515 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200516 EXPECT_EQ(1, parser()->remb()->num_packets());
danilchapba6aa902017-04-18 06:57:02 -0700517
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200518 // Turn off REMB. rtcp_sender no longer should send it.
519 rtcp_sender_->UnsetRemb();
danilchapba6aa902017-04-18 06:57:02 -0700520 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
521 ASSERT_EQ(2, parser()->receiver_report()->num_packets());
522 EXPECT_EQ(1, parser()->remb()->num_packets());
Danil Chapovalov857a8fb2016-09-06 11:41:46 +0200523}
524
asapersson22ff75a2015-08-21 00:02:47 -0700525TEST_F(RtcpSenderTest, SendRemb) {
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200526 const uint64_t kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200527 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700528 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200529 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
530
531 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRemb);
532
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200533 EXPECT_EQ(1, parser()->remb()->num_packets());
534 EXPECT_EQ(kSenderSsrc, parser()->remb()->sender_ssrc());
535 EXPECT_EQ(kBitrate, parser()->remb()->bitrate_bps());
536 EXPECT_THAT(parser()->remb()->ssrcs(),
asapersson22ff75a2015-08-21 00:02:47 -0700537 ElementsAre(kRemoteSsrc, kRemoteSsrc + 1));
538}
539
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200540TEST_F(RtcpSenderTest, RembIncludedInEachCompoundPacketAfterSet) {
asapersson22ff75a2015-08-21 00:02:47 -0700541 const int kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200542 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700543 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200544 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
545
546 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200547 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700548 // REMB should be included in each compound packet.
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200549 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200550 EXPECT_EQ(2, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700551}
552
asapersson22ff75a2015-08-21 00:02:47 -0700553TEST_F(RtcpSenderTest, SendXrWithVoipMetric) {
pbosda903ea2015-10-02 02:36:56 -0700554 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700555 RTCPVoIPMetric metric;
556 metric.lossRate = 1;
557 metric.discardRate = 2;
558 metric.burstDensity = 3;
559 metric.gapDensity = 4;
560 metric.burstDuration = 0x1111;
561 metric.gapDuration = 0x2222;
562 metric.roundTripDelay = 0x3333;
563 metric.endSystemDelay = 0x4444;
564 metric.signalLevel = 5;
565 metric.noiseLevel = 6;
566 metric.RERL = 7;
567 metric.Gmin = 8;
568 metric.Rfactor = 9;
569 metric.extRfactor = 10;
570 metric.MOSLQ = 11;
571 metric.MOSCQ = 12;
572 metric.RXconfig = 13;
573 metric.JBnominal = 0x5555;
574 metric.JBmax = 0x6666;
575 metric.JBabsMax = 0x7777;
576 EXPECT_EQ(0, rtcp_sender_->SetRTCPVoIPMetrics(&metric));
577 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpXrVoipMetric));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200578 EXPECT_EQ(1, parser()->xr()->num_packets());
579 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
danilchap80ac24d2016-10-31 08:40:47 -0700580 ASSERT_TRUE(parser()->xr()->voip_metric());
581 EXPECT_EQ(kRemoteSsrc, parser()->xr()->voip_metric()->ssrc());
582 const auto& parsed_metric = parser()->xr()->voip_metric()->voip_metric();
583 EXPECT_EQ(metric.lossRate, parsed_metric.lossRate);
584 EXPECT_EQ(metric.discardRate, parsed_metric.discardRate);
585 EXPECT_EQ(metric.burstDensity, parsed_metric.burstDensity);
586 EXPECT_EQ(metric.gapDensity, parsed_metric.gapDensity);
587 EXPECT_EQ(metric.burstDuration, parsed_metric.burstDuration);
588 EXPECT_EQ(metric.gapDuration, parsed_metric.gapDuration);
589 EXPECT_EQ(metric.roundTripDelay, parsed_metric.roundTripDelay);
590 EXPECT_EQ(metric.endSystemDelay, parsed_metric.endSystemDelay);
591 EXPECT_EQ(metric.signalLevel, parsed_metric.signalLevel);
592 EXPECT_EQ(metric.noiseLevel, parsed_metric.noiseLevel);
593 EXPECT_EQ(metric.RERL, parsed_metric.RERL);
594 EXPECT_EQ(metric.Gmin, parsed_metric.Gmin);
595 EXPECT_EQ(metric.Rfactor, parsed_metric.Rfactor);
596 EXPECT_EQ(metric.extRfactor, parsed_metric.extRfactor);
597 EXPECT_EQ(metric.MOSLQ, parsed_metric.MOSLQ);
598 EXPECT_EQ(metric.MOSCQ, parsed_metric.MOSCQ);
599 EXPECT_EQ(metric.RXconfig, parsed_metric.RXconfig);
600 EXPECT_EQ(metric.JBnominal, parsed_metric.JBnominal);
601 EXPECT_EQ(metric.JBmax, parsed_metric.JBmax);
602 EXPECT_EQ(metric.JBabsMax, parsed_metric.JBabsMax);
asapersson22ff75a2015-08-21 00:02:47 -0700603}
604
605TEST_F(RtcpSenderTest, SendXrWithDlrr) {
pbosda903ea2015-10-02 02:36:56 -0700606 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000607 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
asapersson22ff75a2015-08-21 00:02:47 -0700608 feedback_state.has_last_xr_rr = true;
danilchap798896a2016-09-28 02:54:25 -0700609 rtcp::ReceiveTimeInfo last_xr_rr;
610 last_xr_rr.ssrc = 0x11111111;
611 last_xr_rr.last_rr = 0x22222222;
612 last_xr_rr.delay_since_last_rr = 0x33333333;
asapersson22ff75a2015-08-21 00:02:47 -0700613 feedback_state.last_xr_rr = last_xr_rr;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000614 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200615 EXPECT_EQ(1, parser()->xr()->num_packets());
616 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
danilchap80ac24d2016-10-31 08:40:47 -0700617 EXPECT_EQ(1U, parser()->xr()->dlrr().sub_blocks().size());
618 EXPECT_EQ(last_xr_rr.ssrc, parser()->xr()->dlrr().sub_blocks()[0].ssrc);
619 EXPECT_EQ(last_xr_rr.last_rr, parser()->xr()->dlrr().sub_blocks()[0].last_rr);
danilchap798896a2016-09-28 02:54:25 -0700620 EXPECT_EQ(last_xr_rr.delay_since_last_rr,
danilchap80ac24d2016-10-31 08:40:47 -0700621 parser()->xr()->dlrr().sub_blocks()[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000622}
623
asapersson22ff75a2015-08-21 00:02:47 -0700624TEST_F(RtcpSenderTest, SendXrWithRrtr) {
pbosda903ea2015-10-02 02:36:56 -0700625 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700626 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000627 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
danilchap21dc1892017-03-07 02:51:09 -0800628 NtpTime ntp = clock_.CurrentNtpTime();
asapersson22ff75a2015-08-21 00:02:47 -0700629 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200630 EXPECT_EQ(1, parser()->xr()->num_packets());
631 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
danilchap80ac24d2016-10-31 08:40:47 -0700632 EXPECT_FALSE(parser()->xr()->dlrr());
633 EXPECT_FALSE(parser()->xr()->voip_metric());
634 ASSERT_TRUE(parser()->xr()->rrtr());
danilchap21dc1892017-03-07 02:51:09 -0800635 EXPECT_EQ(ntp, parser()->xr()->rrtr()->ntp());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000636}
637
asapersson22ff75a2015-08-21 00:02:47 -0700638TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfSending) {
pbosda903ea2015-10-02 02:36:56 -0700639 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700640 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
641 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
642 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200643 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700644}
645
646TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfNotEnabled) {
pbosda903ea2015-10-02 02:36:56 -0700647 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700648 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000649 rtcp_sender_->SendRtcpXrReceiverReferenceTime(false);
asapersson22ff75a2015-08-21 00:02:47 -0700650 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200651 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000652}
653
asapersson22ff75a2015-08-21 00:02:47 -0700654TEST_F(RtcpSenderTest, TestRegisterRtcpPacketTypeObserver) {
655 RtcpPacketTypeCounterObserverImpl observer;
sprang86fd9ed2015-09-29 04:45:43 -0700656 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
terelius429c3452016-01-21 05:42:04 -0800657 &observer, nullptr, &test_transport_));
asapersson22ff75a2015-08-21 00:02:47 -0700658 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700659 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700660 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
661 EXPECT_EQ(1, parser()->pli()->num_packets());
662 EXPECT_EQ(kRemoteSsrc, observer.ssrc_);
663 EXPECT_EQ(1U, observer.counter_.pli_packets);
664 EXPECT_EQ(clock_.TimeInMilliseconds(),
665 observer.counter_.first_packet_time_ms);
666}
667
668TEST_F(RtcpSenderTest, SendTmmbr) {
669 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700670 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700671 rtcp_sender_->SetTargetBitrate(kBitrateBps);
672 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpTmmbr));
673 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200674 EXPECT_EQ(kSenderSsrc, parser()->tmmbr()->sender_ssrc());
675 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
676 EXPECT_EQ(kBitrateBps, parser()->tmmbr()->requests()[0].bitrate_bps());
asapersson22ff75a2015-08-21 00:02:47 -0700677 // TODO(asapersson): tmmbr_item()->Overhead() looks broken, always zero.
678}
679
680TEST_F(RtcpSenderTest, TmmbrIncludedInCompoundPacketIfEnabled) {
681 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700682 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700683 EXPECT_FALSE(rtcp_sender_->TMMBR());
684 rtcp_sender_->SetTMMBRStatus(true);
685 EXPECT_TRUE(rtcp_sender_->TMMBR());
686 rtcp_sender_->SetTargetBitrate(kBitrateBps);
687 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
688 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200689 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
asapersson22ff75a2015-08-21 00:02:47 -0700690 // TMMBR should be included in each compound packet.
691 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
692 EXPECT_EQ(2, parser()->tmmbr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700693
694 rtcp_sender_->SetTMMBRStatus(false);
695 EXPECT_FALSE(rtcp_sender_->TMMBR());
696}
697
698TEST_F(RtcpSenderTest, SendTmmbn) {
pbosda903ea2015-10-02 02:36:56 -0700699 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200700 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700701 std::vector<rtcp::TmmbItem> bounding_set;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200702 const uint32_t kBitrateBps = 32768000;
asapersson22ff75a2015-08-21 00:02:47 -0700703 const uint32_t kPacketOh = 40;
704 const uint32_t kSourceSsrc = 12345;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200705 const rtcp::TmmbItem tmmbn(kSourceSsrc, kBitrateBps, kPacketOh);
danilchap6eaa3a42016-05-09 10:59:50 -0700706 bounding_set.push_back(tmmbn);
danilchap853ecb22016-08-22 08:26:15 -0700707 rtcp_sender_->SetTmmbn(bounding_set);
danilchap6eaa3a42016-05-09 10:59:50 -0700708
asapersson22ff75a2015-08-21 00:02:47 -0700709 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
710 EXPECT_EQ(1, parser()->sender_report()->num_packets());
711 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200712 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
713 EXPECT_EQ(1U, parser()->tmmbn()->items().size());
714 EXPECT_EQ(kBitrateBps, parser()->tmmbn()->items()[0].bitrate_bps());
715 EXPECT_EQ(kPacketOh, parser()->tmmbn()->items()[0].packet_overhead());
716 EXPECT_EQ(kSourceSsrc, parser()->tmmbn()->items()[0].ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700717}
718
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000719// This test is written to verify actual behaviour. It does not seem
720// to make much sense to send an empty TMMBN, since there is no place
721// to put an actual limit here. It's just information that no limit
722// is set, which is kind of the starting assumption.
723// See http://code.google.com/p/webrtc/issues/detail?id=468 for one
724// situation where this caused confusion.
725TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndEmpty) {
pbosda903ea2015-10-02 02:36:56 -0700726 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200727 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700728 std::vector<rtcp::TmmbItem> bounding_set;
danilchap853ecb22016-08-22 08:26:15 -0700729 rtcp_sender_->SetTmmbn(bounding_set);
asapersson22ff75a2015-08-21 00:02:47 -0700730 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
731 EXPECT_EQ(1, parser()->sender_report()->num_packets());
732 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200733 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
734 EXPECT_EQ(0U, parser()->tmmbn()->items().size());
hta@webrtc.org65a4e4e2012-04-30 11:23:41 +0000735}
736
asapersson22ff75a2015-08-21 00:02:47 -0700737TEST_F(RtcpSenderTest, SendCompoundPliRemb) {
738 const int kBitrate = 261011;
739 std::vector<uint32_t> ssrcs;
740 ssrcs.push_back(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700741 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200742 rtcp_sender_->SetRemb(kBitrate, ssrcs);
asapersson22ff75a2015-08-21 00:02:47 -0700743 std::set<RTCPPacketType> packet_types;
744 packet_types.insert(kRtcpRemb);
745 packet_types.insert(kRtcpPli);
746 EXPECT_EQ(0, rtcp_sender_->SendCompoundRTCP(feedback_state(), packet_types));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200747 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700748 EXPECT_EQ(1, parser()->pli()->num_packets());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000749}
Erik Språnga38233a2015-07-24 09:58:18 +0200750
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800751// This test is written to verify that BYE is always the last packet
752// type in a RTCP compoud packet. The rtcp_sender_ is recreated with
753// mock_transport, which is used to check for whether BYE at the end
754// of a RTCP compound packet.
755TEST_F(RtcpSenderTest, ByeMustBeLast) {
756 MockTransport mock_transport;
757 EXPECT_CALL(mock_transport, SendRtcp(_, _))
758 .WillOnce(Invoke([](const uint8_t* data, size_t len) {
759 const uint8_t* next_packet = data;
danilchapb1ed6092016-11-01 06:38:37 -0700760 const uint8_t* const packet_end = data + len;
761 rtcp::CommonHeader packet;
762 while (next_packet < packet_end) {
763 EXPECT_TRUE(packet.Parse(next_packet, packet_end - next_packet));
764 next_packet = packet.NextPacket();
765 if (packet.type() == rtcp::Bye::kPacketType) // Main test expectation.
766 EXPECT_EQ(0, packet_end - next_packet)
767 << "Bye packet should be last in a compound RTCP packet.";
768 if (next_packet == packet_end) // Validate test was set correctly.
769 EXPECT_EQ(packet.type(), rtcp::Bye::kPacketType)
770 << "Last packet in this test expected to be Bye.";
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800771 }
772
773 return true;
774 }));
775
776 // Re-configure rtcp_sender_ with mock_transport_
777 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
778 nullptr, nullptr, &mock_transport));
779 rtcp_sender_->SetSSRC(kSenderSsrc);
780 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
danilchap71fead22016-08-18 02:01:49 -0700781 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200782 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds());
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800783
784 // Set up XR VoIP metric to be included with BYE
785 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
786 RTCPVoIPMetric metric;
787 EXPECT_EQ(0, rtcp_sender_->SetRTCPVoIPMetrics(&metric));
788 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
789}
790
sprang5e38c962016-12-01 05:18:09 -0800791TEST_F(RtcpSenderTest, SendXrWithTargetBitrate) {
792 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
793 const size_t kNumSpatialLayers = 2;
794 const size_t kNumTemporalLayers = 2;
795 BitrateAllocation allocation;
796 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
797 uint32_t start_bitrate_bps = (sl + 1) * 100000;
798 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl)
799 allocation.SetBitrate(sl, tl, start_bitrate_bps + (tl * 20000));
800 }
801 rtcp_sender_->SetVideoBitrateAllocation(allocation);
802
803 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
804 EXPECT_EQ(1, parser()->xr()->num_packets());
805 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
806 const rtc::Optional<rtcp::TargetBitrate>& target_bitrate =
807 parser()->xr()->target_bitrate();
808 ASSERT_TRUE(target_bitrate);
809 const std::vector<rtcp::TargetBitrate::BitrateItem>& bitrates =
810 target_bitrate->GetTargetBitrates();
811 EXPECT_EQ(kNumSpatialLayers * kNumTemporalLayers, bitrates.size());
812
813 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
814 uint32_t start_bitrate_bps = (sl + 1) * 100000;
815 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl) {
816 size_t index = (sl * kNumSpatialLayers) + tl;
817 const rtcp::TargetBitrate::BitrateItem& item = bitrates[index];
818 EXPECT_EQ(sl, item.spatial_layer);
819 EXPECT_EQ(tl, item.temporal_layer);
820 EXPECT_EQ(start_bitrate_bps + (tl * 20000),
821 item.target_bitrate_kbps * 1000);
822 }
823 }
824}
825
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000826} // namespace webrtc