blob: 0ddfb943eda0083528308682b1a364251a7eee58 [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
Elad Alone86af2c2019-06-03 14:37:50 +020013#include "absl/base/macros.h"
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +020014#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
16#include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
17#include "modules/rtp_rtcp/source/rtcp_sender.h"
Niels Möller1f3206c2018-09-14 08:26:32 +020018#include "modules/rtp_rtcp/source/rtp_packet_received.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "modules/rtp_rtcp/source/rtp_rtcp_impl.h"
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +020020#include "modules/rtp_rtcp/source/time_util.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "rtc_base/rate_limiter.h"
22#include "test/gmock.h"
23#include "test/gtest.h"
24#include "test/mock_transport.h"
25#include "test/rtcp_packet_parser.h"
asapersson22ff75a2015-08-21 00:02:47 -070026
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -080027using ::testing::_;
asapersson22ff75a2015-08-21 00:02:47 -070028using ::testing::ElementsAre;
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -080029using ::testing::Invoke;
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +020030using ::testing::SizeIs;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000031
32namespace webrtc {
33
asapersson22ff75a2015-08-21 00:02:47 -070034class RtcpPacketTypeCounterObserverImpl : public RtcpPacketTypeCounterObserver {
35 public:
36 RtcpPacketTypeCounterObserverImpl() : ssrc_(0) {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +000037 ~RtcpPacketTypeCounterObserverImpl() override = default;
asapersson22ff75a2015-08-21 00:02:47 -070038 void RtcpPacketTypesCounterUpdated(
39 uint32_t ssrc,
40 const RtcpPacketTypeCounter& packet_counter) override {
41 ssrc_ = ssrc;
42 counter_ = packet_counter;
43 }
44 uint32_t ssrc_;
45 RtcpPacketTypeCounter counter_;
46};
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000047
Niels Möller8fb57462018-11-13 10:08:33 +010048class TestTransport : public Transport {
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000049 public:
asapersson22ff75a2015-08-21 00:02:47 -070050 TestTransport() {}
51
stefan1d8a5062015-10-02 03:39:33 -070052 bool SendRtp(const uint8_t* /*data*/,
53 size_t /*len*/,
54 const PacketOptions& options) override {
pbos2d566682015-09-28 09:59:31 -070055 return false;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000056 }
pbos2d566682015-09-28 09:59:31 -070057 bool SendRtcp(const uint8_t* data, size_t len) override {
Danil Chapovalovba6f7be2016-09-02 18:29:10 +020058 parser_.Parse(data, len);
pbos2d566682015-09-28 09:59:31 -070059 return true;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000060 }
asapersson22ff75a2015-08-21 00:02:47 -070061 test::RtcpPacketParser parser_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000062};
63
Erik Språnga38233a2015-07-24 09:58:18 +020064namespace {
asapersson22ff75a2015-08-21 00:02:47 -070065static const uint32_t kSenderSsrc = 0x11111111;
66static const uint32_t kRemoteSsrc = 0x22222222;
Danil Chapovalov70ffead2016-07-20 15:26:59 +020067static const uint32_t kStartRtpTimestamp = 0x34567;
68static const uint32_t kRtpTimestamp = 0x45678;
Yves Gerey665174f2018-06-19 15:03:05 +020069} // namespace
Erik Språnga38233a2015-07-24 09:58:18 +020070
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000071class RtcpSenderTest : public ::testing::Test {
72 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +000073 RtcpSenderTest()
asapersson22ff75a2015-08-21 00:02:47 -070074 : clock_(1335900000),
Erik Språng737336d2016-07-29 12:59:36 +020075 receive_statistics_(ReceiveStatistics::Create(&clock_)),
76 retransmission_rate_limiter_(&clock_, 1000) {
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000077 RtpRtcp::Configuration configuration;
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000078 configuration.audio = false;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +000079 configuration.clock = &clock_;
asapersson22ff75a2015-08-21 00:02:47 -070080 configuration.outgoing_transport = &test_transport_;
Erik Språng737336d2016-07-29 12:59:36 +020081 configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080082 configuration.rtcp_report_interval_ms = 1000;
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000083
asapersson22ff75a2015-08-21 00:02:47 -070084 rtp_rtcp_impl_.reset(new ModuleRtpRtcpImpl(configuration));
sprang86fd9ed2015-09-29 04:45:43 -070085 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -080086 nullptr, nullptr, &test_transport_,
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080087 configuration.rtcp_report_interval_ms));
asapersson22ff75a2015-08-21 00:02:47 -070088 rtcp_sender_->SetSSRC(kSenderSsrc);
89 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
danilchap71fead22016-08-18 02:01:49 -070090 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
Ilya Nikolaevskiy5e58bcb2018-10-24 13:34:32 +020091 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds(),
Mirko Bonadei970f2f72019-02-28 14:57:52 +010092 /*payload_type=*/0);
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) {
Niels Möller1f3206c2018-09-14 08:26:32 +020096 RtpPacketReceived packet;
97 packet.SetSsrc(remote_ssrc);
98 packet.SetSequenceNumber(seq_num);
99 packet.SetTimestamp(12345);
100 packet.SetPayloadSize(100 - 12);
101 receive_statistics_->OnRtpPacket(packet);
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000102 }
103
asapersson22ff75a2015-08-21 00:02:47 -0700104 test::RtcpPacketParser* parser() { return &test_transport_.parser_; }
105
106 RTCPSender::FeedbackState feedback_state() {
107 return rtp_rtcp_impl_->GetFeedbackState();
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000108 }
109
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000110 SimulatedClock clock_;
asapersson22ff75a2015-08-21 00:02:47 -0700111 TestTransport test_transport_;
kwiberg84be5112016-04-27 01:19:58 -0700112 std::unique_ptr<ReceiveStatistics> receive_statistics_;
113 std::unique_ptr<ModuleRtpRtcpImpl> rtp_rtcp_impl_;
114 std::unique_ptr<RTCPSender> rtcp_sender_;
Erik Språng737336d2016-07-29 12:59:36 +0200115 RateLimiter retransmission_rate_limiter_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000116};
117
asapersson22ff75a2015-08-21 00:02:47 -0700118TEST_F(RtcpSenderTest, SetRtcpStatus) {
pbosda903ea2015-10-02 02:36:56 -0700119 EXPECT_EQ(RtcpMode::kOff, rtcp_sender_->Status());
120 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
121 EXPECT_EQ(RtcpMode::kReducedSize, rtcp_sender_->Status());
asapersson22ff75a2015-08-21 00:02:47 -0700122}
123
124TEST_F(RtcpSenderTest, SetSendingStatus) {
125 EXPECT_FALSE(rtcp_sender_->Sending());
126 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
127 EXPECT_TRUE(rtcp_sender_->Sending());
128}
129
130TEST_F(RtcpSenderTest, NoPacketSentIfOff) {
pbosda903ea2015-10-02 02:36:56 -0700131 rtcp_sender_->SetRTCPStatus(RtcpMode::kOff);
asapersson22ff75a2015-08-21 00:02:47 -0700132 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000133}
134
asapersson22ff75a2015-08-21 00:02:47 -0700135TEST_F(RtcpSenderTest, SendSr) {
136 const uint32_t kPacketCount = 0x12345;
137 const uint32_t kOctetCount = 0x23456;
pbosda903ea2015-10-02 02:36:56 -0700138 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000139 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200140 rtcp_sender_->SetSendingStatus(feedback_state, true);
asapersson22ff75a2015-08-21 00:02:47 -0700141 feedback_state.packets_sent = kPacketCount;
142 feedback_state.media_bytes_sent = kOctetCount;
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200143 NtpTime ntp = TimeMicrosToNtp(clock_.TimeInMicroseconds());
asapersson22ff75a2015-08-21 00:02:47 -0700144 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
145 EXPECT_EQ(1, parser()->sender_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200146 EXPECT_EQ(kSenderSsrc, parser()->sender_report()->sender_ssrc());
danilchap21dc1892017-03-07 02:51:09 -0800147 EXPECT_EQ(ntp, parser()->sender_report()->ntp());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200148 EXPECT_EQ(kPacketCount, parser()->sender_report()->sender_packet_count());
149 EXPECT_EQ(kOctetCount, parser()->sender_report()->sender_octet_count());
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200150 EXPECT_EQ(kStartRtpTimestamp + kRtpTimestamp,
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200151 parser()->sender_report()->rtp_timestamp());
152 EXPECT_EQ(0U, parser()->sender_report()->report_blocks().size());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000153}
154
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200155TEST_F(RtcpSenderTest, SendConsecutiveSrWithExactSlope) {
156 const uint32_t kPacketCount = 0x12345;
157 const uint32_t kOctetCount = 0x23456;
158 const int kTimeBetweenSRsUs = 10043; // Not exact value in milliseconds.
159 const int kExtraPackets = 30;
160 // Make sure clock is not exactly at some milliseconds point.
161 clock_.AdvanceTimeMicroseconds(kTimeBetweenSRsUs);
162 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
163 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
164 rtcp_sender_->SetSendingStatus(feedback_state, true);
165 feedback_state.packets_sent = kPacketCount;
166 feedback_state.media_bytes_sent = kOctetCount;
167
168 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
169 EXPECT_EQ(1, parser()->sender_report()->num_packets());
170 NtpTime ntp1 = parser()->sender_report()->ntp();
171 uint32_t rtp1 = parser()->sender_report()->rtp_timestamp();
172
173 // Send more SRs to ensure slope is always exact for different offsets
174 for (int packets = 1; packets <= kExtraPackets; ++packets) {
175 clock_.AdvanceTimeMicroseconds(kTimeBetweenSRsUs);
176 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
177 EXPECT_EQ(packets + 1, parser()->sender_report()->num_packets());
178
179 NtpTime ntp2 = parser()->sender_report()->ntp();
180 uint32_t rtp2 = parser()->sender_report()->rtp_timestamp();
181
182 uint32_t ntp_diff_in_rtp_units =
183 (ntp2.ToMs() - ntp1.ToMs()) * (kVideoPayloadTypeFrequency / 1000);
184 EXPECT_EQ(rtp2 - rtp1, ntp_diff_in_rtp_units);
185 }
186}
187
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200188TEST_F(RtcpSenderTest, DoNotSendSrBeforeRtp) {
189 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800190 nullptr, nullptr, &test_transport_, 1000));
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200191 rtcp_sender_->SetSSRC(kSenderSsrc);
192 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
193 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
194 rtcp_sender_->SetSendingStatus(feedback_state(), true);
195
196 // Sender Report shouldn't be send as an SR nor as a Report.
197 rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr);
198 EXPECT_EQ(0, parser()->sender_report()->num_packets());
199 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
200 EXPECT_EQ(0, parser()->sender_report()->num_packets());
201 // Other packets (e.g. Pli) are allowed, even if useless.
202 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
203 EXPECT_EQ(1, parser()->pli()->num_packets());
204}
205
206TEST_F(RtcpSenderTest, DoNotSendCompundBeforeRtp) {
207 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800208 nullptr, nullptr, &test_transport_, 1000));
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200209 rtcp_sender_->SetSSRC(kSenderSsrc);
210 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
211 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
212 rtcp_sender_->SetSendingStatus(feedback_state(), true);
213
214 // In compound mode no packets are allowed (e.g. Pli) because compound mode
215 // should start with Sender Report.
216 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
217 EXPECT_EQ(0, parser()->pli()->num_packets());
218}
219
asapersson22ff75a2015-08-21 00:02:47 -0700220TEST_F(RtcpSenderTest, SendRr) {
pbosda903ea2015-10-02 02:36:56 -0700221 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700222 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
223 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200224 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
225 EXPECT_EQ(0U, parser()->receiver_report()->report_blocks().size());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000226}
227
asapersson22ff75a2015-08-21 00:02:47 -0700228TEST_F(RtcpSenderTest, SendRrWithOneReportBlock) {
229 const uint16_t kSeqNum = 11111;
230 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
pbosda903ea2015-10-02 02:36:56 -0700231 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700232 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
233 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200234 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
235 ASSERT_EQ(1U, parser()->receiver_report()->report_blocks().size());
236 const rtcp::ReportBlock& rb = parser()->receiver_report()->report_blocks()[0];
237 EXPECT_EQ(kRemoteSsrc, rb.source_ssrc());
238 EXPECT_EQ(0U, rb.fraction_lost());
Harald Alvestrand70206d62017-12-08 08:59:07 +0100239 EXPECT_EQ(0, rb.cumulative_lost_signed());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200240 EXPECT_EQ(kSeqNum, rb.extended_high_seq_num());
asapersson22ff75a2015-08-21 00:02:47 -0700241}
242
243TEST_F(RtcpSenderTest, SendRrWithTwoReportBlocks) {
244 const uint16_t kSeqNum = 11111;
245 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
246 InsertIncomingPacket(kRemoteSsrc + 1, kSeqNum + 1);
pbosda903ea2015-10-02 02:36:56 -0700247 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700248 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
249 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200250 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
251 EXPECT_EQ(2U, parser()->receiver_report()->report_blocks().size());
252 EXPECT_EQ(kRemoteSsrc,
253 parser()->receiver_report()->report_blocks()[0].source_ssrc());
254 EXPECT_EQ(kRemoteSsrc + 1,
255 parser()->receiver_report()->report_blocks()[1].source_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700256}
257
258TEST_F(RtcpSenderTest, SendSdes) {
pbosda903ea2015-10-02 02:36:56 -0700259 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700260 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
261 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
262 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200263 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
264 EXPECT_EQ(kSenderSsrc, parser()->sdes()->chunks()[0].ssrc);
265 EXPECT_EQ("alice@host", parser()->sdes()->chunks()[0].cname);
asapersson22ff75a2015-08-21 00:02:47 -0700266}
267
danilchap74e8df8f2017-03-16 08:04:08 -0700268TEST_F(RtcpSenderTest, SendSdesWithMaxChunks) {
269 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
270 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
271 const char cname[] = "smith@host";
272 for (size_t i = 0; i < 30; ++i) {
273 const uint32_t csrc = 0x1234 + i;
274 EXPECT_EQ(0, rtcp_sender_->AddMixedCNAME(csrc, cname));
275 }
276 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
277 EXPECT_EQ(1, parser()->sdes()->num_packets());
278 EXPECT_EQ(31U, parser()->sdes()->chunks().size());
279}
280
asapersson22ff75a2015-08-21 00:02:47 -0700281TEST_F(RtcpSenderTest, SdesIncludedInCompoundPacket) {
pbosda903ea2015-10-02 02:36:56 -0700282 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700283 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
284 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
285 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
286 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200287 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
asapersson22ff75a2015-08-21 00:02:47 -0700288}
289
290TEST_F(RtcpSenderTest, SendBye) {
pbosda903ea2015-10-02 02:36:56 -0700291 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700292 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
293 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200294 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700295}
296
297TEST_F(RtcpSenderTest, StopSendingTriggersBye) {
pbosda903ea2015-10-02 02:36:56 -0700298 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700299 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
300 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
301 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200302 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700303}
304
305TEST_F(RtcpSenderTest, SendApp) {
306 const uint8_t kSubType = 30;
307 uint32_t name = 'n' << 24;
308 name += 'a' << 16;
309 name += 'm' << 8;
310 name += 'e';
311 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
asapersson22ff75a2015-08-21 00:02:47 -0700312 EXPECT_EQ(0, rtcp_sender_->SetApplicationSpecificData(kSubType, name, kData,
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200313 sizeof(kData)));
pbosda903ea2015-10-02 02:36:56 -0700314 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700315 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
316 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200317 EXPECT_EQ(kSubType, parser()->app()->sub_type());
318 EXPECT_EQ(name, parser()->app()->name());
319 EXPECT_EQ(sizeof(kData), parser()->app()->data_size());
320 EXPECT_EQ(0, memcmp(kData, parser()->app()->data(), sizeof(kData)));
asapersson22ff75a2015-08-21 00:02:47 -0700321}
322
Erik Språng521875a2015-09-01 10:11:16 +0200323TEST_F(RtcpSenderTest, SendEmptyApp) {
324 const uint8_t kSubType = 30;
325 const uint32_t kName = 0x6E616D65;
326
327 EXPECT_EQ(
328 0, rtcp_sender_->SetApplicationSpecificData(kSubType, kName, nullptr, 0));
329
pbosda903ea2015-10-02 02:36:56 -0700330 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Erik Språng521875a2015-09-01 10:11:16 +0200331 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
332 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200333 EXPECT_EQ(kSubType, parser()->app()->sub_type());
334 EXPECT_EQ(kName, parser()->app()->name());
335 EXPECT_EQ(0U, parser()->app()->data_size());
Erik Språng521875a2015-09-01 10:11:16 +0200336}
337
asapersson22ff75a2015-08-21 00:02:47 -0700338TEST_F(RtcpSenderTest, SetInvalidApplicationSpecificData) {
339 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't'};
340 const uint16_t kInvalidDataLength = sizeof(kData) / sizeof(kData[0]);
Yves Gerey665174f2018-06-19 15:03:05 +0200341 EXPECT_EQ(-1,
342 rtcp_sender_->SetApplicationSpecificData(
343 0, 0, kData, kInvalidDataLength)); // Should by multiple of 4.
asapersson22ff75a2015-08-21 00:02:47 -0700344}
345
danilchap498ee8e2017-02-08 05:24:31 -0800346TEST_F(RtcpSenderTest, SendFir) {
pbosda903ea2015-10-02 02:36:56 -0700347 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700348 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
349 EXPECT_EQ(1, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200350 EXPECT_EQ(kSenderSsrc, parser()->fir()->sender_ssrc());
351 EXPECT_EQ(1U, parser()->fir()->requests().size());
352 EXPECT_EQ(kRemoteSsrc, parser()->fir()->requests()[0].ssrc);
353 uint8_t seq = parser()->fir()->requests()[0].seq_nr;
asapersson22ff75a2015-08-21 00:02:47 -0700354 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
355 EXPECT_EQ(2, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200356 EXPECT_EQ(seq + 1, parser()->fir()->requests()[0].seq_nr);
asapersson22ff75a2015-08-21 00:02:47 -0700357}
358
asapersson22ff75a2015-08-21 00:02:47 -0700359TEST_F(RtcpSenderTest, SendPli) {
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(), kRtcpPli));
362 EXPECT_EQ(1, parser()->pli()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200363 EXPECT_EQ(kSenderSsrc, parser()->pli()->sender_ssrc());
364 EXPECT_EQ(kRemoteSsrc, parser()->pli()->media_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700365}
366
asapersson22ff75a2015-08-21 00:02:47 -0700367TEST_F(RtcpSenderTest, SendNack) {
pbosda903ea2015-10-02 02:36:56 -0700368 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700369 const uint16_t kList[] = {0, 1, 16};
Elad Alone86af2c2019-06-03 14:37:50 +0200370 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpNack,
371 ABSL_ARRAYSIZE(kList), kList));
asapersson22ff75a2015-08-21 00:02:47 -0700372 EXPECT_EQ(1, parser()->nack()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200373 EXPECT_EQ(kSenderSsrc, parser()->nack()->sender_ssrc());
374 EXPECT_EQ(kRemoteSsrc, parser()->nack()->media_ssrc());
375 EXPECT_THAT(parser()->nack()->packet_ids(), ElementsAre(0, 1, 16));
asapersson22ff75a2015-08-21 00:02:47 -0700376}
377
Elad Alone86af2c2019-06-03 14:37:50 +0200378TEST_F(RtcpSenderTest, SendLossNotificationBufferingNotAllowed) {
Elad Alon7d6a4c02019-02-25 13:00:51 +0100379 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
380 constexpr uint16_t kLastDecoded = 0x1234;
381 constexpr uint16_t kLastReceived = 0x4321;
382 constexpr bool kDecodabilityFlag = true;
Elad Alone86af2c2019-06-03 14:37:50 +0200383 constexpr bool kBufferingAllowed = false;
384 EXPECT_EQ(rtcp_sender_->SendLossNotification(feedback_state(), kLastDecoded,
385 kLastReceived, kDecodabilityFlag,
386 kBufferingAllowed),
387 0);
388 EXPECT_EQ(parser()->processed_rtcp_packets(), 1u);
389 EXPECT_EQ(parser()->loss_notification()->num_packets(), 1);
Elad Alon7d6a4c02019-02-25 13:00:51 +0100390 EXPECT_EQ(kSenderSsrc, parser()->loss_notification()->sender_ssrc());
391 EXPECT_EQ(kRemoteSsrc, parser()->loss_notification()->media_ssrc());
392}
393
Elad Alone86af2c2019-06-03 14:37:50 +0200394TEST_F(RtcpSenderTest, SendLossNotificationBufferingAllowed) {
395 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
396 constexpr uint16_t kLastDecoded = 0x1234;
397 constexpr uint16_t kLastReceived = 0x4321;
398 constexpr bool kDecodabilityFlag = true;
399 constexpr bool kBufferingAllowed = true;
400 EXPECT_EQ(rtcp_sender_->SendLossNotification(feedback_state(), kLastDecoded,
401 kLastReceived, kDecodabilityFlag,
402 kBufferingAllowed),
403 0);
404
405 // No RTCP messages sent yet.
406 ASSERT_EQ(parser()->processed_rtcp_packets(), 0u);
407
408 // Sending another messages triggers sending the LNTF messages as well.
409 const uint16_t kList[] = {0, 1, 16};
410 EXPECT_EQ(rtcp_sender_->SendRTCP(feedback_state(), kRtcpNack,
411 ABSL_ARRAYSIZE(kList), kList),
412 0);
413
414 // Exactly one packet was produced, and it contained both the buffered LNTF
415 // as well as the message that had triggered the packet.
416 EXPECT_EQ(parser()->processed_rtcp_packets(), 1u);
417 EXPECT_EQ(parser()->loss_notification()->num_packets(), 1);
418 EXPECT_EQ(parser()->loss_notification()->sender_ssrc(), kSenderSsrc);
419 EXPECT_EQ(parser()->loss_notification()->media_ssrc(), kRemoteSsrc);
420 EXPECT_EQ(parser()->nack()->num_packets(), 1);
421 EXPECT_EQ(parser()->nack()->sender_ssrc(), kSenderSsrc);
422 EXPECT_EQ(parser()->nack()->media_ssrc(), kRemoteSsrc);
423}
424
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200425TEST_F(RtcpSenderTest, RembNotIncludedBeforeSet) {
426 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
427
428 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
429
430 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
431 EXPECT_EQ(0, parser()->remb()->num_packets());
432}
433
434TEST_F(RtcpSenderTest, RembNotIncludedAfterUnset) {
danilchapba6aa902017-04-18 06:57:02 -0700435 const uint64_t kBitrate = 261011;
436 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
437 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200438 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
danilchapba6aa902017-04-18 06:57:02 -0700439 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
440 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200441 EXPECT_EQ(1, parser()->remb()->num_packets());
danilchapba6aa902017-04-18 06:57:02 -0700442
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200443 // Turn off REMB. rtcp_sender no longer should send it.
444 rtcp_sender_->UnsetRemb();
danilchapba6aa902017-04-18 06:57:02 -0700445 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
446 ASSERT_EQ(2, parser()->receiver_report()->num_packets());
447 EXPECT_EQ(1, parser()->remb()->num_packets());
Danil Chapovalov857a8fb2016-09-06 11:41:46 +0200448}
449
asapersson22ff75a2015-08-21 00:02:47 -0700450TEST_F(RtcpSenderTest, SendRemb) {
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200451 const uint64_t kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200452 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700453 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200454 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
455
456 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRemb);
457
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200458 EXPECT_EQ(1, parser()->remb()->num_packets());
459 EXPECT_EQ(kSenderSsrc, parser()->remb()->sender_ssrc());
460 EXPECT_EQ(kBitrate, parser()->remb()->bitrate_bps());
461 EXPECT_THAT(parser()->remb()->ssrcs(),
asapersson22ff75a2015-08-21 00:02:47 -0700462 ElementsAre(kRemoteSsrc, kRemoteSsrc + 1));
463}
464
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200465TEST_F(RtcpSenderTest, RembIncludedInEachCompoundPacketAfterSet) {
asapersson22ff75a2015-08-21 00:02:47 -0700466 const int kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200467 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700468 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200469 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
470
471 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200472 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700473 // REMB should be included in each compound packet.
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200474 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200475 EXPECT_EQ(2, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700476}
477
asapersson22ff75a2015-08-21 00:02:47 -0700478TEST_F(RtcpSenderTest, SendXrWithDlrr) {
pbosda903ea2015-10-02 02:36:56 -0700479 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000480 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
danilchap798896a2016-09-28 02:54:25 -0700481 rtcp::ReceiveTimeInfo last_xr_rr;
482 last_xr_rr.ssrc = 0x11111111;
483 last_xr_rr.last_rr = 0x22222222;
484 last_xr_rr.delay_since_last_rr = 0x33333333;
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200485 feedback_state.last_xr_rtis.push_back(last_xr_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000486 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200487 EXPECT_EQ(1, parser()->xr()->num_packets());
488 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200489 ASSERT_THAT(parser()->xr()->dlrr().sub_blocks(), SizeIs(1));
danilchap80ac24d2016-10-31 08:40:47 -0700490 EXPECT_EQ(last_xr_rr.ssrc, parser()->xr()->dlrr().sub_blocks()[0].ssrc);
491 EXPECT_EQ(last_xr_rr.last_rr, parser()->xr()->dlrr().sub_blocks()[0].last_rr);
danilchap798896a2016-09-28 02:54:25 -0700492 EXPECT_EQ(last_xr_rr.delay_since_last_rr,
danilchap80ac24d2016-10-31 08:40:47 -0700493 parser()->xr()->dlrr().sub_blocks()[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000494}
495
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200496TEST_F(RtcpSenderTest, SendXrWithMultipleDlrrSubBlocks) {
497 const size_t kNumReceivers = 2;
498 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
499 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
500 for (size_t i = 0; i < kNumReceivers; ++i) {
501 rtcp::ReceiveTimeInfo last_xr_rr;
502 last_xr_rr.ssrc = i;
503 last_xr_rr.last_rr = (i + 1) * 100;
504 last_xr_rr.delay_since_last_rr = (i + 2) * 200;
505 feedback_state.last_xr_rtis.push_back(last_xr_rr);
506 }
507
508 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
509 EXPECT_EQ(1, parser()->xr()->num_packets());
510 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
511 ASSERT_THAT(parser()->xr()->dlrr().sub_blocks(), SizeIs(kNumReceivers));
512 for (size_t i = 0; i < kNumReceivers; ++i) {
513 EXPECT_EQ(feedback_state.last_xr_rtis[i].ssrc,
514 parser()->xr()->dlrr().sub_blocks()[i].ssrc);
515 EXPECT_EQ(feedback_state.last_xr_rtis[i].last_rr,
516 parser()->xr()->dlrr().sub_blocks()[i].last_rr);
517 EXPECT_EQ(feedback_state.last_xr_rtis[i].delay_since_last_rr,
518 parser()->xr()->dlrr().sub_blocks()[i].delay_since_last_rr);
519 }
520}
521
asapersson22ff75a2015-08-21 00:02:47 -0700522TEST_F(RtcpSenderTest, SendXrWithRrtr) {
pbosda903ea2015-10-02 02:36:56 -0700523 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700524 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000525 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200526 NtpTime ntp = TimeMicrosToNtp(clock_.TimeInMicroseconds());
asapersson22ff75a2015-08-21 00:02:47 -0700527 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200528 EXPECT_EQ(1, parser()->xr()->num_packets());
529 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
danilchap80ac24d2016-10-31 08:40:47 -0700530 EXPECT_FALSE(parser()->xr()->dlrr());
danilchap80ac24d2016-10-31 08:40:47 -0700531 ASSERT_TRUE(parser()->xr()->rrtr());
danilchap21dc1892017-03-07 02:51:09 -0800532 EXPECT_EQ(ntp, parser()->xr()->rrtr()->ntp());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000533}
534
asapersson22ff75a2015-08-21 00:02:47 -0700535TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfSending) {
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(), true));
538 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
539 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200540 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700541}
542
543TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfNotEnabled) {
pbosda903ea2015-10-02 02:36:56 -0700544 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700545 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000546 rtcp_sender_->SendRtcpXrReceiverReferenceTime(false);
asapersson22ff75a2015-08-21 00:02:47 -0700547 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200548 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000549}
550
asapersson22ff75a2015-08-21 00:02:47 -0700551TEST_F(RtcpSenderTest, TestRegisterRtcpPacketTypeObserver) {
552 RtcpPacketTypeCounterObserverImpl observer;
sprang86fd9ed2015-09-29 04:45:43 -0700553 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800554 &observer, nullptr, &test_transport_,
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800555 1000));
asapersson22ff75a2015-08-21 00:02:47 -0700556 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700557 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700558 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
559 EXPECT_EQ(1, parser()->pli()->num_packets());
560 EXPECT_EQ(kRemoteSsrc, observer.ssrc_);
561 EXPECT_EQ(1U, observer.counter_.pli_packets);
562 EXPECT_EQ(clock_.TimeInMilliseconds(),
563 observer.counter_.first_packet_time_ms);
564}
565
566TEST_F(RtcpSenderTest, SendTmmbr) {
567 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700568 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700569 rtcp_sender_->SetTargetBitrate(kBitrateBps);
570 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpTmmbr));
571 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200572 EXPECT_EQ(kSenderSsrc, parser()->tmmbr()->sender_ssrc());
573 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
574 EXPECT_EQ(kBitrateBps, parser()->tmmbr()->requests()[0].bitrate_bps());
asapersson22ff75a2015-08-21 00:02:47 -0700575 // TODO(asapersson): tmmbr_item()->Overhead() looks broken, always zero.
576}
577
578TEST_F(RtcpSenderTest, TmmbrIncludedInCompoundPacketIfEnabled) {
579 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700580 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700581 EXPECT_FALSE(rtcp_sender_->TMMBR());
582 rtcp_sender_->SetTMMBRStatus(true);
583 EXPECT_TRUE(rtcp_sender_->TMMBR());
584 rtcp_sender_->SetTargetBitrate(kBitrateBps);
585 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
586 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200587 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
asapersson22ff75a2015-08-21 00:02:47 -0700588 // TMMBR should be included in each compound packet.
589 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
590 EXPECT_EQ(2, parser()->tmmbr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700591
592 rtcp_sender_->SetTMMBRStatus(false);
593 EXPECT_FALSE(rtcp_sender_->TMMBR());
594}
595
596TEST_F(RtcpSenderTest, SendTmmbn) {
pbosda903ea2015-10-02 02:36:56 -0700597 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200598 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700599 std::vector<rtcp::TmmbItem> bounding_set;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200600 const uint32_t kBitrateBps = 32768000;
asapersson22ff75a2015-08-21 00:02:47 -0700601 const uint32_t kPacketOh = 40;
602 const uint32_t kSourceSsrc = 12345;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200603 const rtcp::TmmbItem tmmbn(kSourceSsrc, kBitrateBps, kPacketOh);
danilchap6eaa3a42016-05-09 10:59:50 -0700604 bounding_set.push_back(tmmbn);
danilchap853ecb22016-08-22 08:26:15 -0700605 rtcp_sender_->SetTmmbn(bounding_set);
danilchap6eaa3a42016-05-09 10:59:50 -0700606
asapersson22ff75a2015-08-21 00:02:47 -0700607 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
608 EXPECT_EQ(1, parser()->sender_report()->num_packets());
609 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200610 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
611 EXPECT_EQ(1U, parser()->tmmbn()->items().size());
612 EXPECT_EQ(kBitrateBps, parser()->tmmbn()->items()[0].bitrate_bps());
613 EXPECT_EQ(kPacketOh, parser()->tmmbn()->items()[0].packet_overhead());
614 EXPECT_EQ(kSourceSsrc, parser()->tmmbn()->items()[0].ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700615}
616
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000617// This test is written to verify actual behaviour. It does not seem
618// to make much sense to send an empty TMMBN, since there is no place
619// to put an actual limit here. It's just information that no limit
620// is set, which is kind of the starting assumption.
621// See http://code.google.com/p/webrtc/issues/detail?id=468 for one
622// situation where this caused confusion.
623TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndEmpty) {
pbosda903ea2015-10-02 02:36:56 -0700624 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200625 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700626 std::vector<rtcp::TmmbItem> bounding_set;
danilchap853ecb22016-08-22 08:26:15 -0700627 rtcp_sender_->SetTmmbn(bounding_set);
asapersson22ff75a2015-08-21 00:02:47 -0700628 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
629 EXPECT_EQ(1, parser()->sender_report()->num_packets());
630 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200631 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
632 EXPECT_EQ(0U, parser()->tmmbn()->items().size());
hta@webrtc.org65a4e4e2012-04-30 11:23:41 +0000633}
634
asapersson22ff75a2015-08-21 00:02:47 -0700635TEST_F(RtcpSenderTest, SendCompoundPliRemb) {
636 const int kBitrate = 261011;
637 std::vector<uint32_t> ssrcs;
638 ssrcs.push_back(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700639 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200640 rtcp_sender_->SetRemb(kBitrate, ssrcs);
asapersson22ff75a2015-08-21 00:02:47 -0700641 std::set<RTCPPacketType> packet_types;
642 packet_types.insert(kRtcpRemb);
643 packet_types.insert(kRtcpPli);
644 EXPECT_EQ(0, rtcp_sender_->SendCompoundRTCP(feedback_state(), packet_types));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200645 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700646 EXPECT_EQ(1, parser()->pli()->num_packets());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000647}
Erik Språnga38233a2015-07-24 09:58:18 +0200648
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800649// This test is written to verify that BYE is always the last packet
650// type in a RTCP compoud packet. The rtcp_sender_ is recreated with
651// mock_transport, which is used to check for whether BYE at the end
652// of a RTCP compound packet.
653TEST_F(RtcpSenderTest, ByeMustBeLast) {
654 MockTransport mock_transport;
655 EXPECT_CALL(mock_transport, SendRtcp(_, _))
Yves Gerey665174f2018-06-19 15:03:05 +0200656 .WillOnce(Invoke([](const uint8_t* data, size_t len) {
657 const uint8_t* next_packet = data;
658 const uint8_t* const packet_end = data + len;
659 rtcp::CommonHeader packet;
660 while (next_packet < packet_end) {
661 EXPECT_TRUE(packet.Parse(next_packet, packet_end - next_packet));
662 next_packet = packet.NextPacket();
663 if (packet.type() ==
664 rtcp::Bye::kPacketType) // Main test expectation.
665 EXPECT_EQ(0, packet_end - next_packet)
666 << "Bye packet should be last in a compound RTCP packet.";
667 if (next_packet == packet_end) // Validate test was set correctly.
668 EXPECT_EQ(packet.type(), rtcp::Bye::kPacketType)
669 << "Last packet in this test expected to be Bye.";
670 }
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800671
Yves Gerey665174f2018-06-19 15:03:05 +0200672 return true;
673 }));
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800674
675 // Re-configure rtcp_sender_ with mock_transport_
676 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800677 nullptr, nullptr, &mock_transport, 1000));
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800678 rtcp_sender_->SetSSRC(kSenderSsrc);
679 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
danilchap71fead22016-08-18 02:01:49 -0700680 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
Ilya Nikolaevskiy5e58bcb2018-10-24 13:34:32 +0200681 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds(),
Mirko Bonadei970f2f72019-02-28 14:57:52 +0100682 /*payload_type=*/0);
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800683
Niels Möller44b384d2018-10-05 11:15:57 +0200684 // Set up REMB info to be included with BYE.
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800685 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Niels Möller44b384d2018-10-05 11:15:57 +0200686 rtcp_sender_->SetRemb(1234, {});
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800687 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
688}
689
sprang5e38c962016-12-01 05:18:09 -0800690TEST_F(RtcpSenderTest, SendXrWithTargetBitrate) {
691 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
692 const size_t kNumSpatialLayers = 2;
693 const size_t kNumTemporalLayers = 2;
Erik Språng566124a2018-04-23 12:32:22 +0200694 VideoBitrateAllocation allocation;
sprang5e38c962016-12-01 05:18:09 -0800695 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
696 uint32_t start_bitrate_bps = (sl + 1) * 100000;
697 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl)
698 allocation.SetBitrate(sl, tl, start_bitrate_bps + (tl * 20000));
699 }
700 rtcp_sender_->SetVideoBitrateAllocation(allocation);
701
702 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
703 EXPECT_EQ(1, parser()->xr()->num_packets());
704 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
Danil Chapovalovd264df52018-06-14 12:59:38 +0200705 const absl::optional<rtcp::TargetBitrate>& target_bitrate =
sprang5e38c962016-12-01 05:18:09 -0800706 parser()->xr()->target_bitrate();
707 ASSERT_TRUE(target_bitrate);
708 const std::vector<rtcp::TargetBitrate::BitrateItem>& bitrates =
709 target_bitrate->GetTargetBitrates();
710 EXPECT_EQ(kNumSpatialLayers * kNumTemporalLayers, bitrates.size());
711
712 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
713 uint32_t start_bitrate_bps = (sl + 1) * 100000;
714 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl) {
715 size_t index = (sl * kNumSpatialLayers) + tl;
716 const rtcp::TargetBitrate::BitrateItem& item = bitrates[index];
717 EXPECT_EQ(sl, item.spatial_layer);
718 EXPECT_EQ(tl, item.temporal_layer);
719 EXPECT_EQ(start_bitrate_bps + (tl * 20000),
720 item.target_bitrate_kbps * 1000);
721 }
722 }
723}
724
Erik Språng8782a582018-10-04 15:36:06 +0200725TEST_F(RtcpSenderTest, SendImmediateXrWithTargetBitrate) {
726 // Initialize. Send a first report right away.
727 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
728 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
729 clock_.AdvanceTimeMilliseconds(5);
730
731 // Video bitrate allocation generated, save until next time we send a report.
732 VideoBitrateAllocation allocation;
733 allocation.SetBitrate(0, 0, 100000);
734 rtcp_sender_->SetVideoBitrateAllocation(allocation);
735 // First seen instance will be sent immediately.
736 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
737 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
738 clock_.AdvanceTimeMilliseconds(5);
739
740 // Update bitrate of existing layer, does not quality for immediate sending.
741 allocation.SetBitrate(0, 0, 150000);
742 rtcp_sender_->SetVideoBitrateAllocation(allocation);
743 EXPECT_FALSE(rtcp_sender_->TimeToSendRTCPReport(false));
744
745 // A new spatial layer enabled, signal this as soon as possible.
746 allocation.SetBitrate(1, 0, 200000);
747 rtcp_sender_->SetVideoBitrateAllocation(allocation);
748 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
749 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
750 clock_.AdvanceTimeMilliseconds(5);
751
752 // Explicitly disable top layer. The same set of layers now has a bitrate
753 // defined, but the explicit 0 indicates shutdown. Signal immediately.
754 allocation.SetBitrate(1, 0, 0);
755 EXPECT_FALSE(rtcp_sender_->TimeToSendRTCPReport(false));
756 rtcp_sender_->SetVideoBitrateAllocation(allocation);
757 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
758}
759
Erik Språng1cd73912018-10-05 12:57:59 +0200760TEST_F(RtcpSenderTest, SendTargetBitrateExplicitZeroOnStreamRemoval) {
761 // Set up and send a bitrate allocation with two layers.
762
763 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
764 VideoBitrateAllocation allocation;
765 allocation.SetBitrate(0, 0, 100000);
766 allocation.SetBitrate(1, 0, 200000);
767 rtcp_sender_->SetVideoBitrateAllocation(allocation);
768 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
769 absl::optional<rtcp::TargetBitrate> target_bitrate =
770 parser()->xr()->target_bitrate();
771 ASSERT_TRUE(target_bitrate);
772 std::vector<rtcp::TargetBitrate::BitrateItem> bitrates =
773 target_bitrate->GetTargetBitrates();
774 ASSERT_EQ(2u, bitrates.size());
775 EXPECT_EQ(bitrates[0].target_bitrate_kbps,
776 allocation.GetBitrate(0, 0) / 1000);
777 EXPECT_EQ(bitrates[1].target_bitrate_kbps,
778 allocation.GetBitrate(1, 0) / 1000);
779
780 // Create a new allocation, where the second stream is no longer available.
781 VideoBitrateAllocation new_allocation;
782 new_allocation.SetBitrate(0, 0, 150000);
783 rtcp_sender_->SetVideoBitrateAllocation(new_allocation);
784 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
785 target_bitrate = parser()->xr()->target_bitrate();
786 ASSERT_TRUE(target_bitrate);
787 bitrates = target_bitrate->GetTargetBitrates();
788
789 // Two bitrates should still be set, with an explicit entry indicating the
790 // removed stream is gone.
791 ASSERT_EQ(2u, bitrates.size());
792 EXPECT_EQ(bitrates[0].target_bitrate_kbps,
793 new_allocation.GetBitrate(0, 0) / 1000);
794 EXPECT_EQ(bitrates[1].target_bitrate_kbps, 0u);
795}
796
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000797} // namespace webrtc