blob: 3e37cc6001ec013bbc9911edca0f9a523ae168e1 [file] [log] [blame]
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001/*
henrike@webrtc.orgd6d014f2012-02-16 02:18:09 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
kwiberg84be5112016-04-27 01:19:58 -070011#include <memory>
12
Mirko Bonadei71207422017-09-15 13:58:09 +020013#include "common_types.h" // NOLINT(build/include)
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
Yves Gerey665174f2018-06-19 15:03:05 +020048class TestTransport : public Transport, public RtpData {
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 int OnReceivedPayloadData(const uint8_t* payload_data,
perkj16ccfdf2017-02-28 14:41:05 -080062 size_t payload_size,
asapersson22ff75a2015-08-21 00:02:47 -070063 const WebRtcRTPHeader* rtp_header) override {
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000064 return 0;
65 }
asapersson22ff75a2015-08-21 00:02:47 -070066 test::RtcpPacketParser parser_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000067};
68
Erik Språnga38233a2015-07-24 09:58:18 +020069namespace {
asapersson22ff75a2015-08-21 00:02:47 -070070static const uint32_t kSenderSsrc = 0x11111111;
71static const uint32_t kRemoteSsrc = 0x22222222;
Danil Chapovalov70ffead2016-07-20 15:26:59 +020072static const uint32_t kStartRtpTimestamp = 0x34567;
73static const uint32_t kRtpTimestamp = 0x45678;
Yves Gerey665174f2018-06-19 15:03:05 +020074} // namespace
Erik Språnga38233a2015-07-24 09:58:18 +020075
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000076class RtcpSenderTest : public ::testing::Test {
77 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +000078 RtcpSenderTest()
asapersson22ff75a2015-08-21 00:02:47 -070079 : clock_(1335900000),
Erik Språng737336d2016-07-29 12:59:36 +020080 receive_statistics_(ReceiveStatistics::Create(&clock_)),
81 retransmission_rate_limiter_(&clock_, 1000) {
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000082 RtpRtcp::Configuration configuration;
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000083 configuration.audio = false;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +000084 configuration.clock = &clock_;
asapersson22ff75a2015-08-21 00:02:47 -070085 configuration.outgoing_transport = &test_transport_;
Erik Språng737336d2016-07-29 12:59:36 +020086 configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000087
asapersson22ff75a2015-08-21 00:02:47 -070088 rtp_rtcp_impl_.reset(new ModuleRtpRtcpImpl(configuration));
sprang86fd9ed2015-09-29 04:45:43 -070089 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -080090 nullptr, nullptr, &test_transport_,
91 configuration.rtcp_interval_config));
asapersson22ff75a2015-08-21 00:02:47 -070092 rtcp_sender_->SetSSRC(kSenderSsrc);
93 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
danilchap71fead22016-08-18 02:01:49 -070094 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
Ilya Nikolaevskiy5e58bcb2018-10-24 13:34:32 +020095 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds(),
96 /*paylpad_type=*/0);
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000097 }
Erik Språnga38233a2015-07-24 09:58:18 +020098
asapersson22ff75a2015-08-21 00:02:47 -070099 void InsertIncomingPacket(uint32_t remote_ssrc, uint16_t seq_num) {
Niels Möller1f3206c2018-09-14 08:26:32 +0200100 RtpPacketReceived packet;
101 packet.SetSsrc(remote_ssrc);
102 packet.SetSequenceNumber(seq_num);
103 packet.SetTimestamp(12345);
104 packet.SetPayloadSize(100 - 12);
105 receive_statistics_->OnRtpPacket(packet);
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000106 }
107
asapersson22ff75a2015-08-21 00:02:47 -0700108 test::RtcpPacketParser* parser() { return &test_transport_.parser_; }
109
110 RTCPSender::FeedbackState feedback_state() {
111 return rtp_rtcp_impl_->GetFeedbackState();
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000112 }
113
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000114 SimulatedClock clock_;
asapersson22ff75a2015-08-21 00:02:47 -0700115 TestTransport test_transport_;
kwiberg84be5112016-04-27 01:19:58 -0700116 std::unique_ptr<ReceiveStatistics> receive_statistics_;
117 std::unique_ptr<ModuleRtpRtcpImpl> rtp_rtcp_impl_;
118 std::unique_ptr<RTCPSender> rtcp_sender_;
Erik Språng737336d2016-07-29 12:59:36 +0200119 RateLimiter retransmission_rate_limiter_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000120};
121
asapersson22ff75a2015-08-21 00:02:47 -0700122TEST_F(RtcpSenderTest, SetRtcpStatus) {
pbosda903ea2015-10-02 02:36:56 -0700123 EXPECT_EQ(RtcpMode::kOff, rtcp_sender_->Status());
124 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
125 EXPECT_EQ(RtcpMode::kReducedSize, rtcp_sender_->Status());
asapersson22ff75a2015-08-21 00:02:47 -0700126}
127
128TEST_F(RtcpSenderTest, SetSendingStatus) {
129 EXPECT_FALSE(rtcp_sender_->Sending());
130 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
131 EXPECT_TRUE(rtcp_sender_->Sending());
132}
133
134TEST_F(RtcpSenderTest, NoPacketSentIfOff) {
pbosda903ea2015-10-02 02:36:56 -0700135 rtcp_sender_->SetRTCPStatus(RtcpMode::kOff);
asapersson22ff75a2015-08-21 00:02:47 -0700136 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000137}
138
asapersson22ff75a2015-08-21 00:02:47 -0700139TEST_F(RtcpSenderTest, SendSr) {
140 const uint32_t kPacketCount = 0x12345;
141 const uint32_t kOctetCount = 0x23456;
pbosda903ea2015-10-02 02:36:56 -0700142 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000143 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200144 rtcp_sender_->SetSendingStatus(feedback_state, true);
asapersson22ff75a2015-08-21 00:02:47 -0700145 feedback_state.packets_sent = kPacketCount;
146 feedback_state.media_bytes_sent = kOctetCount;
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200147 NtpTime ntp = TimeMicrosToNtp(clock_.TimeInMicroseconds());
asapersson22ff75a2015-08-21 00:02:47 -0700148 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
149 EXPECT_EQ(1, parser()->sender_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200150 EXPECT_EQ(kSenderSsrc, parser()->sender_report()->sender_ssrc());
danilchap21dc1892017-03-07 02:51:09 -0800151 EXPECT_EQ(ntp, parser()->sender_report()->ntp());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200152 EXPECT_EQ(kPacketCount, parser()->sender_report()->sender_packet_count());
153 EXPECT_EQ(kOctetCount, parser()->sender_report()->sender_octet_count());
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200154 EXPECT_EQ(kStartRtpTimestamp + kRtpTimestamp,
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200155 parser()->sender_report()->rtp_timestamp());
156 EXPECT_EQ(0U, parser()->sender_report()->report_blocks().size());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000157}
158
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200159TEST_F(RtcpSenderTest, SendConsecutiveSrWithExactSlope) {
160 const uint32_t kPacketCount = 0x12345;
161 const uint32_t kOctetCount = 0x23456;
162 const int kTimeBetweenSRsUs = 10043; // Not exact value in milliseconds.
163 const int kExtraPackets = 30;
164 // Make sure clock is not exactly at some milliseconds point.
165 clock_.AdvanceTimeMicroseconds(kTimeBetweenSRsUs);
166 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
167 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
168 rtcp_sender_->SetSendingStatus(feedback_state, true);
169 feedback_state.packets_sent = kPacketCount;
170 feedback_state.media_bytes_sent = kOctetCount;
171
172 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
173 EXPECT_EQ(1, parser()->sender_report()->num_packets());
174 NtpTime ntp1 = parser()->sender_report()->ntp();
175 uint32_t rtp1 = parser()->sender_report()->rtp_timestamp();
176
177 // Send more SRs to ensure slope is always exact for different offsets
178 for (int packets = 1; packets <= kExtraPackets; ++packets) {
179 clock_.AdvanceTimeMicroseconds(kTimeBetweenSRsUs);
180 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
181 EXPECT_EQ(packets + 1, parser()->sender_report()->num_packets());
182
183 NtpTime ntp2 = parser()->sender_report()->ntp();
184 uint32_t rtp2 = parser()->sender_report()->rtp_timestamp();
185
186 uint32_t ntp_diff_in_rtp_units =
187 (ntp2.ToMs() - ntp1.ToMs()) * (kVideoPayloadTypeFrequency / 1000);
188 EXPECT_EQ(rtp2 - rtp1, ntp_diff_in_rtp_units);
189 }
190}
191
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200192TEST_F(RtcpSenderTest, DoNotSendSrBeforeRtp) {
193 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800194 nullptr, nullptr, &test_transport_,
195 RtcpIntervalConfig{}));
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200196 rtcp_sender_->SetSSRC(kSenderSsrc);
197 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
198 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
199 rtcp_sender_->SetSendingStatus(feedback_state(), true);
200
201 // Sender Report shouldn't be send as an SR nor as a Report.
202 rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr);
203 EXPECT_EQ(0, parser()->sender_report()->num_packets());
204 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
205 EXPECT_EQ(0, parser()->sender_report()->num_packets());
206 // Other packets (e.g. Pli) are allowed, even if useless.
207 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
208 EXPECT_EQ(1, parser()->pli()->num_packets());
209}
210
211TEST_F(RtcpSenderTest, DoNotSendCompundBeforeRtp) {
212 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800213 nullptr, nullptr, &test_transport_,
214 RtcpIntervalConfig{}));
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200215 rtcp_sender_->SetSSRC(kSenderSsrc);
216 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
217 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
218 rtcp_sender_->SetSendingStatus(feedback_state(), true);
219
220 // In compound mode no packets are allowed (e.g. Pli) because compound mode
221 // should start with Sender Report.
222 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
223 EXPECT_EQ(0, parser()->pli()->num_packets());
224}
225
asapersson22ff75a2015-08-21 00:02:47 -0700226TEST_F(RtcpSenderTest, SendRr) {
pbosda903ea2015-10-02 02:36:56 -0700227 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700228 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
229 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200230 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
231 EXPECT_EQ(0U, parser()->receiver_report()->report_blocks().size());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000232}
233
asapersson22ff75a2015-08-21 00:02:47 -0700234TEST_F(RtcpSenderTest, SendRrWithOneReportBlock) {
235 const uint16_t kSeqNum = 11111;
236 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
pbosda903ea2015-10-02 02:36:56 -0700237 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700238 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
239 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200240 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
241 ASSERT_EQ(1U, parser()->receiver_report()->report_blocks().size());
242 const rtcp::ReportBlock& rb = parser()->receiver_report()->report_blocks()[0];
243 EXPECT_EQ(kRemoteSsrc, rb.source_ssrc());
244 EXPECT_EQ(0U, rb.fraction_lost());
Harald Alvestrand70206d62017-12-08 08:59:07 +0100245 EXPECT_EQ(0, rb.cumulative_lost_signed());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200246 EXPECT_EQ(kSeqNum, rb.extended_high_seq_num());
asapersson22ff75a2015-08-21 00:02:47 -0700247}
248
249TEST_F(RtcpSenderTest, SendRrWithTwoReportBlocks) {
250 const uint16_t kSeqNum = 11111;
251 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
252 InsertIncomingPacket(kRemoteSsrc + 1, kSeqNum + 1);
pbosda903ea2015-10-02 02:36:56 -0700253 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700254 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
255 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200256 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
257 EXPECT_EQ(2U, parser()->receiver_report()->report_blocks().size());
258 EXPECT_EQ(kRemoteSsrc,
259 parser()->receiver_report()->report_blocks()[0].source_ssrc());
260 EXPECT_EQ(kRemoteSsrc + 1,
261 parser()->receiver_report()->report_blocks()[1].source_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700262}
263
264TEST_F(RtcpSenderTest, SendSdes) {
pbosda903ea2015-10-02 02:36:56 -0700265 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700266 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
267 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
268 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200269 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
270 EXPECT_EQ(kSenderSsrc, parser()->sdes()->chunks()[0].ssrc);
271 EXPECT_EQ("alice@host", parser()->sdes()->chunks()[0].cname);
asapersson22ff75a2015-08-21 00:02:47 -0700272}
273
danilchap74e8df8f2017-03-16 08:04:08 -0700274TEST_F(RtcpSenderTest, SendSdesWithMaxChunks) {
275 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
276 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
277 const char cname[] = "smith@host";
278 for (size_t i = 0; i < 30; ++i) {
279 const uint32_t csrc = 0x1234 + i;
280 EXPECT_EQ(0, rtcp_sender_->AddMixedCNAME(csrc, cname));
281 }
282 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
283 EXPECT_EQ(1, parser()->sdes()->num_packets());
284 EXPECT_EQ(31U, parser()->sdes()->chunks().size());
285}
286
asapersson22ff75a2015-08-21 00:02:47 -0700287TEST_F(RtcpSenderTest, SdesIncludedInCompoundPacket) {
pbosda903ea2015-10-02 02:36:56 -0700288 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700289 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
290 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
291 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
292 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200293 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
asapersson22ff75a2015-08-21 00:02:47 -0700294}
295
296TEST_F(RtcpSenderTest, SendBye) {
pbosda903ea2015-10-02 02:36:56 -0700297 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700298 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
299 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200300 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700301}
302
303TEST_F(RtcpSenderTest, StopSendingTriggersBye) {
pbosda903ea2015-10-02 02:36:56 -0700304 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700305 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
306 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
307 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200308 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700309}
310
311TEST_F(RtcpSenderTest, SendApp) {
312 const uint8_t kSubType = 30;
313 uint32_t name = 'n' << 24;
314 name += 'a' << 16;
315 name += 'm' << 8;
316 name += 'e';
317 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
asapersson22ff75a2015-08-21 00:02:47 -0700318 EXPECT_EQ(0, rtcp_sender_->SetApplicationSpecificData(kSubType, name, kData,
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200319 sizeof(kData)));
pbosda903ea2015-10-02 02:36:56 -0700320 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700321 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
322 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200323 EXPECT_EQ(kSubType, parser()->app()->sub_type());
324 EXPECT_EQ(name, parser()->app()->name());
325 EXPECT_EQ(sizeof(kData), parser()->app()->data_size());
326 EXPECT_EQ(0, memcmp(kData, parser()->app()->data(), sizeof(kData)));
asapersson22ff75a2015-08-21 00:02:47 -0700327}
328
Erik Språng521875a2015-09-01 10:11:16 +0200329TEST_F(RtcpSenderTest, SendEmptyApp) {
330 const uint8_t kSubType = 30;
331 const uint32_t kName = 0x6E616D65;
332
333 EXPECT_EQ(
334 0, rtcp_sender_->SetApplicationSpecificData(kSubType, kName, nullptr, 0));
335
pbosda903ea2015-10-02 02:36:56 -0700336 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Erik Språng521875a2015-09-01 10:11:16 +0200337 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
338 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200339 EXPECT_EQ(kSubType, parser()->app()->sub_type());
340 EXPECT_EQ(kName, parser()->app()->name());
341 EXPECT_EQ(0U, parser()->app()->data_size());
Erik Språng521875a2015-09-01 10:11:16 +0200342}
343
asapersson22ff75a2015-08-21 00:02:47 -0700344TEST_F(RtcpSenderTest, SetInvalidApplicationSpecificData) {
345 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't'};
346 const uint16_t kInvalidDataLength = sizeof(kData) / sizeof(kData[0]);
Yves Gerey665174f2018-06-19 15:03:05 +0200347 EXPECT_EQ(-1,
348 rtcp_sender_->SetApplicationSpecificData(
349 0, 0, kData, kInvalidDataLength)); // Should by multiple of 4.
asapersson22ff75a2015-08-21 00:02:47 -0700350}
351
danilchap498ee8e2017-02-08 05:24:31 -0800352TEST_F(RtcpSenderTest, SendFir) {
pbosda903ea2015-10-02 02:36:56 -0700353 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700354 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
355 EXPECT_EQ(1, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200356 EXPECT_EQ(kSenderSsrc, parser()->fir()->sender_ssrc());
357 EXPECT_EQ(1U, parser()->fir()->requests().size());
358 EXPECT_EQ(kRemoteSsrc, parser()->fir()->requests()[0].ssrc);
359 uint8_t seq = parser()->fir()->requests()[0].seq_nr;
asapersson22ff75a2015-08-21 00:02:47 -0700360 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
361 EXPECT_EQ(2, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200362 EXPECT_EQ(seq + 1, parser()->fir()->requests()[0].seq_nr);
asapersson22ff75a2015-08-21 00:02:47 -0700363}
364
asapersson22ff75a2015-08-21 00:02:47 -0700365TEST_F(RtcpSenderTest, SendPli) {
pbosda903ea2015-10-02 02:36:56 -0700366 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700367 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
368 EXPECT_EQ(1, parser()->pli()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200369 EXPECT_EQ(kSenderSsrc, parser()->pli()->sender_ssrc());
370 EXPECT_EQ(kRemoteSsrc, parser()->pli()->media_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700371}
372
asapersson22ff75a2015-08-21 00:02:47 -0700373TEST_F(RtcpSenderTest, SendNack) {
pbosda903ea2015-10-02 02:36:56 -0700374 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700375 const uint16_t kList[] = {0, 1, 16};
376 const int32_t kListLength = sizeof(kList) / sizeof(kList[0]);
377 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpNack, kListLength,
378 kList));
379 EXPECT_EQ(1, parser()->nack()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200380 EXPECT_EQ(kSenderSsrc, parser()->nack()->sender_ssrc());
381 EXPECT_EQ(kRemoteSsrc, parser()->nack()->media_ssrc());
382 EXPECT_THAT(parser()->nack()->packet_ids(), ElementsAre(0, 1, 16));
asapersson22ff75a2015-08-21 00:02:47 -0700383}
384
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200385TEST_F(RtcpSenderTest, RembNotIncludedBeforeSet) {
386 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
387
388 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
389
390 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
391 EXPECT_EQ(0, parser()->remb()->num_packets());
392}
393
394TEST_F(RtcpSenderTest, RembNotIncludedAfterUnset) {
danilchapba6aa902017-04-18 06:57:02 -0700395 const uint64_t kBitrate = 261011;
396 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
397 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200398 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
danilchapba6aa902017-04-18 06:57:02 -0700399 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
400 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200401 EXPECT_EQ(1, parser()->remb()->num_packets());
danilchapba6aa902017-04-18 06:57:02 -0700402
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200403 // Turn off REMB. rtcp_sender no longer should send it.
404 rtcp_sender_->UnsetRemb();
danilchapba6aa902017-04-18 06:57:02 -0700405 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
406 ASSERT_EQ(2, parser()->receiver_report()->num_packets());
407 EXPECT_EQ(1, parser()->remb()->num_packets());
Danil Chapovalov857a8fb2016-09-06 11:41:46 +0200408}
409
asapersson22ff75a2015-08-21 00:02:47 -0700410TEST_F(RtcpSenderTest, SendRemb) {
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200411 const uint64_t kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200412 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700413 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200414 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
415
416 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRemb);
417
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200418 EXPECT_EQ(1, parser()->remb()->num_packets());
419 EXPECT_EQ(kSenderSsrc, parser()->remb()->sender_ssrc());
420 EXPECT_EQ(kBitrate, parser()->remb()->bitrate_bps());
421 EXPECT_THAT(parser()->remb()->ssrcs(),
asapersson22ff75a2015-08-21 00:02:47 -0700422 ElementsAre(kRemoteSsrc, kRemoteSsrc + 1));
423}
424
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200425TEST_F(RtcpSenderTest, RembIncludedInEachCompoundPacketAfterSet) {
asapersson22ff75a2015-08-21 00:02:47 -0700426 const int kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200427 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700428 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200429 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
430
431 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200432 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700433 // REMB should be included in each compound packet.
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200434 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200435 EXPECT_EQ(2, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700436}
437
asapersson22ff75a2015-08-21 00:02:47 -0700438TEST_F(RtcpSenderTest, SendXrWithDlrr) {
pbosda903ea2015-10-02 02:36:56 -0700439 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000440 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
danilchap798896a2016-09-28 02:54:25 -0700441 rtcp::ReceiveTimeInfo last_xr_rr;
442 last_xr_rr.ssrc = 0x11111111;
443 last_xr_rr.last_rr = 0x22222222;
444 last_xr_rr.delay_since_last_rr = 0x33333333;
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200445 feedback_state.last_xr_rtis.push_back(last_xr_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000446 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200447 EXPECT_EQ(1, parser()->xr()->num_packets());
448 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200449 ASSERT_THAT(parser()->xr()->dlrr().sub_blocks(), SizeIs(1));
danilchap80ac24d2016-10-31 08:40:47 -0700450 EXPECT_EQ(last_xr_rr.ssrc, parser()->xr()->dlrr().sub_blocks()[0].ssrc);
451 EXPECT_EQ(last_xr_rr.last_rr, parser()->xr()->dlrr().sub_blocks()[0].last_rr);
danilchap798896a2016-09-28 02:54:25 -0700452 EXPECT_EQ(last_xr_rr.delay_since_last_rr,
danilchap80ac24d2016-10-31 08:40:47 -0700453 parser()->xr()->dlrr().sub_blocks()[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000454}
455
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200456TEST_F(RtcpSenderTest, SendXrWithMultipleDlrrSubBlocks) {
457 const size_t kNumReceivers = 2;
458 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
459 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
460 for (size_t i = 0; i < kNumReceivers; ++i) {
461 rtcp::ReceiveTimeInfo last_xr_rr;
462 last_xr_rr.ssrc = i;
463 last_xr_rr.last_rr = (i + 1) * 100;
464 last_xr_rr.delay_since_last_rr = (i + 2) * 200;
465 feedback_state.last_xr_rtis.push_back(last_xr_rr);
466 }
467
468 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
469 EXPECT_EQ(1, parser()->xr()->num_packets());
470 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
471 ASSERT_THAT(parser()->xr()->dlrr().sub_blocks(), SizeIs(kNumReceivers));
472 for (size_t i = 0; i < kNumReceivers; ++i) {
473 EXPECT_EQ(feedback_state.last_xr_rtis[i].ssrc,
474 parser()->xr()->dlrr().sub_blocks()[i].ssrc);
475 EXPECT_EQ(feedback_state.last_xr_rtis[i].last_rr,
476 parser()->xr()->dlrr().sub_blocks()[i].last_rr);
477 EXPECT_EQ(feedback_state.last_xr_rtis[i].delay_since_last_rr,
478 parser()->xr()->dlrr().sub_blocks()[i].delay_since_last_rr);
479 }
480}
481
asapersson22ff75a2015-08-21 00:02:47 -0700482TEST_F(RtcpSenderTest, SendXrWithRrtr) {
pbosda903ea2015-10-02 02:36:56 -0700483 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700484 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000485 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200486 NtpTime ntp = TimeMicrosToNtp(clock_.TimeInMicroseconds());
asapersson22ff75a2015-08-21 00:02:47 -0700487 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200488 EXPECT_EQ(1, parser()->xr()->num_packets());
489 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
danilchap80ac24d2016-10-31 08:40:47 -0700490 EXPECT_FALSE(parser()->xr()->dlrr());
danilchap80ac24d2016-10-31 08:40:47 -0700491 ASSERT_TRUE(parser()->xr()->rrtr());
danilchap21dc1892017-03-07 02:51:09 -0800492 EXPECT_EQ(ntp, parser()->xr()->rrtr()->ntp());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000493}
494
asapersson22ff75a2015-08-21 00:02:47 -0700495TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfSending) {
pbosda903ea2015-10-02 02:36:56 -0700496 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700497 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
498 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
499 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200500 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700501}
502
503TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfNotEnabled) {
pbosda903ea2015-10-02 02:36:56 -0700504 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700505 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000506 rtcp_sender_->SendRtcpXrReceiverReferenceTime(false);
asapersson22ff75a2015-08-21 00:02:47 -0700507 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200508 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000509}
510
asapersson22ff75a2015-08-21 00:02:47 -0700511TEST_F(RtcpSenderTest, TestRegisterRtcpPacketTypeObserver) {
512 RtcpPacketTypeCounterObserverImpl observer;
sprang86fd9ed2015-09-29 04:45:43 -0700513 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800514 &observer, nullptr, &test_transport_,
515 RtcpIntervalConfig{}));
asapersson22ff75a2015-08-21 00:02:47 -0700516 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700517 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700518 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
519 EXPECT_EQ(1, parser()->pli()->num_packets());
520 EXPECT_EQ(kRemoteSsrc, observer.ssrc_);
521 EXPECT_EQ(1U, observer.counter_.pli_packets);
522 EXPECT_EQ(clock_.TimeInMilliseconds(),
523 observer.counter_.first_packet_time_ms);
524}
525
526TEST_F(RtcpSenderTest, SendTmmbr) {
527 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700528 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700529 rtcp_sender_->SetTargetBitrate(kBitrateBps);
530 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpTmmbr));
531 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200532 EXPECT_EQ(kSenderSsrc, parser()->tmmbr()->sender_ssrc());
533 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
534 EXPECT_EQ(kBitrateBps, parser()->tmmbr()->requests()[0].bitrate_bps());
asapersson22ff75a2015-08-21 00:02:47 -0700535 // TODO(asapersson): tmmbr_item()->Overhead() looks broken, always zero.
536}
537
538TEST_F(RtcpSenderTest, TmmbrIncludedInCompoundPacketIfEnabled) {
539 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700540 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700541 EXPECT_FALSE(rtcp_sender_->TMMBR());
542 rtcp_sender_->SetTMMBRStatus(true);
543 EXPECT_TRUE(rtcp_sender_->TMMBR());
544 rtcp_sender_->SetTargetBitrate(kBitrateBps);
545 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
546 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200547 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
asapersson22ff75a2015-08-21 00:02:47 -0700548 // TMMBR should be included in each compound packet.
549 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
550 EXPECT_EQ(2, parser()->tmmbr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700551
552 rtcp_sender_->SetTMMBRStatus(false);
553 EXPECT_FALSE(rtcp_sender_->TMMBR());
554}
555
556TEST_F(RtcpSenderTest, SendTmmbn) {
pbosda903ea2015-10-02 02:36:56 -0700557 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200558 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700559 std::vector<rtcp::TmmbItem> bounding_set;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200560 const uint32_t kBitrateBps = 32768000;
asapersson22ff75a2015-08-21 00:02:47 -0700561 const uint32_t kPacketOh = 40;
562 const uint32_t kSourceSsrc = 12345;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200563 const rtcp::TmmbItem tmmbn(kSourceSsrc, kBitrateBps, kPacketOh);
danilchap6eaa3a42016-05-09 10:59:50 -0700564 bounding_set.push_back(tmmbn);
danilchap853ecb22016-08-22 08:26:15 -0700565 rtcp_sender_->SetTmmbn(bounding_set);
danilchap6eaa3a42016-05-09 10:59:50 -0700566
asapersson22ff75a2015-08-21 00:02:47 -0700567 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
568 EXPECT_EQ(1, parser()->sender_report()->num_packets());
569 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200570 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
571 EXPECT_EQ(1U, parser()->tmmbn()->items().size());
572 EXPECT_EQ(kBitrateBps, parser()->tmmbn()->items()[0].bitrate_bps());
573 EXPECT_EQ(kPacketOh, parser()->tmmbn()->items()[0].packet_overhead());
574 EXPECT_EQ(kSourceSsrc, parser()->tmmbn()->items()[0].ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700575}
576
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000577// This test is written to verify actual behaviour. It does not seem
578// to make much sense to send an empty TMMBN, since there is no place
579// to put an actual limit here. It's just information that no limit
580// is set, which is kind of the starting assumption.
581// See http://code.google.com/p/webrtc/issues/detail?id=468 for one
582// situation where this caused confusion.
583TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndEmpty) {
pbosda903ea2015-10-02 02:36:56 -0700584 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200585 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700586 std::vector<rtcp::TmmbItem> bounding_set;
danilchap853ecb22016-08-22 08:26:15 -0700587 rtcp_sender_->SetTmmbn(bounding_set);
asapersson22ff75a2015-08-21 00:02:47 -0700588 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
589 EXPECT_EQ(1, parser()->sender_report()->num_packets());
590 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200591 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
592 EXPECT_EQ(0U, parser()->tmmbn()->items().size());
hta@webrtc.org65a4e4e2012-04-30 11:23:41 +0000593}
594
asapersson22ff75a2015-08-21 00:02:47 -0700595TEST_F(RtcpSenderTest, SendCompoundPliRemb) {
596 const int kBitrate = 261011;
597 std::vector<uint32_t> ssrcs;
598 ssrcs.push_back(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700599 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200600 rtcp_sender_->SetRemb(kBitrate, ssrcs);
asapersson22ff75a2015-08-21 00:02:47 -0700601 std::set<RTCPPacketType> packet_types;
602 packet_types.insert(kRtcpRemb);
603 packet_types.insert(kRtcpPli);
604 EXPECT_EQ(0, rtcp_sender_->SendCompoundRTCP(feedback_state(), packet_types));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200605 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700606 EXPECT_EQ(1, parser()->pli()->num_packets());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000607}
Erik Språnga38233a2015-07-24 09:58:18 +0200608
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800609// This test is written to verify that BYE is always the last packet
610// type in a RTCP compoud packet. The rtcp_sender_ is recreated with
611// mock_transport, which is used to check for whether BYE at the end
612// of a RTCP compound packet.
613TEST_F(RtcpSenderTest, ByeMustBeLast) {
614 MockTransport mock_transport;
615 EXPECT_CALL(mock_transport, SendRtcp(_, _))
Yves Gerey665174f2018-06-19 15:03:05 +0200616 .WillOnce(Invoke([](const uint8_t* data, size_t len) {
617 const uint8_t* next_packet = data;
618 const uint8_t* const packet_end = data + len;
619 rtcp::CommonHeader packet;
620 while (next_packet < packet_end) {
621 EXPECT_TRUE(packet.Parse(next_packet, packet_end - next_packet));
622 next_packet = packet.NextPacket();
623 if (packet.type() ==
624 rtcp::Bye::kPacketType) // Main test expectation.
625 EXPECT_EQ(0, packet_end - next_packet)
626 << "Bye packet should be last in a compound RTCP packet.";
627 if (next_packet == packet_end) // Validate test was set correctly.
628 EXPECT_EQ(packet.type(), rtcp::Bye::kPacketType)
629 << "Last packet in this test expected to be Bye.";
630 }
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800631
Yves Gerey665174f2018-06-19 15:03:05 +0200632 return true;
633 }));
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800634
635 // Re-configure rtcp_sender_ with mock_transport_
636 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800637 nullptr, nullptr, &mock_transport,
638 RtcpIntervalConfig{}));
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800639 rtcp_sender_->SetSSRC(kSenderSsrc);
640 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
danilchap71fead22016-08-18 02:01:49 -0700641 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
Ilya Nikolaevskiy5e58bcb2018-10-24 13:34:32 +0200642 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds(),
643 /*paylpad_type=*/0);
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800644
Niels Möller44b384d2018-10-05 11:15:57 +0200645 // Set up REMB info to be included with BYE.
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800646 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Niels Möller44b384d2018-10-05 11:15:57 +0200647 rtcp_sender_->SetRemb(1234, {});
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800648 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
649}
650
sprang5e38c962016-12-01 05:18:09 -0800651TEST_F(RtcpSenderTest, SendXrWithTargetBitrate) {
652 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
653 const size_t kNumSpatialLayers = 2;
654 const size_t kNumTemporalLayers = 2;
Erik Språng566124a2018-04-23 12:32:22 +0200655 VideoBitrateAllocation allocation;
sprang5e38c962016-12-01 05:18:09 -0800656 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
657 uint32_t start_bitrate_bps = (sl + 1) * 100000;
658 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl)
659 allocation.SetBitrate(sl, tl, start_bitrate_bps + (tl * 20000));
660 }
661 rtcp_sender_->SetVideoBitrateAllocation(allocation);
662
663 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
664 EXPECT_EQ(1, parser()->xr()->num_packets());
665 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
Danil Chapovalovd264df52018-06-14 12:59:38 +0200666 const absl::optional<rtcp::TargetBitrate>& target_bitrate =
sprang5e38c962016-12-01 05:18:09 -0800667 parser()->xr()->target_bitrate();
668 ASSERT_TRUE(target_bitrate);
669 const std::vector<rtcp::TargetBitrate::BitrateItem>& bitrates =
670 target_bitrate->GetTargetBitrates();
671 EXPECT_EQ(kNumSpatialLayers * kNumTemporalLayers, bitrates.size());
672
673 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
674 uint32_t start_bitrate_bps = (sl + 1) * 100000;
675 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl) {
676 size_t index = (sl * kNumSpatialLayers) + tl;
677 const rtcp::TargetBitrate::BitrateItem& item = bitrates[index];
678 EXPECT_EQ(sl, item.spatial_layer);
679 EXPECT_EQ(tl, item.temporal_layer);
680 EXPECT_EQ(start_bitrate_bps + (tl * 20000),
681 item.target_bitrate_kbps * 1000);
682 }
683 }
684}
685
Erik Språng8782a582018-10-04 15:36:06 +0200686TEST_F(RtcpSenderTest, SendImmediateXrWithTargetBitrate) {
687 // Initialize. Send a first report right away.
688 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
689 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
690 clock_.AdvanceTimeMilliseconds(5);
691
692 // Video bitrate allocation generated, save until next time we send a report.
693 VideoBitrateAllocation allocation;
694 allocation.SetBitrate(0, 0, 100000);
695 rtcp_sender_->SetVideoBitrateAllocation(allocation);
696 // First seen instance will be sent immediately.
697 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
698 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
699 clock_.AdvanceTimeMilliseconds(5);
700
701 // Update bitrate of existing layer, does not quality for immediate sending.
702 allocation.SetBitrate(0, 0, 150000);
703 rtcp_sender_->SetVideoBitrateAllocation(allocation);
704 EXPECT_FALSE(rtcp_sender_->TimeToSendRTCPReport(false));
705
706 // A new spatial layer enabled, signal this as soon as possible.
707 allocation.SetBitrate(1, 0, 200000);
708 rtcp_sender_->SetVideoBitrateAllocation(allocation);
709 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
710 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
711 clock_.AdvanceTimeMilliseconds(5);
712
713 // Explicitly disable top layer. The same set of layers now has a bitrate
714 // defined, but the explicit 0 indicates shutdown. Signal immediately.
715 allocation.SetBitrate(1, 0, 0);
716 EXPECT_FALSE(rtcp_sender_->TimeToSendRTCPReport(false));
717 rtcp_sender_->SetVideoBitrateAllocation(allocation);
718 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
719}
720
Erik Språng1cd73912018-10-05 12:57:59 +0200721TEST_F(RtcpSenderTest, SendTargetBitrateExplicitZeroOnStreamRemoval) {
722 // Set up and send a bitrate allocation with two layers.
723
724 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
725 VideoBitrateAllocation allocation;
726 allocation.SetBitrate(0, 0, 100000);
727 allocation.SetBitrate(1, 0, 200000);
728 rtcp_sender_->SetVideoBitrateAllocation(allocation);
729 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
730 absl::optional<rtcp::TargetBitrate> target_bitrate =
731 parser()->xr()->target_bitrate();
732 ASSERT_TRUE(target_bitrate);
733 std::vector<rtcp::TargetBitrate::BitrateItem> bitrates =
734 target_bitrate->GetTargetBitrates();
735 ASSERT_EQ(2u, bitrates.size());
736 EXPECT_EQ(bitrates[0].target_bitrate_kbps,
737 allocation.GetBitrate(0, 0) / 1000);
738 EXPECT_EQ(bitrates[1].target_bitrate_kbps,
739 allocation.GetBitrate(1, 0) / 1000);
740
741 // Create a new allocation, where the second stream is no longer available.
742 VideoBitrateAllocation new_allocation;
743 new_allocation.SetBitrate(0, 0, 150000);
744 rtcp_sender_->SetVideoBitrateAllocation(new_allocation);
745 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
746 target_bitrate = parser()->xr()->target_bitrate();
747 ASSERT_TRUE(target_bitrate);
748 bitrates = target_bitrate->GetTargetBitrates();
749
750 // Two bitrates should still be set, with an explicit entry indicating the
751 // removed stream is gone.
752 ASSERT_EQ(2u, bitrates.size());
753 EXPECT_EQ(bitrates[0].target_bitrate_kbps,
754 new_allocation.GetBitrate(0, 0) / 1000);
755 EXPECT_EQ(bitrates[1].target_bitrate_kbps, 0u);
756}
757
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000758} // namespace webrtc