blob: 974f19f5ee0c637956250558ebb785f99274cfe8 [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
asapersson22ff75a2015-08-21 00:02:47 -070031class RtcpPacketTypeCounterObserverImpl : public RtcpPacketTypeCounterObserver {
32 public:
33 RtcpPacketTypeCounterObserverImpl() : ssrc_(0) {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +000034 ~RtcpPacketTypeCounterObserverImpl() override = default;
asapersson22ff75a2015-08-21 00:02:47 -070035 void RtcpPacketTypesCounterUpdated(
36 uint32_t ssrc,
37 const RtcpPacketTypeCounter& packet_counter) override {
38 ssrc_ = ssrc;
39 counter_ = packet_counter;
40 }
41 uint32_t ssrc_;
42 RtcpPacketTypeCounter counter_;
43};
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000044
Yves Gerey665174f2018-06-19 15:03:05 +020045class TestTransport : public Transport, public RtpData {
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000046 public:
asapersson22ff75a2015-08-21 00:02:47 -070047 TestTransport() {}
48
stefan1d8a5062015-10-02 03:39:33 -070049 bool SendRtp(const uint8_t* /*data*/,
50 size_t /*len*/,
51 const PacketOptions& options) override {
pbos2d566682015-09-28 09:59:31 -070052 return false;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000053 }
pbos2d566682015-09-28 09:59:31 -070054 bool SendRtcp(const uint8_t* data, size_t len) override {
Danil Chapovalovba6f7be2016-09-02 18:29:10 +020055 parser_.Parse(data, len);
pbos2d566682015-09-28 09:59:31 -070056 return true;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000057 }
asapersson22ff75a2015-08-21 00:02:47 -070058 int OnReceivedPayloadData(const uint8_t* payload_data,
perkj16ccfdf2017-02-28 14:41:05 -080059 size_t payload_size,
asapersson22ff75a2015-08-21 00:02:47 -070060 const WebRtcRTPHeader* rtp_header) override {
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000061 return 0;
62 }
asapersson22ff75a2015-08-21 00:02:47 -070063 test::RtcpPacketParser parser_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000064};
65
Erik Språnga38233a2015-07-24 09:58:18 +020066namespace {
asapersson22ff75a2015-08-21 00:02:47 -070067static const uint32_t kSenderSsrc = 0x11111111;
68static const uint32_t kRemoteSsrc = 0x22222222;
Danil Chapovalov70ffead2016-07-20 15:26:59 +020069static const uint32_t kStartRtpTimestamp = 0x34567;
70static const uint32_t kRtpTimestamp = 0x45678;
Yves Gerey665174f2018-06-19 15:03:05 +020071} // namespace
Erik Språnga38233a2015-07-24 09:58:18 +020072
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000073class RtcpSenderTest : public ::testing::Test {
74 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +000075 RtcpSenderTest()
asapersson22ff75a2015-08-21 00:02:47 -070076 : clock_(1335900000),
Erik Språng737336d2016-07-29 12:59:36 +020077 receive_statistics_(ReceiveStatistics::Create(&clock_)),
78 retransmission_rate_limiter_(&clock_, 1000) {
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000079 RtpRtcp::Configuration configuration;
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000080 configuration.audio = false;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +000081 configuration.clock = &clock_;
asapersson22ff75a2015-08-21 00:02:47 -070082 configuration.outgoing_transport = &test_transport_;
Erik Språng737336d2016-07-29 12:59:36 +020083 configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000084
asapersson22ff75a2015-08-21 00:02:47 -070085 rtp_rtcp_impl_.reset(new ModuleRtpRtcpImpl(configuration));
sprang86fd9ed2015-09-29 04:45:43 -070086 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -080087 nullptr, nullptr, &test_transport_,
88 configuration.rtcp_interval_config));
asapersson22ff75a2015-08-21 00:02:47 -070089 rtcp_sender_->SetSSRC(kSenderSsrc);
90 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
danilchap71fead22016-08-18 02:01:49 -070091 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
Danil Chapovalov70ffead2016-07-20 15:26:59 +020092 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000093 }
Erik Språnga38233a2015-07-24 09:58:18 +020094
asapersson22ff75a2015-08-21 00:02:47 -070095 void InsertIncomingPacket(uint32_t remote_ssrc, uint16_t seq_num) {
96 RTPHeader header;
97 header.ssrc = remote_ssrc;
98 header.sequenceNumber = seq_num;
99 header.timestamp = 12345;
100 header.headerLength = 12;
101 size_t kPacketLength = 100;
102 receive_statistics_->IncomingPacket(header, kPacketLength, false);
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000103 }
104
asapersson22ff75a2015-08-21 00:02:47 -0700105 test::RtcpPacketParser* parser() { return &test_transport_.parser_; }
106
107 RTCPSender::FeedbackState feedback_state() {
108 return rtp_rtcp_impl_->GetFeedbackState();
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000109 }
110
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000111 SimulatedClock clock_;
asapersson22ff75a2015-08-21 00:02:47 -0700112 TestTransport test_transport_;
kwiberg84be5112016-04-27 01:19:58 -0700113 std::unique_ptr<ReceiveStatistics> receive_statistics_;
114 std::unique_ptr<ModuleRtpRtcpImpl> rtp_rtcp_impl_;
115 std::unique_ptr<RTCPSender> rtcp_sender_;
Erik Språng737336d2016-07-29 12:59:36 +0200116 RateLimiter retransmission_rate_limiter_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000117};
118
asapersson22ff75a2015-08-21 00:02:47 -0700119TEST_F(RtcpSenderTest, SetRtcpStatus) {
pbosda903ea2015-10-02 02:36:56 -0700120 EXPECT_EQ(RtcpMode::kOff, rtcp_sender_->Status());
121 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
122 EXPECT_EQ(RtcpMode::kReducedSize, rtcp_sender_->Status());
asapersson22ff75a2015-08-21 00:02:47 -0700123}
124
125TEST_F(RtcpSenderTest, SetSendingStatus) {
126 EXPECT_FALSE(rtcp_sender_->Sending());
127 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
128 EXPECT_TRUE(rtcp_sender_->Sending());
129}
130
131TEST_F(RtcpSenderTest, NoPacketSentIfOff) {
pbosda903ea2015-10-02 02:36:56 -0700132 rtcp_sender_->SetRTCPStatus(RtcpMode::kOff);
asapersson22ff75a2015-08-21 00:02:47 -0700133 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000134}
135
asapersson22ff75a2015-08-21 00:02:47 -0700136TEST_F(RtcpSenderTest, SendSr) {
137 const uint32_t kPacketCount = 0x12345;
138 const uint32_t kOctetCount = 0x23456;
pbosda903ea2015-10-02 02:36:56 -0700139 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000140 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200141 rtcp_sender_->SetSendingStatus(feedback_state, true);
asapersson22ff75a2015-08-21 00:02:47 -0700142 feedback_state.packets_sent = kPacketCount;
143 feedback_state.media_bytes_sent = kOctetCount;
danilchap21dc1892017-03-07 02:51:09 -0800144 NtpTime ntp = clock_.CurrentNtpTime();
asapersson22ff75a2015-08-21 00:02:47 -0700145 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
146 EXPECT_EQ(1, parser()->sender_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200147 EXPECT_EQ(kSenderSsrc, parser()->sender_report()->sender_ssrc());
danilchap21dc1892017-03-07 02:51:09 -0800148 EXPECT_EQ(ntp, parser()->sender_report()->ntp());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200149 EXPECT_EQ(kPacketCount, parser()->sender_report()->sender_packet_count());
150 EXPECT_EQ(kOctetCount, parser()->sender_report()->sender_octet_count());
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200151 EXPECT_EQ(kStartRtpTimestamp + kRtpTimestamp,
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200152 parser()->sender_report()->rtp_timestamp());
153 EXPECT_EQ(0U, parser()->sender_report()->report_blocks().size());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000154}
155
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200156TEST_F(RtcpSenderTest, DoNotSendSrBeforeRtp) {
157 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800158 nullptr, nullptr, &test_transport_,
159 RtcpIntervalConfig{}));
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200160 rtcp_sender_->SetSSRC(kSenderSsrc);
161 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
162 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
163 rtcp_sender_->SetSendingStatus(feedback_state(), true);
164
165 // Sender Report shouldn't be send as an SR nor as a Report.
166 rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr);
167 EXPECT_EQ(0, parser()->sender_report()->num_packets());
168 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
169 EXPECT_EQ(0, parser()->sender_report()->num_packets());
170 // Other packets (e.g. Pli) are allowed, even if useless.
171 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
172 EXPECT_EQ(1, parser()->pli()->num_packets());
173}
174
175TEST_F(RtcpSenderTest, DoNotSendCompundBeforeRtp) {
176 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800177 nullptr, nullptr, &test_transport_,
178 RtcpIntervalConfig{}));
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200179 rtcp_sender_->SetSSRC(kSenderSsrc);
180 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
181 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
182 rtcp_sender_->SetSendingStatus(feedback_state(), true);
183
184 // In compound mode no packets are allowed (e.g. Pli) because compound mode
185 // should start with Sender Report.
186 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
187 EXPECT_EQ(0, parser()->pli()->num_packets());
188}
189
asapersson22ff75a2015-08-21 00:02:47 -0700190TEST_F(RtcpSenderTest, SendRr) {
pbosda903ea2015-10-02 02:36:56 -0700191 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700192 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
193 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200194 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
195 EXPECT_EQ(0U, parser()->receiver_report()->report_blocks().size());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000196}
197
asapersson22ff75a2015-08-21 00:02:47 -0700198TEST_F(RtcpSenderTest, SendRrWithOneReportBlock) {
199 const uint16_t kSeqNum = 11111;
200 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
pbosda903ea2015-10-02 02:36:56 -0700201 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700202 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
203 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200204 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
205 ASSERT_EQ(1U, parser()->receiver_report()->report_blocks().size());
206 const rtcp::ReportBlock& rb = parser()->receiver_report()->report_blocks()[0];
207 EXPECT_EQ(kRemoteSsrc, rb.source_ssrc());
208 EXPECT_EQ(0U, rb.fraction_lost());
Harald Alvestrand70206d62017-12-08 08:59:07 +0100209 EXPECT_EQ(0, rb.cumulative_lost_signed());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200210 EXPECT_EQ(kSeqNum, rb.extended_high_seq_num());
asapersson22ff75a2015-08-21 00:02:47 -0700211}
212
213TEST_F(RtcpSenderTest, SendRrWithTwoReportBlocks) {
214 const uint16_t kSeqNum = 11111;
215 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
216 InsertIncomingPacket(kRemoteSsrc + 1, kSeqNum + 1);
pbosda903ea2015-10-02 02:36:56 -0700217 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700218 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
219 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200220 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
221 EXPECT_EQ(2U, parser()->receiver_report()->report_blocks().size());
222 EXPECT_EQ(kRemoteSsrc,
223 parser()->receiver_report()->report_blocks()[0].source_ssrc());
224 EXPECT_EQ(kRemoteSsrc + 1,
225 parser()->receiver_report()->report_blocks()[1].source_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700226}
227
228TEST_F(RtcpSenderTest, SendSdes) {
pbosda903ea2015-10-02 02:36:56 -0700229 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700230 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
231 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
232 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200233 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
234 EXPECT_EQ(kSenderSsrc, parser()->sdes()->chunks()[0].ssrc);
235 EXPECT_EQ("alice@host", parser()->sdes()->chunks()[0].cname);
asapersson22ff75a2015-08-21 00:02:47 -0700236}
237
danilchap74e8df8f2017-03-16 08:04:08 -0700238TEST_F(RtcpSenderTest, SendSdesWithMaxChunks) {
239 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
240 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
241 const char cname[] = "smith@host";
242 for (size_t i = 0; i < 30; ++i) {
243 const uint32_t csrc = 0x1234 + i;
244 EXPECT_EQ(0, rtcp_sender_->AddMixedCNAME(csrc, cname));
245 }
246 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
247 EXPECT_EQ(1, parser()->sdes()->num_packets());
248 EXPECT_EQ(31U, parser()->sdes()->chunks().size());
249}
250
asapersson22ff75a2015-08-21 00:02:47 -0700251TEST_F(RtcpSenderTest, SdesIncludedInCompoundPacket) {
pbosda903ea2015-10-02 02:36:56 -0700252 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700253 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
254 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
255 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
256 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200257 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
asapersson22ff75a2015-08-21 00:02:47 -0700258}
259
260TEST_F(RtcpSenderTest, SendBye) {
pbosda903ea2015-10-02 02:36:56 -0700261 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700262 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
263 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200264 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700265}
266
267TEST_F(RtcpSenderTest, StopSendingTriggersBye) {
pbosda903ea2015-10-02 02:36:56 -0700268 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700269 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
270 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
271 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200272 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700273}
274
275TEST_F(RtcpSenderTest, SendApp) {
276 const uint8_t kSubType = 30;
277 uint32_t name = 'n' << 24;
278 name += 'a' << 16;
279 name += 'm' << 8;
280 name += 'e';
281 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
asapersson22ff75a2015-08-21 00:02:47 -0700282 EXPECT_EQ(0, rtcp_sender_->SetApplicationSpecificData(kSubType, name, kData,
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200283 sizeof(kData)));
pbosda903ea2015-10-02 02:36:56 -0700284 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700285 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
286 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200287 EXPECT_EQ(kSubType, parser()->app()->sub_type());
288 EXPECT_EQ(name, parser()->app()->name());
289 EXPECT_EQ(sizeof(kData), parser()->app()->data_size());
290 EXPECT_EQ(0, memcmp(kData, parser()->app()->data(), sizeof(kData)));
asapersson22ff75a2015-08-21 00:02:47 -0700291}
292
Erik Språng521875a2015-09-01 10:11:16 +0200293TEST_F(RtcpSenderTest, SendEmptyApp) {
294 const uint8_t kSubType = 30;
295 const uint32_t kName = 0x6E616D65;
296
297 EXPECT_EQ(
298 0, rtcp_sender_->SetApplicationSpecificData(kSubType, kName, nullptr, 0));
299
pbosda903ea2015-10-02 02:36:56 -0700300 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Erik Språng521875a2015-09-01 10:11:16 +0200301 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
302 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200303 EXPECT_EQ(kSubType, parser()->app()->sub_type());
304 EXPECT_EQ(kName, parser()->app()->name());
305 EXPECT_EQ(0U, parser()->app()->data_size());
Erik Språng521875a2015-09-01 10:11:16 +0200306}
307
asapersson22ff75a2015-08-21 00:02:47 -0700308TEST_F(RtcpSenderTest, SetInvalidApplicationSpecificData) {
309 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't'};
310 const uint16_t kInvalidDataLength = sizeof(kData) / sizeof(kData[0]);
Yves Gerey665174f2018-06-19 15:03:05 +0200311 EXPECT_EQ(-1,
312 rtcp_sender_->SetApplicationSpecificData(
313 0, 0, kData, kInvalidDataLength)); // Should by multiple of 4.
asapersson22ff75a2015-08-21 00:02:47 -0700314}
315
danilchap498ee8e2017-02-08 05:24:31 -0800316TEST_F(RtcpSenderTest, SendFir) {
pbosda903ea2015-10-02 02:36:56 -0700317 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700318 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
319 EXPECT_EQ(1, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200320 EXPECT_EQ(kSenderSsrc, parser()->fir()->sender_ssrc());
321 EXPECT_EQ(1U, parser()->fir()->requests().size());
322 EXPECT_EQ(kRemoteSsrc, parser()->fir()->requests()[0].ssrc);
323 uint8_t seq = parser()->fir()->requests()[0].seq_nr;
asapersson22ff75a2015-08-21 00:02:47 -0700324 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
325 EXPECT_EQ(2, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200326 EXPECT_EQ(seq + 1, parser()->fir()->requests()[0].seq_nr);
asapersson22ff75a2015-08-21 00:02:47 -0700327}
328
asapersson22ff75a2015-08-21 00:02:47 -0700329TEST_F(RtcpSenderTest, SendPli) {
pbosda903ea2015-10-02 02:36:56 -0700330 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700331 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
332 EXPECT_EQ(1, parser()->pli()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200333 EXPECT_EQ(kSenderSsrc, parser()->pli()->sender_ssrc());
334 EXPECT_EQ(kRemoteSsrc, parser()->pli()->media_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700335}
336
asapersson22ff75a2015-08-21 00:02:47 -0700337TEST_F(RtcpSenderTest, SendNack) {
pbosda903ea2015-10-02 02:36:56 -0700338 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700339 const uint16_t kList[] = {0, 1, 16};
340 const int32_t kListLength = sizeof(kList) / sizeof(kList[0]);
341 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpNack, kListLength,
342 kList));
343 EXPECT_EQ(1, parser()->nack()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200344 EXPECT_EQ(kSenderSsrc, parser()->nack()->sender_ssrc());
345 EXPECT_EQ(kRemoteSsrc, parser()->nack()->media_ssrc());
346 EXPECT_THAT(parser()->nack()->packet_ids(), ElementsAre(0, 1, 16));
asapersson22ff75a2015-08-21 00:02:47 -0700347}
348
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200349TEST_F(RtcpSenderTest, RembNotIncludedBeforeSet) {
350 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
351
352 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
353
354 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
355 EXPECT_EQ(0, parser()->remb()->num_packets());
356}
357
358TEST_F(RtcpSenderTest, RembNotIncludedAfterUnset) {
danilchapba6aa902017-04-18 06:57:02 -0700359 const uint64_t kBitrate = 261011;
360 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
361 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200362 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
danilchapba6aa902017-04-18 06:57:02 -0700363 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
364 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200365 EXPECT_EQ(1, parser()->remb()->num_packets());
danilchapba6aa902017-04-18 06:57:02 -0700366
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200367 // Turn off REMB. rtcp_sender no longer should send it.
368 rtcp_sender_->UnsetRemb();
danilchapba6aa902017-04-18 06:57:02 -0700369 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
370 ASSERT_EQ(2, parser()->receiver_report()->num_packets());
371 EXPECT_EQ(1, parser()->remb()->num_packets());
Danil Chapovalov857a8fb2016-09-06 11:41:46 +0200372}
373
asapersson22ff75a2015-08-21 00:02:47 -0700374TEST_F(RtcpSenderTest, SendRemb) {
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200375 const uint64_t kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200376 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700377 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200378 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
379
380 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRemb);
381
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200382 EXPECT_EQ(1, parser()->remb()->num_packets());
383 EXPECT_EQ(kSenderSsrc, parser()->remb()->sender_ssrc());
384 EXPECT_EQ(kBitrate, parser()->remb()->bitrate_bps());
385 EXPECT_THAT(parser()->remb()->ssrcs(),
asapersson22ff75a2015-08-21 00:02:47 -0700386 ElementsAre(kRemoteSsrc, kRemoteSsrc + 1));
387}
388
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200389TEST_F(RtcpSenderTest, RembIncludedInEachCompoundPacketAfterSet) {
asapersson22ff75a2015-08-21 00:02:47 -0700390 const int kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200391 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700392 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200393 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
394
395 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200396 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700397 // REMB should be included in each compound packet.
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200398 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200399 EXPECT_EQ(2, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700400}
401
asapersson22ff75a2015-08-21 00:02:47 -0700402TEST_F(RtcpSenderTest, SendXrWithVoipMetric) {
pbosda903ea2015-10-02 02:36:56 -0700403 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700404 RTCPVoIPMetric metric;
405 metric.lossRate = 1;
406 metric.discardRate = 2;
407 metric.burstDensity = 3;
408 metric.gapDensity = 4;
409 metric.burstDuration = 0x1111;
410 metric.gapDuration = 0x2222;
411 metric.roundTripDelay = 0x3333;
412 metric.endSystemDelay = 0x4444;
413 metric.signalLevel = 5;
414 metric.noiseLevel = 6;
415 metric.RERL = 7;
416 metric.Gmin = 8;
417 metric.Rfactor = 9;
418 metric.extRfactor = 10;
419 metric.MOSLQ = 11;
420 metric.MOSCQ = 12;
421 metric.RXconfig = 13;
422 metric.JBnominal = 0x5555;
423 metric.JBmax = 0x6666;
424 metric.JBabsMax = 0x7777;
425 EXPECT_EQ(0, rtcp_sender_->SetRTCPVoIPMetrics(&metric));
426 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpXrVoipMetric));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200427 EXPECT_EQ(1, parser()->xr()->num_packets());
428 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
danilchap80ac24d2016-10-31 08:40:47 -0700429 ASSERT_TRUE(parser()->xr()->voip_metric());
430 EXPECT_EQ(kRemoteSsrc, parser()->xr()->voip_metric()->ssrc());
431 const auto& parsed_metric = parser()->xr()->voip_metric()->voip_metric();
432 EXPECT_EQ(metric.lossRate, parsed_metric.lossRate);
433 EXPECT_EQ(metric.discardRate, parsed_metric.discardRate);
434 EXPECT_EQ(metric.burstDensity, parsed_metric.burstDensity);
435 EXPECT_EQ(metric.gapDensity, parsed_metric.gapDensity);
436 EXPECT_EQ(metric.burstDuration, parsed_metric.burstDuration);
437 EXPECT_EQ(metric.gapDuration, parsed_metric.gapDuration);
438 EXPECT_EQ(metric.roundTripDelay, parsed_metric.roundTripDelay);
439 EXPECT_EQ(metric.endSystemDelay, parsed_metric.endSystemDelay);
440 EXPECT_EQ(metric.signalLevel, parsed_metric.signalLevel);
441 EXPECT_EQ(metric.noiseLevel, parsed_metric.noiseLevel);
442 EXPECT_EQ(metric.RERL, parsed_metric.RERL);
443 EXPECT_EQ(metric.Gmin, parsed_metric.Gmin);
444 EXPECT_EQ(metric.Rfactor, parsed_metric.Rfactor);
445 EXPECT_EQ(metric.extRfactor, parsed_metric.extRfactor);
446 EXPECT_EQ(metric.MOSLQ, parsed_metric.MOSLQ);
447 EXPECT_EQ(metric.MOSCQ, parsed_metric.MOSCQ);
448 EXPECT_EQ(metric.RXconfig, parsed_metric.RXconfig);
449 EXPECT_EQ(metric.JBnominal, parsed_metric.JBnominal);
450 EXPECT_EQ(metric.JBmax, parsed_metric.JBmax);
451 EXPECT_EQ(metric.JBabsMax, parsed_metric.JBabsMax);
asapersson22ff75a2015-08-21 00:02:47 -0700452}
453
454TEST_F(RtcpSenderTest, SendXrWithDlrr) {
pbosda903ea2015-10-02 02:36:56 -0700455 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000456 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
danilchap798896a2016-09-28 02:54:25 -0700457 rtcp::ReceiveTimeInfo last_xr_rr;
458 last_xr_rr.ssrc = 0x11111111;
459 last_xr_rr.last_rr = 0x22222222;
460 last_xr_rr.delay_since_last_rr = 0x33333333;
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200461 feedback_state.last_xr_rtis.push_back(last_xr_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000462 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200463 EXPECT_EQ(1, parser()->xr()->num_packets());
464 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200465 ASSERT_THAT(parser()->xr()->dlrr().sub_blocks(), SizeIs(1));
danilchap80ac24d2016-10-31 08:40:47 -0700466 EXPECT_EQ(last_xr_rr.ssrc, parser()->xr()->dlrr().sub_blocks()[0].ssrc);
467 EXPECT_EQ(last_xr_rr.last_rr, parser()->xr()->dlrr().sub_blocks()[0].last_rr);
danilchap798896a2016-09-28 02:54:25 -0700468 EXPECT_EQ(last_xr_rr.delay_since_last_rr,
danilchap80ac24d2016-10-31 08:40:47 -0700469 parser()->xr()->dlrr().sub_blocks()[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000470}
471
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200472TEST_F(RtcpSenderTest, SendXrWithMultipleDlrrSubBlocks) {
473 const size_t kNumReceivers = 2;
474 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
475 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
476 for (size_t i = 0; i < kNumReceivers; ++i) {
477 rtcp::ReceiveTimeInfo last_xr_rr;
478 last_xr_rr.ssrc = i;
479 last_xr_rr.last_rr = (i + 1) * 100;
480 last_xr_rr.delay_since_last_rr = (i + 2) * 200;
481 feedback_state.last_xr_rtis.push_back(last_xr_rr);
482 }
483
484 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
485 EXPECT_EQ(1, parser()->xr()->num_packets());
486 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
487 ASSERT_THAT(parser()->xr()->dlrr().sub_blocks(), SizeIs(kNumReceivers));
488 for (size_t i = 0; i < kNumReceivers; ++i) {
489 EXPECT_EQ(feedback_state.last_xr_rtis[i].ssrc,
490 parser()->xr()->dlrr().sub_blocks()[i].ssrc);
491 EXPECT_EQ(feedback_state.last_xr_rtis[i].last_rr,
492 parser()->xr()->dlrr().sub_blocks()[i].last_rr);
493 EXPECT_EQ(feedback_state.last_xr_rtis[i].delay_since_last_rr,
494 parser()->xr()->dlrr().sub_blocks()[i].delay_since_last_rr);
495 }
496}
497
asapersson22ff75a2015-08-21 00:02:47 -0700498TEST_F(RtcpSenderTest, SendXrWithRrtr) {
pbosda903ea2015-10-02 02:36:56 -0700499 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700500 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000501 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
danilchap21dc1892017-03-07 02:51:09 -0800502 NtpTime ntp = clock_.CurrentNtpTime();
asapersson22ff75a2015-08-21 00:02:47 -0700503 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200504 EXPECT_EQ(1, parser()->xr()->num_packets());
505 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
danilchap80ac24d2016-10-31 08:40:47 -0700506 EXPECT_FALSE(parser()->xr()->dlrr());
507 EXPECT_FALSE(parser()->xr()->voip_metric());
508 ASSERT_TRUE(parser()->xr()->rrtr());
danilchap21dc1892017-03-07 02:51:09 -0800509 EXPECT_EQ(ntp, parser()->xr()->rrtr()->ntp());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000510}
511
asapersson22ff75a2015-08-21 00:02:47 -0700512TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfSending) {
pbosda903ea2015-10-02 02:36:56 -0700513 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700514 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
515 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
516 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200517 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700518}
519
520TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfNotEnabled) {
pbosda903ea2015-10-02 02:36:56 -0700521 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700522 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000523 rtcp_sender_->SendRtcpXrReceiverReferenceTime(false);
asapersson22ff75a2015-08-21 00:02:47 -0700524 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200525 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000526}
527
asapersson22ff75a2015-08-21 00:02:47 -0700528TEST_F(RtcpSenderTest, TestRegisterRtcpPacketTypeObserver) {
529 RtcpPacketTypeCounterObserverImpl observer;
sprang86fd9ed2015-09-29 04:45:43 -0700530 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800531 &observer, nullptr, &test_transport_,
532 RtcpIntervalConfig{}));
asapersson22ff75a2015-08-21 00:02:47 -0700533 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700534 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700535 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
536 EXPECT_EQ(1, parser()->pli()->num_packets());
537 EXPECT_EQ(kRemoteSsrc, observer.ssrc_);
538 EXPECT_EQ(1U, observer.counter_.pli_packets);
539 EXPECT_EQ(clock_.TimeInMilliseconds(),
540 observer.counter_.first_packet_time_ms);
541}
542
543TEST_F(RtcpSenderTest, SendTmmbr) {
544 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700545 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700546 rtcp_sender_->SetTargetBitrate(kBitrateBps);
547 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpTmmbr));
548 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200549 EXPECT_EQ(kSenderSsrc, parser()->tmmbr()->sender_ssrc());
550 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
551 EXPECT_EQ(kBitrateBps, parser()->tmmbr()->requests()[0].bitrate_bps());
asapersson22ff75a2015-08-21 00:02:47 -0700552 // TODO(asapersson): tmmbr_item()->Overhead() looks broken, always zero.
553}
554
555TEST_F(RtcpSenderTest, TmmbrIncludedInCompoundPacketIfEnabled) {
556 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700557 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700558 EXPECT_FALSE(rtcp_sender_->TMMBR());
559 rtcp_sender_->SetTMMBRStatus(true);
560 EXPECT_TRUE(rtcp_sender_->TMMBR());
561 rtcp_sender_->SetTargetBitrate(kBitrateBps);
562 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
563 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200564 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
asapersson22ff75a2015-08-21 00:02:47 -0700565 // TMMBR should be included in each compound packet.
566 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
567 EXPECT_EQ(2, parser()->tmmbr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700568
569 rtcp_sender_->SetTMMBRStatus(false);
570 EXPECT_FALSE(rtcp_sender_->TMMBR());
571}
572
573TEST_F(RtcpSenderTest, SendTmmbn) {
pbosda903ea2015-10-02 02:36:56 -0700574 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200575 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700576 std::vector<rtcp::TmmbItem> bounding_set;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200577 const uint32_t kBitrateBps = 32768000;
asapersson22ff75a2015-08-21 00:02:47 -0700578 const uint32_t kPacketOh = 40;
579 const uint32_t kSourceSsrc = 12345;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200580 const rtcp::TmmbItem tmmbn(kSourceSsrc, kBitrateBps, kPacketOh);
danilchap6eaa3a42016-05-09 10:59:50 -0700581 bounding_set.push_back(tmmbn);
danilchap853ecb22016-08-22 08:26:15 -0700582 rtcp_sender_->SetTmmbn(bounding_set);
danilchap6eaa3a42016-05-09 10:59:50 -0700583
asapersson22ff75a2015-08-21 00:02:47 -0700584 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
585 EXPECT_EQ(1, parser()->sender_report()->num_packets());
586 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200587 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
588 EXPECT_EQ(1U, parser()->tmmbn()->items().size());
589 EXPECT_EQ(kBitrateBps, parser()->tmmbn()->items()[0].bitrate_bps());
590 EXPECT_EQ(kPacketOh, parser()->tmmbn()->items()[0].packet_overhead());
591 EXPECT_EQ(kSourceSsrc, parser()->tmmbn()->items()[0].ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700592}
593
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000594// This test is written to verify actual behaviour. It does not seem
595// to make much sense to send an empty TMMBN, since there is no place
596// to put an actual limit here. It's just information that no limit
597// is set, which is kind of the starting assumption.
598// See http://code.google.com/p/webrtc/issues/detail?id=468 for one
599// situation where this caused confusion.
600TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndEmpty) {
pbosda903ea2015-10-02 02:36:56 -0700601 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200602 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700603 std::vector<rtcp::TmmbItem> bounding_set;
danilchap853ecb22016-08-22 08:26:15 -0700604 rtcp_sender_->SetTmmbn(bounding_set);
asapersson22ff75a2015-08-21 00:02:47 -0700605 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
606 EXPECT_EQ(1, parser()->sender_report()->num_packets());
607 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200608 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
609 EXPECT_EQ(0U, parser()->tmmbn()->items().size());
hta@webrtc.org65a4e4e2012-04-30 11:23:41 +0000610}
611
asapersson22ff75a2015-08-21 00:02:47 -0700612TEST_F(RtcpSenderTest, SendCompoundPliRemb) {
613 const int kBitrate = 261011;
614 std::vector<uint32_t> ssrcs;
615 ssrcs.push_back(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700616 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200617 rtcp_sender_->SetRemb(kBitrate, ssrcs);
asapersson22ff75a2015-08-21 00:02:47 -0700618 std::set<RTCPPacketType> packet_types;
619 packet_types.insert(kRtcpRemb);
620 packet_types.insert(kRtcpPli);
621 EXPECT_EQ(0, rtcp_sender_->SendCompoundRTCP(feedback_state(), packet_types));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200622 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700623 EXPECT_EQ(1, parser()->pli()->num_packets());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000624}
Erik Språnga38233a2015-07-24 09:58:18 +0200625
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800626// This test is written to verify that BYE is always the last packet
627// type in a RTCP compoud packet. The rtcp_sender_ is recreated with
628// mock_transport, which is used to check for whether BYE at the end
629// of a RTCP compound packet.
630TEST_F(RtcpSenderTest, ByeMustBeLast) {
631 MockTransport mock_transport;
632 EXPECT_CALL(mock_transport, SendRtcp(_, _))
Yves Gerey665174f2018-06-19 15:03:05 +0200633 .WillOnce(Invoke([](const uint8_t* data, size_t len) {
634 const uint8_t* next_packet = data;
635 const uint8_t* const packet_end = data + len;
636 rtcp::CommonHeader packet;
637 while (next_packet < packet_end) {
638 EXPECT_TRUE(packet.Parse(next_packet, packet_end - next_packet));
639 next_packet = packet.NextPacket();
640 if (packet.type() ==
641 rtcp::Bye::kPacketType) // Main test expectation.
642 EXPECT_EQ(0, packet_end - next_packet)
643 << "Bye packet should be last in a compound RTCP packet.";
644 if (next_packet == packet_end) // Validate test was set correctly.
645 EXPECT_EQ(packet.type(), rtcp::Bye::kPacketType)
646 << "Last packet in this test expected to be Bye.";
647 }
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800648
Yves Gerey665174f2018-06-19 15:03:05 +0200649 return true;
650 }));
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800651
652 // Re-configure rtcp_sender_ with mock_transport_
653 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800654 nullptr, nullptr, &mock_transport,
655 RtcpIntervalConfig{}));
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800656 rtcp_sender_->SetSSRC(kSenderSsrc);
657 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
danilchap71fead22016-08-18 02:01:49 -0700658 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200659 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds());
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800660
661 // Set up XR VoIP metric to be included with BYE
662 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
663 RTCPVoIPMetric metric;
664 EXPECT_EQ(0, rtcp_sender_->SetRTCPVoIPMetrics(&metric));
665 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
666}
667
sprang5e38c962016-12-01 05:18:09 -0800668TEST_F(RtcpSenderTest, SendXrWithTargetBitrate) {
669 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
670 const size_t kNumSpatialLayers = 2;
671 const size_t kNumTemporalLayers = 2;
Erik Språng566124a2018-04-23 12:32:22 +0200672 VideoBitrateAllocation allocation;
sprang5e38c962016-12-01 05:18:09 -0800673 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
674 uint32_t start_bitrate_bps = (sl + 1) * 100000;
675 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl)
676 allocation.SetBitrate(sl, tl, start_bitrate_bps + (tl * 20000));
677 }
678 rtcp_sender_->SetVideoBitrateAllocation(allocation);
679
680 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
681 EXPECT_EQ(1, parser()->xr()->num_packets());
682 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
Danil Chapovalovd264df52018-06-14 12:59:38 +0200683 const absl::optional<rtcp::TargetBitrate>& target_bitrate =
sprang5e38c962016-12-01 05:18:09 -0800684 parser()->xr()->target_bitrate();
685 ASSERT_TRUE(target_bitrate);
686 const std::vector<rtcp::TargetBitrate::BitrateItem>& bitrates =
687 target_bitrate->GetTargetBitrates();
688 EXPECT_EQ(kNumSpatialLayers * kNumTemporalLayers, bitrates.size());
689
690 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
691 uint32_t start_bitrate_bps = (sl + 1) * 100000;
692 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl) {
693 size_t index = (sl * kNumSpatialLayers) + tl;
694 const rtcp::TargetBitrate::BitrateItem& item = bitrates[index];
695 EXPECT_EQ(sl, item.spatial_layer);
696 EXPECT_EQ(tl, item.temporal_layer);
697 EXPECT_EQ(start_bitrate_bps + (tl * 20000),
698 item.target_bitrate_kbps * 1000);
699 }
700 }
701}
702
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000703} // namespace webrtc