blob: c3f3920d3eebc131b3cd5b4046442af1ddb1a2c1 [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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "modules/rtp_rtcp/source/rtcp_sender.h"
12
kwiberg84be5112016-04-27 01:19:58 -070013#include <memory>
Per Kjellander16999812019-10-10 12:57:28 +020014#include <utility>
kwiberg84be5112016-04-27 01:19:58 -070015
Elad Alone86af2c2019-06-03 14:37:50 +020016#include "absl/base/macros.h"
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +020017#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
19#include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
Niels Möller1f3206c2018-09-14 08:26:32 +020020#include "modules/rtp_rtcp/source/rtp_packet_received.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "modules/rtp_rtcp/source/rtp_rtcp_impl.h"
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +020022#include "modules/rtp_rtcp/source/time_util.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "rtc_base/rate_limiter.h"
24#include "test/gmock.h"
25#include "test/gtest.h"
26#include "test/mock_transport.h"
27#include "test/rtcp_packet_parser.h"
asapersson22ff75a2015-08-21 00:02:47 -070028
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -080029using ::testing::_;
asapersson22ff75a2015-08-21 00:02:47 -070030using ::testing::ElementsAre;
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -080031using ::testing::Invoke;
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +020032using ::testing::SizeIs;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000033
34namespace webrtc {
35
asapersson22ff75a2015-08-21 00:02:47 -070036class RtcpPacketTypeCounterObserverImpl : public RtcpPacketTypeCounterObserver {
37 public:
38 RtcpPacketTypeCounterObserverImpl() : ssrc_(0) {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +000039 ~RtcpPacketTypeCounterObserverImpl() override = default;
asapersson22ff75a2015-08-21 00:02:47 -070040 void RtcpPacketTypesCounterUpdated(
41 uint32_t ssrc,
42 const RtcpPacketTypeCounter& packet_counter) override {
43 ssrc_ = ssrc;
44 counter_ = packet_counter;
45 }
46 uint32_t ssrc_;
47 RtcpPacketTypeCounter counter_;
48};
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000049
Niels Möller8fb57462018-11-13 10:08:33 +010050class TestTransport : public Transport {
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000051 public:
asapersson22ff75a2015-08-21 00:02:47 -070052 TestTransport() {}
53
stefan1d8a5062015-10-02 03:39:33 -070054 bool SendRtp(const uint8_t* /*data*/,
55 size_t /*len*/,
56 const PacketOptions& options) override {
pbos2d566682015-09-28 09:59:31 -070057 return false;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000058 }
pbos2d566682015-09-28 09:59:31 -070059 bool SendRtcp(const uint8_t* data, size_t len) override {
Danil Chapovalovba6f7be2016-09-02 18:29:10 +020060 parser_.Parse(data, len);
pbos2d566682015-09-28 09:59:31 -070061 return true;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000062 }
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) {
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +000079 RtpRtcp::Configuration configuration = GetDefaultConfig();
80 rtp_rtcp_impl_.reset(new ModuleRtpRtcpImpl(configuration));
81 rtcp_sender_.reset(new RTCPSender(configuration));
82 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
83 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
84 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds(),
85 /*payload_type=*/0);
86 }
87
88 RtpRtcp::Configuration GetDefaultConfig() {
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000089 RtpRtcp::Configuration configuration;
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000090 configuration.audio = false;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +000091 configuration.clock = &clock_;
asapersson22ff75a2015-08-21 00:02:47 -070092 configuration.outgoing_transport = &test_transport_;
Erik Språng737336d2016-07-29 12:59:36 +020093 configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080094 configuration.rtcp_report_interval_ms = 1000;
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +000095 configuration.receive_statistics = receive_statistics_.get();
Erik Språng54d5d2c2019-08-20 17:22:36 +020096 configuration.local_media_ssrc = kSenderSsrc;
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +000097 return configuration;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000098 }
Erik Språnga38233a2015-07-24 09:58:18 +020099
asapersson22ff75a2015-08-21 00:02:47 -0700100 void InsertIncomingPacket(uint32_t remote_ssrc, uint16_t seq_num) {
Niels Möller1f3206c2018-09-14 08:26:32 +0200101 RtpPacketReceived packet;
102 packet.SetSsrc(remote_ssrc);
103 packet.SetSequenceNumber(seq_num);
104 packet.SetTimestamp(12345);
105 packet.SetPayloadSize(100 - 12);
106 receive_statistics_->OnRtpPacket(packet);
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000107 }
108
asapersson22ff75a2015-08-21 00:02:47 -0700109 test::RtcpPacketParser* parser() { return &test_transport_.parser_; }
110
111 RTCPSender::FeedbackState feedback_state() {
112 return rtp_rtcp_impl_->GetFeedbackState();
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000113 }
114
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000115 SimulatedClock clock_;
asapersson22ff75a2015-08-21 00:02:47 -0700116 TestTransport test_transport_;
kwiberg84be5112016-04-27 01:19:58 -0700117 std::unique_ptr<ReceiveStatistics> receive_statistics_;
118 std::unique_ptr<ModuleRtpRtcpImpl> rtp_rtcp_impl_;
119 std::unique_ptr<RTCPSender> rtcp_sender_;
Erik Språng737336d2016-07-29 12:59:36 +0200120 RateLimiter retransmission_rate_limiter_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000121};
122
asapersson22ff75a2015-08-21 00:02:47 -0700123TEST_F(RtcpSenderTest, SetRtcpStatus) {
pbosda903ea2015-10-02 02:36:56 -0700124 EXPECT_EQ(RtcpMode::kOff, rtcp_sender_->Status());
125 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
126 EXPECT_EQ(RtcpMode::kReducedSize, rtcp_sender_->Status());
asapersson22ff75a2015-08-21 00:02:47 -0700127}
128
129TEST_F(RtcpSenderTest, SetSendingStatus) {
130 EXPECT_FALSE(rtcp_sender_->Sending());
131 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
132 EXPECT_TRUE(rtcp_sender_->Sending());
133}
134
135TEST_F(RtcpSenderTest, NoPacketSentIfOff) {
pbosda903ea2015-10-02 02:36:56 -0700136 rtcp_sender_->SetRTCPStatus(RtcpMode::kOff);
asapersson22ff75a2015-08-21 00:02:47 -0700137 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000138}
139
asapersson22ff75a2015-08-21 00:02:47 -0700140TEST_F(RtcpSenderTest, SendSr) {
141 const uint32_t kPacketCount = 0x12345;
142 const uint32_t kOctetCount = 0x23456;
pbosda903ea2015-10-02 02:36:56 -0700143 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000144 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200145 rtcp_sender_->SetSendingStatus(feedback_state, true);
asapersson22ff75a2015-08-21 00:02:47 -0700146 feedback_state.packets_sent = kPacketCount;
147 feedback_state.media_bytes_sent = kOctetCount;
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200148 NtpTime ntp = TimeMicrosToNtp(clock_.TimeInMicroseconds());
asapersson22ff75a2015-08-21 00:02:47 -0700149 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
150 EXPECT_EQ(1, parser()->sender_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200151 EXPECT_EQ(kSenderSsrc, parser()->sender_report()->sender_ssrc());
danilchap21dc1892017-03-07 02:51:09 -0800152 EXPECT_EQ(ntp, parser()->sender_report()->ntp());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200153 EXPECT_EQ(kPacketCount, parser()->sender_report()->sender_packet_count());
154 EXPECT_EQ(kOctetCount, parser()->sender_report()->sender_octet_count());
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200155 EXPECT_EQ(kStartRtpTimestamp + kRtpTimestamp,
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200156 parser()->sender_report()->rtp_timestamp());
157 EXPECT_EQ(0U, parser()->sender_report()->report_blocks().size());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000158}
159
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200160TEST_F(RtcpSenderTest, SendConsecutiveSrWithExactSlope) {
161 const uint32_t kPacketCount = 0x12345;
162 const uint32_t kOctetCount = 0x23456;
163 const int kTimeBetweenSRsUs = 10043; // Not exact value in milliseconds.
164 const int kExtraPackets = 30;
165 // Make sure clock is not exactly at some milliseconds point.
166 clock_.AdvanceTimeMicroseconds(kTimeBetweenSRsUs);
167 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
168 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
169 rtcp_sender_->SetSendingStatus(feedback_state, true);
170 feedback_state.packets_sent = kPacketCount;
171 feedback_state.media_bytes_sent = kOctetCount;
172
173 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
174 EXPECT_EQ(1, parser()->sender_report()->num_packets());
175 NtpTime ntp1 = parser()->sender_report()->ntp();
176 uint32_t rtp1 = parser()->sender_report()->rtp_timestamp();
177
178 // Send more SRs to ensure slope is always exact for different offsets
179 for (int packets = 1; packets <= kExtraPackets; ++packets) {
180 clock_.AdvanceTimeMicroseconds(kTimeBetweenSRsUs);
181 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
182 EXPECT_EQ(packets + 1, parser()->sender_report()->num_packets());
183
184 NtpTime ntp2 = parser()->sender_report()->ntp();
185 uint32_t rtp2 = parser()->sender_report()->rtp_timestamp();
186
187 uint32_t ntp_diff_in_rtp_units =
188 (ntp2.ToMs() - ntp1.ToMs()) * (kVideoPayloadTypeFrequency / 1000);
189 EXPECT_EQ(rtp2 - rtp1, ntp_diff_in_rtp_units);
190 }
191}
192
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200193TEST_F(RtcpSenderTest, DoNotSendSrBeforeRtp) {
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +0000194 RtpRtcp::Configuration config;
195 config.clock = &clock_;
196 config.receive_statistics = receive_statistics_.get();
197 config.outgoing_transport = &test_transport_;
198 config.rtcp_report_interval_ms = 1000;
Erik Språng54d5d2c2019-08-20 17:22:36 +0200199 config.local_media_ssrc = kSenderSsrc;
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +0000200 rtcp_sender_.reset(new RTCPSender(config));
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200201 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
202 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
203 rtcp_sender_->SetSendingStatus(feedback_state(), true);
204
205 // Sender Report shouldn't be send as an SR nor as a Report.
206 rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr);
207 EXPECT_EQ(0, parser()->sender_report()->num_packets());
208 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
209 EXPECT_EQ(0, parser()->sender_report()->num_packets());
210 // Other packets (e.g. Pli) are allowed, even if useless.
211 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
212 EXPECT_EQ(1, parser()->pli()->num_packets());
213}
214
215TEST_F(RtcpSenderTest, DoNotSendCompundBeforeRtp) {
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +0000216 RtpRtcp::Configuration config;
217 config.clock = &clock_;
218 config.receive_statistics = receive_statistics_.get();
219 config.outgoing_transport = &test_transport_;
220 config.rtcp_report_interval_ms = 1000;
Erik Språng54d5d2c2019-08-20 17:22:36 +0200221 config.local_media_ssrc = kSenderSsrc;
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +0000222 rtcp_sender_.reset(new RTCPSender(config));
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200223 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
224 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
225 rtcp_sender_->SetSendingStatus(feedback_state(), true);
226
227 // In compound mode no packets are allowed (e.g. Pli) because compound mode
228 // should start with Sender Report.
229 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
230 EXPECT_EQ(0, parser()->pli()->num_packets());
231}
232
asapersson22ff75a2015-08-21 00:02:47 -0700233TEST_F(RtcpSenderTest, SendRr) {
pbosda903ea2015-10-02 02:36:56 -0700234 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700235 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
236 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200237 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
238 EXPECT_EQ(0U, parser()->receiver_report()->report_blocks().size());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000239}
240
asapersson22ff75a2015-08-21 00:02:47 -0700241TEST_F(RtcpSenderTest, SendRrWithOneReportBlock) {
242 const uint16_t kSeqNum = 11111;
243 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
pbosda903ea2015-10-02 02:36:56 -0700244 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700245 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
246 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200247 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
248 ASSERT_EQ(1U, parser()->receiver_report()->report_blocks().size());
249 const rtcp::ReportBlock& rb = parser()->receiver_report()->report_blocks()[0];
250 EXPECT_EQ(kRemoteSsrc, rb.source_ssrc());
251 EXPECT_EQ(0U, rb.fraction_lost());
Harald Alvestrand70206d62017-12-08 08:59:07 +0100252 EXPECT_EQ(0, rb.cumulative_lost_signed());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200253 EXPECT_EQ(kSeqNum, rb.extended_high_seq_num());
asapersson22ff75a2015-08-21 00:02:47 -0700254}
255
256TEST_F(RtcpSenderTest, SendRrWithTwoReportBlocks) {
257 const uint16_t kSeqNum = 11111;
258 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
259 InsertIncomingPacket(kRemoteSsrc + 1, kSeqNum + 1);
pbosda903ea2015-10-02 02:36:56 -0700260 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700261 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
262 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200263 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
264 EXPECT_EQ(2U, parser()->receiver_report()->report_blocks().size());
265 EXPECT_EQ(kRemoteSsrc,
266 parser()->receiver_report()->report_blocks()[0].source_ssrc());
267 EXPECT_EQ(kRemoteSsrc + 1,
268 parser()->receiver_report()->report_blocks()[1].source_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700269}
270
271TEST_F(RtcpSenderTest, SendSdes) {
pbosda903ea2015-10-02 02:36:56 -0700272 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700273 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
274 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
275 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200276 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
277 EXPECT_EQ(kSenderSsrc, parser()->sdes()->chunks()[0].ssrc);
278 EXPECT_EQ("alice@host", parser()->sdes()->chunks()[0].cname);
asapersson22ff75a2015-08-21 00:02:47 -0700279}
280
danilchap74e8df8f2017-03-16 08:04:08 -0700281TEST_F(RtcpSenderTest, SendSdesWithMaxChunks) {
282 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
283 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
284 const char cname[] = "smith@host";
285 for (size_t i = 0; i < 30; ++i) {
286 const uint32_t csrc = 0x1234 + i;
287 EXPECT_EQ(0, rtcp_sender_->AddMixedCNAME(csrc, cname));
288 }
289 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
290 EXPECT_EQ(1, parser()->sdes()->num_packets());
291 EXPECT_EQ(31U, parser()->sdes()->chunks().size());
292}
293
asapersson22ff75a2015-08-21 00:02:47 -0700294TEST_F(RtcpSenderTest, SdesIncludedInCompoundPacket) {
pbosda903ea2015-10-02 02:36:56 -0700295 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700296 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
297 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
298 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
299 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200300 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
asapersson22ff75a2015-08-21 00:02:47 -0700301}
302
303TEST_F(RtcpSenderTest, SendBye) {
pbosda903ea2015-10-02 02:36:56 -0700304 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700305 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
306 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200307 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700308}
309
310TEST_F(RtcpSenderTest, StopSendingTriggersBye) {
pbosda903ea2015-10-02 02:36:56 -0700311 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700312 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
313 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
314 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200315 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700316}
317
318TEST_F(RtcpSenderTest, SendApp) {
319 const uint8_t kSubType = 30;
320 uint32_t name = 'n' << 24;
321 name += 'a' << 16;
322 name += 'm' << 8;
323 name += 'e';
324 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
asapersson22ff75a2015-08-21 00:02:47 -0700325 EXPECT_EQ(0, rtcp_sender_->SetApplicationSpecificData(kSubType, name, kData,
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200326 sizeof(kData)));
pbosda903ea2015-10-02 02:36:56 -0700327 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700328 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
329 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200330 EXPECT_EQ(kSubType, parser()->app()->sub_type());
331 EXPECT_EQ(name, parser()->app()->name());
332 EXPECT_EQ(sizeof(kData), parser()->app()->data_size());
333 EXPECT_EQ(0, memcmp(kData, parser()->app()->data(), sizeof(kData)));
asapersson22ff75a2015-08-21 00:02:47 -0700334}
335
Erik Språng521875a2015-09-01 10:11:16 +0200336TEST_F(RtcpSenderTest, SendEmptyApp) {
337 const uint8_t kSubType = 30;
338 const uint32_t kName = 0x6E616D65;
339
340 EXPECT_EQ(
341 0, rtcp_sender_->SetApplicationSpecificData(kSubType, kName, nullptr, 0));
342
pbosda903ea2015-10-02 02:36:56 -0700343 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Erik Språng521875a2015-09-01 10:11:16 +0200344 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
345 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200346 EXPECT_EQ(kSubType, parser()->app()->sub_type());
347 EXPECT_EQ(kName, parser()->app()->name());
348 EXPECT_EQ(0U, parser()->app()->data_size());
Erik Språng521875a2015-09-01 10:11:16 +0200349}
350
asapersson22ff75a2015-08-21 00:02:47 -0700351TEST_F(RtcpSenderTest, SetInvalidApplicationSpecificData) {
352 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't'};
353 const uint16_t kInvalidDataLength = sizeof(kData) / sizeof(kData[0]);
Yves Gerey665174f2018-06-19 15:03:05 +0200354 EXPECT_EQ(-1,
355 rtcp_sender_->SetApplicationSpecificData(
356 0, 0, kData, kInvalidDataLength)); // Should by multiple of 4.
asapersson22ff75a2015-08-21 00:02:47 -0700357}
358
danilchap498ee8e2017-02-08 05:24:31 -0800359TEST_F(RtcpSenderTest, SendFir) {
pbosda903ea2015-10-02 02:36:56 -0700360 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700361 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
362 EXPECT_EQ(1, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200363 EXPECT_EQ(kSenderSsrc, parser()->fir()->sender_ssrc());
364 EXPECT_EQ(1U, parser()->fir()->requests().size());
365 EXPECT_EQ(kRemoteSsrc, parser()->fir()->requests()[0].ssrc);
366 uint8_t seq = parser()->fir()->requests()[0].seq_nr;
asapersson22ff75a2015-08-21 00:02:47 -0700367 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
368 EXPECT_EQ(2, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200369 EXPECT_EQ(seq + 1, parser()->fir()->requests()[0].seq_nr);
asapersson22ff75a2015-08-21 00:02:47 -0700370}
371
asapersson22ff75a2015-08-21 00:02:47 -0700372TEST_F(RtcpSenderTest, SendPli) {
pbosda903ea2015-10-02 02:36:56 -0700373 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700374 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
375 EXPECT_EQ(1, parser()->pli()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200376 EXPECT_EQ(kSenderSsrc, parser()->pli()->sender_ssrc());
377 EXPECT_EQ(kRemoteSsrc, parser()->pli()->media_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700378}
379
asapersson22ff75a2015-08-21 00:02:47 -0700380TEST_F(RtcpSenderTest, SendNack) {
pbosda903ea2015-10-02 02:36:56 -0700381 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700382 const uint16_t kList[] = {0, 1, 16};
Elad Alone86af2c2019-06-03 14:37:50 +0200383 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpNack,
384 ABSL_ARRAYSIZE(kList), kList));
asapersson22ff75a2015-08-21 00:02:47 -0700385 EXPECT_EQ(1, parser()->nack()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200386 EXPECT_EQ(kSenderSsrc, parser()->nack()->sender_ssrc());
387 EXPECT_EQ(kRemoteSsrc, parser()->nack()->media_ssrc());
388 EXPECT_THAT(parser()->nack()->packet_ids(), ElementsAre(0, 1, 16));
asapersson22ff75a2015-08-21 00:02:47 -0700389}
390
Elad Alone86af2c2019-06-03 14:37:50 +0200391TEST_F(RtcpSenderTest, SendLossNotificationBufferingNotAllowed) {
Elad Alon7d6a4c02019-02-25 13:00:51 +0100392 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
393 constexpr uint16_t kLastDecoded = 0x1234;
394 constexpr uint16_t kLastReceived = 0x4321;
395 constexpr bool kDecodabilityFlag = true;
Elad Alone86af2c2019-06-03 14:37:50 +0200396 constexpr bool kBufferingAllowed = false;
397 EXPECT_EQ(rtcp_sender_->SendLossNotification(feedback_state(), kLastDecoded,
398 kLastReceived, kDecodabilityFlag,
399 kBufferingAllowed),
400 0);
401 EXPECT_EQ(parser()->processed_rtcp_packets(), 1u);
402 EXPECT_EQ(parser()->loss_notification()->num_packets(), 1);
Elad Alon7d6a4c02019-02-25 13:00:51 +0100403 EXPECT_EQ(kSenderSsrc, parser()->loss_notification()->sender_ssrc());
404 EXPECT_EQ(kRemoteSsrc, parser()->loss_notification()->media_ssrc());
405}
406
Elad Alone86af2c2019-06-03 14:37:50 +0200407TEST_F(RtcpSenderTest, SendLossNotificationBufferingAllowed) {
408 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
409 constexpr uint16_t kLastDecoded = 0x1234;
410 constexpr uint16_t kLastReceived = 0x4321;
411 constexpr bool kDecodabilityFlag = true;
412 constexpr bool kBufferingAllowed = true;
413 EXPECT_EQ(rtcp_sender_->SendLossNotification(feedback_state(), kLastDecoded,
414 kLastReceived, kDecodabilityFlag,
415 kBufferingAllowed),
416 0);
417
418 // No RTCP messages sent yet.
419 ASSERT_EQ(parser()->processed_rtcp_packets(), 0u);
420
421 // Sending another messages triggers sending the LNTF messages as well.
422 const uint16_t kList[] = {0, 1, 16};
423 EXPECT_EQ(rtcp_sender_->SendRTCP(feedback_state(), kRtcpNack,
424 ABSL_ARRAYSIZE(kList), kList),
425 0);
426
427 // Exactly one packet was produced, and it contained both the buffered LNTF
428 // as well as the message that had triggered the packet.
429 EXPECT_EQ(parser()->processed_rtcp_packets(), 1u);
430 EXPECT_EQ(parser()->loss_notification()->num_packets(), 1);
431 EXPECT_EQ(parser()->loss_notification()->sender_ssrc(), kSenderSsrc);
432 EXPECT_EQ(parser()->loss_notification()->media_ssrc(), kRemoteSsrc);
433 EXPECT_EQ(parser()->nack()->num_packets(), 1);
434 EXPECT_EQ(parser()->nack()->sender_ssrc(), kSenderSsrc);
435 EXPECT_EQ(parser()->nack()->media_ssrc(), kRemoteSsrc);
436}
437
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200438TEST_F(RtcpSenderTest, RembNotIncludedBeforeSet) {
439 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
440
441 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
442
443 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
444 EXPECT_EQ(0, parser()->remb()->num_packets());
445}
446
447TEST_F(RtcpSenderTest, RembNotIncludedAfterUnset) {
danilchapba6aa902017-04-18 06:57:02 -0700448 const uint64_t kBitrate = 261011;
449 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
450 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200451 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
danilchapba6aa902017-04-18 06:57:02 -0700452 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
453 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200454 EXPECT_EQ(1, parser()->remb()->num_packets());
danilchapba6aa902017-04-18 06:57:02 -0700455
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200456 // Turn off REMB. rtcp_sender no longer should send it.
457 rtcp_sender_->UnsetRemb();
danilchapba6aa902017-04-18 06:57:02 -0700458 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
459 ASSERT_EQ(2, parser()->receiver_report()->num_packets());
460 EXPECT_EQ(1, parser()->remb()->num_packets());
Danil Chapovalov857a8fb2016-09-06 11:41:46 +0200461}
462
asapersson22ff75a2015-08-21 00:02:47 -0700463TEST_F(RtcpSenderTest, SendRemb) {
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200464 const uint64_t kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200465 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700466 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200467 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
468
469 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRemb);
470
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200471 EXPECT_EQ(1, parser()->remb()->num_packets());
472 EXPECT_EQ(kSenderSsrc, parser()->remb()->sender_ssrc());
473 EXPECT_EQ(kBitrate, parser()->remb()->bitrate_bps());
474 EXPECT_THAT(parser()->remb()->ssrcs(),
asapersson22ff75a2015-08-21 00:02:47 -0700475 ElementsAre(kRemoteSsrc, kRemoteSsrc + 1));
476}
477
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200478TEST_F(RtcpSenderTest, RembIncludedInEachCompoundPacketAfterSet) {
asapersson22ff75a2015-08-21 00:02:47 -0700479 const int kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200480 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700481 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200482 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
483
484 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200485 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700486 // REMB should be included in each compound packet.
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200487 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200488 EXPECT_EQ(2, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700489}
490
asapersson22ff75a2015-08-21 00:02:47 -0700491TEST_F(RtcpSenderTest, SendXrWithDlrr) {
pbosda903ea2015-10-02 02:36:56 -0700492 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000493 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
danilchap798896a2016-09-28 02:54:25 -0700494 rtcp::ReceiveTimeInfo last_xr_rr;
495 last_xr_rr.ssrc = 0x11111111;
496 last_xr_rr.last_rr = 0x22222222;
497 last_xr_rr.delay_since_last_rr = 0x33333333;
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200498 feedback_state.last_xr_rtis.push_back(last_xr_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000499 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200500 EXPECT_EQ(1, parser()->xr()->num_packets());
501 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200502 ASSERT_THAT(parser()->xr()->dlrr().sub_blocks(), SizeIs(1));
danilchap80ac24d2016-10-31 08:40:47 -0700503 EXPECT_EQ(last_xr_rr.ssrc, parser()->xr()->dlrr().sub_blocks()[0].ssrc);
504 EXPECT_EQ(last_xr_rr.last_rr, parser()->xr()->dlrr().sub_blocks()[0].last_rr);
danilchap798896a2016-09-28 02:54:25 -0700505 EXPECT_EQ(last_xr_rr.delay_since_last_rr,
danilchap80ac24d2016-10-31 08:40:47 -0700506 parser()->xr()->dlrr().sub_blocks()[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000507}
508
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200509TEST_F(RtcpSenderTest, SendXrWithMultipleDlrrSubBlocks) {
510 const size_t kNumReceivers = 2;
511 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
512 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
513 for (size_t i = 0; i < kNumReceivers; ++i) {
514 rtcp::ReceiveTimeInfo last_xr_rr;
515 last_xr_rr.ssrc = i;
516 last_xr_rr.last_rr = (i + 1) * 100;
517 last_xr_rr.delay_since_last_rr = (i + 2) * 200;
518 feedback_state.last_xr_rtis.push_back(last_xr_rr);
519 }
520
521 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
522 EXPECT_EQ(1, parser()->xr()->num_packets());
523 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
524 ASSERT_THAT(parser()->xr()->dlrr().sub_blocks(), SizeIs(kNumReceivers));
525 for (size_t i = 0; i < kNumReceivers; ++i) {
526 EXPECT_EQ(feedback_state.last_xr_rtis[i].ssrc,
527 parser()->xr()->dlrr().sub_blocks()[i].ssrc);
528 EXPECT_EQ(feedback_state.last_xr_rtis[i].last_rr,
529 parser()->xr()->dlrr().sub_blocks()[i].last_rr);
530 EXPECT_EQ(feedback_state.last_xr_rtis[i].delay_since_last_rr,
531 parser()->xr()->dlrr().sub_blocks()[i].delay_since_last_rr);
532 }
533}
534
asapersson22ff75a2015-08-21 00:02:47 -0700535TEST_F(RtcpSenderTest, SendXrWithRrtr) {
pbosda903ea2015-10-02 02:36:56 -0700536 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700537 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000538 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200539 NtpTime ntp = TimeMicrosToNtp(clock_.TimeInMicroseconds());
asapersson22ff75a2015-08-21 00:02:47 -0700540 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200541 EXPECT_EQ(1, parser()->xr()->num_packets());
542 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
danilchap80ac24d2016-10-31 08:40:47 -0700543 EXPECT_FALSE(parser()->xr()->dlrr());
danilchap80ac24d2016-10-31 08:40:47 -0700544 ASSERT_TRUE(parser()->xr()->rrtr());
danilchap21dc1892017-03-07 02:51:09 -0800545 EXPECT_EQ(ntp, parser()->xr()->rrtr()->ntp());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000546}
547
asapersson22ff75a2015-08-21 00:02:47 -0700548TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfSending) {
pbosda903ea2015-10-02 02:36:56 -0700549 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700550 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
551 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
552 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200553 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700554}
555
556TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfNotEnabled) {
pbosda903ea2015-10-02 02:36:56 -0700557 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700558 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000559 rtcp_sender_->SendRtcpXrReceiverReferenceTime(false);
asapersson22ff75a2015-08-21 00:02:47 -0700560 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200561 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000562}
563
asapersson22ff75a2015-08-21 00:02:47 -0700564TEST_F(RtcpSenderTest, TestRegisterRtcpPacketTypeObserver) {
565 RtcpPacketTypeCounterObserverImpl observer;
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +0000566 RtpRtcp::Configuration config;
567 config.clock = &clock_;
568 config.receive_statistics = receive_statistics_.get();
569 config.outgoing_transport = &test_transport_;
570 config.rtcp_packet_type_counter_observer = &observer;
571 config.rtcp_report_interval_ms = 1000;
572 rtcp_sender_.reset(new RTCPSender(config));
573
asapersson22ff75a2015-08-21 00:02:47 -0700574 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700575 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700576 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
577 EXPECT_EQ(1, parser()->pli()->num_packets());
578 EXPECT_EQ(kRemoteSsrc, observer.ssrc_);
579 EXPECT_EQ(1U, observer.counter_.pli_packets);
580 EXPECT_EQ(clock_.TimeInMilliseconds(),
581 observer.counter_.first_packet_time_ms);
582}
583
584TEST_F(RtcpSenderTest, SendTmmbr) {
585 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700586 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700587 rtcp_sender_->SetTargetBitrate(kBitrateBps);
588 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpTmmbr));
589 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200590 EXPECT_EQ(kSenderSsrc, parser()->tmmbr()->sender_ssrc());
591 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
592 EXPECT_EQ(kBitrateBps, parser()->tmmbr()->requests()[0].bitrate_bps());
asapersson22ff75a2015-08-21 00:02:47 -0700593 // TODO(asapersson): tmmbr_item()->Overhead() looks broken, always zero.
594}
595
596TEST_F(RtcpSenderTest, TmmbrIncludedInCompoundPacketIfEnabled) {
597 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700598 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700599 EXPECT_FALSE(rtcp_sender_->TMMBR());
600 rtcp_sender_->SetTMMBRStatus(true);
601 EXPECT_TRUE(rtcp_sender_->TMMBR());
602 rtcp_sender_->SetTargetBitrate(kBitrateBps);
603 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
604 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200605 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
asapersson22ff75a2015-08-21 00:02:47 -0700606 // TMMBR should be included in each compound packet.
607 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
608 EXPECT_EQ(2, parser()->tmmbr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700609
610 rtcp_sender_->SetTMMBRStatus(false);
611 EXPECT_FALSE(rtcp_sender_->TMMBR());
612}
613
614TEST_F(RtcpSenderTest, SendTmmbn) {
pbosda903ea2015-10-02 02:36:56 -0700615 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200616 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700617 std::vector<rtcp::TmmbItem> bounding_set;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200618 const uint32_t kBitrateBps = 32768000;
asapersson22ff75a2015-08-21 00:02:47 -0700619 const uint32_t kPacketOh = 40;
620 const uint32_t kSourceSsrc = 12345;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200621 const rtcp::TmmbItem tmmbn(kSourceSsrc, kBitrateBps, kPacketOh);
danilchap6eaa3a42016-05-09 10:59:50 -0700622 bounding_set.push_back(tmmbn);
danilchap853ecb22016-08-22 08:26:15 -0700623 rtcp_sender_->SetTmmbn(bounding_set);
danilchap6eaa3a42016-05-09 10:59:50 -0700624
asapersson22ff75a2015-08-21 00:02:47 -0700625 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
626 EXPECT_EQ(1, parser()->sender_report()->num_packets());
627 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200628 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
629 EXPECT_EQ(1U, parser()->tmmbn()->items().size());
630 EXPECT_EQ(kBitrateBps, parser()->tmmbn()->items()[0].bitrate_bps());
631 EXPECT_EQ(kPacketOh, parser()->tmmbn()->items()[0].packet_overhead());
632 EXPECT_EQ(kSourceSsrc, parser()->tmmbn()->items()[0].ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700633}
634
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000635// This test is written to verify actual behaviour. It does not seem
636// to make much sense to send an empty TMMBN, since there is no place
637// to put an actual limit here. It's just information that no limit
638// is set, which is kind of the starting assumption.
639// See http://code.google.com/p/webrtc/issues/detail?id=468 for one
640// situation where this caused confusion.
641TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndEmpty) {
pbosda903ea2015-10-02 02:36:56 -0700642 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200643 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700644 std::vector<rtcp::TmmbItem> bounding_set;
danilchap853ecb22016-08-22 08:26:15 -0700645 rtcp_sender_->SetTmmbn(bounding_set);
asapersson22ff75a2015-08-21 00:02:47 -0700646 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
647 EXPECT_EQ(1, parser()->sender_report()->num_packets());
648 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200649 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
650 EXPECT_EQ(0U, parser()->tmmbn()->items().size());
hta@webrtc.org65a4e4e2012-04-30 11:23:41 +0000651}
652
asapersson22ff75a2015-08-21 00:02:47 -0700653TEST_F(RtcpSenderTest, SendCompoundPliRemb) {
654 const int kBitrate = 261011;
655 std::vector<uint32_t> ssrcs;
656 ssrcs.push_back(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700657 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200658 rtcp_sender_->SetRemb(kBitrate, ssrcs);
asapersson22ff75a2015-08-21 00:02:47 -0700659 std::set<RTCPPacketType> packet_types;
660 packet_types.insert(kRtcpRemb);
661 packet_types.insert(kRtcpPli);
662 EXPECT_EQ(0, rtcp_sender_->SendCompoundRTCP(feedback_state(), packet_types));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200663 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700664 EXPECT_EQ(1, parser()->pli()->num_packets());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000665}
Erik Språnga38233a2015-07-24 09:58:18 +0200666
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800667// This test is written to verify that BYE is always the last packet
668// type in a RTCP compoud packet. The rtcp_sender_ is recreated with
669// mock_transport, which is used to check for whether BYE at the end
670// of a RTCP compound packet.
671TEST_F(RtcpSenderTest, ByeMustBeLast) {
672 MockTransport mock_transport;
673 EXPECT_CALL(mock_transport, SendRtcp(_, _))
Yves Gerey665174f2018-06-19 15:03:05 +0200674 .WillOnce(Invoke([](const uint8_t* data, size_t len) {
675 const uint8_t* next_packet = data;
676 const uint8_t* const packet_end = data + len;
677 rtcp::CommonHeader packet;
678 while (next_packet < packet_end) {
679 EXPECT_TRUE(packet.Parse(next_packet, packet_end - next_packet));
680 next_packet = packet.NextPacket();
681 if (packet.type() ==
682 rtcp::Bye::kPacketType) // Main test expectation.
683 EXPECT_EQ(0, packet_end - next_packet)
684 << "Bye packet should be last in a compound RTCP packet.";
685 if (next_packet == packet_end) // Validate test was set correctly.
686 EXPECT_EQ(packet.type(), rtcp::Bye::kPacketType)
687 << "Last packet in this test expected to be Bye.";
688 }
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800689
Yves Gerey665174f2018-06-19 15:03:05 +0200690 return true;
691 }));
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800692
693 // Re-configure rtcp_sender_ with mock_transport_
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +0000694 RtpRtcp::Configuration config;
695 config.clock = &clock_;
696 config.receive_statistics = receive_statistics_.get();
697 config.outgoing_transport = &mock_transport;
698 config.rtcp_report_interval_ms = 1000;
Erik Språng54d5d2c2019-08-20 17:22:36 +0200699 config.local_media_ssrc = kSenderSsrc;
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +0000700 rtcp_sender_.reset(new RTCPSender(config));
701
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800702 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
danilchap71fead22016-08-18 02:01:49 -0700703 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
Ilya Nikolaevskiy5e58bcb2018-10-24 13:34:32 +0200704 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds(),
Mirko Bonadei970f2f72019-02-28 14:57:52 +0100705 /*payload_type=*/0);
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800706
Niels Möller44b384d2018-10-05 11:15:57 +0200707 // Set up REMB info to be included with BYE.
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800708 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Niels Möller44b384d2018-10-05 11:15:57 +0200709 rtcp_sender_->SetRemb(1234, {});
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800710 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
711}
712
sprang5e38c962016-12-01 05:18:09 -0800713TEST_F(RtcpSenderTest, SendXrWithTargetBitrate) {
714 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
715 const size_t kNumSpatialLayers = 2;
716 const size_t kNumTemporalLayers = 2;
Erik Språng566124a2018-04-23 12:32:22 +0200717 VideoBitrateAllocation allocation;
sprang5e38c962016-12-01 05:18:09 -0800718 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
719 uint32_t start_bitrate_bps = (sl + 1) * 100000;
720 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl)
721 allocation.SetBitrate(sl, tl, start_bitrate_bps + (tl * 20000));
722 }
723 rtcp_sender_->SetVideoBitrateAllocation(allocation);
724
725 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
726 EXPECT_EQ(1, parser()->xr()->num_packets());
727 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
Danil Chapovalovd264df52018-06-14 12:59:38 +0200728 const absl::optional<rtcp::TargetBitrate>& target_bitrate =
sprang5e38c962016-12-01 05:18:09 -0800729 parser()->xr()->target_bitrate();
730 ASSERT_TRUE(target_bitrate);
731 const std::vector<rtcp::TargetBitrate::BitrateItem>& bitrates =
732 target_bitrate->GetTargetBitrates();
733 EXPECT_EQ(kNumSpatialLayers * kNumTemporalLayers, bitrates.size());
734
735 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
736 uint32_t start_bitrate_bps = (sl + 1) * 100000;
737 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl) {
738 size_t index = (sl * kNumSpatialLayers) + tl;
739 const rtcp::TargetBitrate::BitrateItem& item = bitrates[index];
740 EXPECT_EQ(sl, item.spatial_layer);
741 EXPECT_EQ(tl, item.temporal_layer);
742 EXPECT_EQ(start_bitrate_bps + (tl * 20000),
743 item.target_bitrate_kbps * 1000);
744 }
745 }
746}
747
Erik Språng8782a582018-10-04 15:36:06 +0200748TEST_F(RtcpSenderTest, SendImmediateXrWithTargetBitrate) {
749 // Initialize. Send a first report right away.
750 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
751 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
752 clock_.AdvanceTimeMilliseconds(5);
753
754 // Video bitrate allocation generated, save until next time we send a report.
755 VideoBitrateAllocation allocation;
756 allocation.SetBitrate(0, 0, 100000);
757 rtcp_sender_->SetVideoBitrateAllocation(allocation);
758 // First seen instance will be sent immediately.
759 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
760 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
761 clock_.AdvanceTimeMilliseconds(5);
762
763 // Update bitrate of existing layer, does not quality for immediate sending.
764 allocation.SetBitrate(0, 0, 150000);
765 rtcp_sender_->SetVideoBitrateAllocation(allocation);
766 EXPECT_FALSE(rtcp_sender_->TimeToSendRTCPReport(false));
767
768 // A new spatial layer enabled, signal this as soon as possible.
769 allocation.SetBitrate(1, 0, 200000);
770 rtcp_sender_->SetVideoBitrateAllocation(allocation);
771 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
772 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
773 clock_.AdvanceTimeMilliseconds(5);
774
775 // Explicitly disable top layer. The same set of layers now has a bitrate
776 // defined, but the explicit 0 indicates shutdown. Signal immediately.
777 allocation.SetBitrate(1, 0, 0);
778 EXPECT_FALSE(rtcp_sender_->TimeToSendRTCPReport(false));
779 rtcp_sender_->SetVideoBitrateAllocation(allocation);
780 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
781}
782
Erik Språng1cd73912018-10-05 12:57:59 +0200783TEST_F(RtcpSenderTest, SendTargetBitrateExplicitZeroOnStreamRemoval) {
784 // Set up and send a bitrate allocation with two layers.
785
786 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
787 VideoBitrateAllocation allocation;
788 allocation.SetBitrate(0, 0, 100000);
789 allocation.SetBitrate(1, 0, 200000);
790 rtcp_sender_->SetVideoBitrateAllocation(allocation);
791 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
792 absl::optional<rtcp::TargetBitrate> target_bitrate =
793 parser()->xr()->target_bitrate();
794 ASSERT_TRUE(target_bitrate);
795 std::vector<rtcp::TargetBitrate::BitrateItem> bitrates =
796 target_bitrate->GetTargetBitrates();
797 ASSERT_EQ(2u, bitrates.size());
798 EXPECT_EQ(bitrates[0].target_bitrate_kbps,
799 allocation.GetBitrate(0, 0) / 1000);
800 EXPECT_EQ(bitrates[1].target_bitrate_kbps,
801 allocation.GetBitrate(1, 0) / 1000);
802
803 // Create a new allocation, where the second stream is no longer available.
804 VideoBitrateAllocation new_allocation;
805 new_allocation.SetBitrate(0, 0, 150000);
806 rtcp_sender_->SetVideoBitrateAllocation(new_allocation);
807 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
808 target_bitrate = parser()->xr()->target_bitrate();
809 ASSERT_TRUE(target_bitrate);
810 bitrates = target_bitrate->GetTargetBitrates();
811
812 // Two bitrates should still be set, with an explicit entry indicating the
813 // removed stream is gone.
814 ASSERT_EQ(2u, bitrates.size());
815 EXPECT_EQ(bitrates[0].target_bitrate_kbps,
816 new_allocation.GetBitrate(0, 0) / 1000);
817 EXPECT_EQ(bitrates[1].target_bitrate_kbps, 0u);
818}
819
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +0000820TEST_F(RtcpSenderTest, DoesntSchedulesInitialReportWhenSsrcSetOnConstruction) {
821 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
822 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
823 // New report should not have been scheduled yet.
824 clock_.AdvanceTimeMilliseconds(100);
825 EXPECT_FALSE(rtcp_sender_->TimeToSendRTCPReport(false));
826}
827
828TEST_F(RtcpSenderTest, DoesntSchedulesInitialReportOnFirstSetSsrc) {
829 // Set up without first SSRC not set at construction.
830 RtpRtcp::Configuration configuration = GetDefaultConfig();
Erik Språng54d5d2c2019-08-20 17:22:36 +0200831 configuration.local_media_ssrc = absl::nullopt;
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +0000832
833 rtcp_sender_.reset(new RTCPSender(configuration));
834 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
835 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
836 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds(),
837 /*payload_type=*/0);
838 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
839
840 // Set SSRC for the first time. New report should not be scheduled.
841 rtcp_sender_->SetSSRC(kSenderSsrc);
842 clock_.AdvanceTimeMilliseconds(100);
843 EXPECT_FALSE(rtcp_sender_->TimeToSendRTCPReport(false));
844}
845
846TEST_F(RtcpSenderTest, SchedulesReportOnSsrcChange) {
847 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
848 rtcp_sender_->SetSSRC(kSenderSsrc + 1);
849 clock_.AdvanceTimeMilliseconds(100);
850 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
851}
852
Per Kjellander16999812019-10-10 12:57:28 +0200853TEST_F(RtcpSenderTest, SendsCombinedRtcpPacket) {
854 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
855
856 std::vector<std::unique_ptr<rtcp::RtcpPacket>> packets;
857 auto transport_feedback = std::make_unique<rtcp::TransportFeedback>();
858 transport_feedback->AddReceivedPacket(321, 10000);
859 packets.push_back(std::move(transport_feedback));
860 auto remote_estimate = std::make_unique<rtcp::RemoteEstimate>();
861 packets.push_back(std::move(remote_estimate));
862 rtcp_sender_->SendCombinedRtcpPacket(std::move(packets));
863
864 EXPECT_EQ(parser()->transport_feedback()->num_packets(), 1);
865 EXPECT_EQ(parser()->transport_feedback()->sender_ssrc(), kSenderSsrc);
866 EXPECT_EQ(parser()->app()->num_packets(), 1);
867 EXPECT_EQ(parser()->app()->sender_ssrc(), kSenderSsrc);
868}
869
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000870} // namespace webrtc