blob: 09cdff17a2284f2954c632a24bc2abaf53902a6a [file] [log] [blame]
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001/*
henrike@webrtc.orgd6d014f2012-02-16 02:18:09 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "modules/rtp_rtcp/source/rtcp_sender.h"
12
kwiberg84be5112016-04-27 01:19:58 -070013#include <memory>
14
Elad Alone86af2c2019-06-03 14:37:50 +020015#include "absl/base/macros.h"
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +020016#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
18#include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
Niels Möller1f3206c2018-09-14 08:26:32 +020019#include "modules/rtp_rtcp/source/rtp_packet_received.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "modules/rtp_rtcp/source/rtp_rtcp_impl.h"
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +020021#include "modules/rtp_rtcp/source/time_util.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "rtc_base/rate_limiter.h"
23#include "test/gmock.h"
24#include "test/gtest.h"
25#include "test/mock_transport.h"
26#include "test/rtcp_packet_parser.h"
asapersson22ff75a2015-08-21 00:02:47 -070027
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -080028using ::testing::_;
asapersson22ff75a2015-08-21 00:02:47 -070029using ::testing::ElementsAre;
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -080030using ::testing::Invoke;
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +020031using ::testing::SizeIs;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000032
33namespace webrtc {
34
asapersson22ff75a2015-08-21 00:02:47 -070035class RtcpPacketTypeCounterObserverImpl : public RtcpPacketTypeCounterObserver {
36 public:
37 RtcpPacketTypeCounterObserverImpl() : ssrc_(0) {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +000038 ~RtcpPacketTypeCounterObserverImpl() override = default;
asapersson22ff75a2015-08-21 00:02:47 -070039 void RtcpPacketTypesCounterUpdated(
40 uint32_t ssrc,
41 const RtcpPacketTypeCounter& packet_counter) override {
42 ssrc_ = ssrc;
43 counter_ = packet_counter;
44 }
45 uint32_t ssrc_;
46 RtcpPacketTypeCounter counter_;
47};
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000048
Niels Möller8fb57462018-11-13 10:08:33 +010049class TestTransport : public Transport {
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000050 public:
asapersson22ff75a2015-08-21 00:02:47 -070051 TestTransport() {}
52
stefan1d8a5062015-10-02 03:39:33 -070053 bool SendRtp(const uint8_t* /*data*/,
54 size_t /*len*/,
55 const PacketOptions& options) override {
pbos2d566682015-09-28 09:59:31 -070056 return false;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000057 }
pbos2d566682015-09-28 09:59:31 -070058 bool SendRtcp(const uint8_t* data, size_t len) override {
Danil Chapovalovba6f7be2016-09-02 18:29:10 +020059 parser_.Parse(data, len);
pbos2d566682015-09-28 09:59:31 -070060 return true;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000061 }
asapersson22ff75a2015-08-21 00:02:47 -070062 test::RtcpPacketParser parser_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000063};
64
Erik Språnga38233a2015-07-24 09:58:18 +020065namespace {
asapersson22ff75a2015-08-21 00:02:47 -070066static const uint32_t kSenderSsrc = 0x11111111;
67static const uint32_t kRemoteSsrc = 0x22222222;
Danil Chapovalov70ffead2016-07-20 15:26:59 +020068static const uint32_t kStartRtpTimestamp = 0x34567;
69static const uint32_t kRtpTimestamp = 0x45678;
Yves Gerey665174f2018-06-19 15:03:05 +020070} // namespace
Erik Språnga38233a2015-07-24 09:58:18 +020071
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000072class RtcpSenderTest : public ::testing::Test {
73 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +000074 RtcpSenderTest()
asapersson22ff75a2015-08-21 00:02:47 -070075 : clock_(1335900000),
Erik Språng737336d2016-07-29 12:59:36 +020076 receive_statistics_(ReceiveStatistics::Create(&clock_)),
77 retransmission_rate_limiter_(&clock_, 1000) {
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +000078 RtpRtcp::Configuration configuration = GetDefaultConfig();
79 rtp_rtcp_impl_.reset(new ModuleRtpRtcpImpl(configuration));
80 rtcp_sender_.reset(new RTCPSender(configuration));
81 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
82 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
83 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds(),
84 /*payload_type=*/0);
85 }
86
87 RtpRtcp::Configuration GetDefaultConfig() {
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000088 RtpRtcp::Configuration configuration;
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000089 configuration.audio = false;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +000090 configuration.clock = &clock_;
asapersson22ff75a2015-08-21 00:02:47 -070091 configuration.outgoing_transport = &test_transport_;
Erik Språng737336d2016-07-29 12:59:36 +020092 configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080093 configuration.rtcp_report_interval_ms = 1000;
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +000094 configuration.receive_statistics = receive_statistics_.get();
95 configuration.media_send_ssrc = kSenderSsrc;
96 return configuration;
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) {
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +0000193 RtpRtcp::Configuration config;
194 config.clock = &clock_;
195 config.receive_statistics = receive_statistics_.get();
196 config.outgoing_transport = &test_transport_;
197 config.rtcp_report_interval_ms = 1000;
198 config.media_send_ssrc = kSenderSsrc;
199 rtcp_sender_.reset(new RTCPSender(config));
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200200 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
201 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
202 rtcp_sender_->SetSendingStatus(feedback_state(), true);
203
204 // Sender Report shouldn't be send as an SR nor as a Report.
205 rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr);
206 EXPECT_EQ(0, parser()->sender_report()->num_packets());
207 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
208 EXPECT_EQ(0, parser()->sender_report()->num_packets());
209 // Other packets (e.g. Pli) are allowed, even if useless.
210 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
211 EXPECT_EQ(1, parser()->pli()->num_packets());
212}
213
214TEST_F(RtcpSenderTest, DoNotSendCompundBeforeRtp) {
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +0000215 RtpRtcp::Configuration config;
216 config.clock = &clock_;
217 config.receive_statistics = receive_statistics_.get();
218 config.outgoing_transport = &test_transport_;
219 config.rtcp_report_interval_ms = 1000;
220 config.media_send_ssrc = kSenderSsrc;
221 rtcp_sender_.reset(new RTCPSender(config));
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200222 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
223 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
224 rtcp_sender_->SetSendingStatus(feedback_state(), true);
225
226 // In compound mode no packets are allowed (e.g. Pli) because compound mode
227 // should start with Sender Report.
228 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
229 EXPECT_EQ(0, parser()->pli()->num_packets());
230}
231
asapersson22ff75a2015-08-21 00:02:47 -0700232TEST_F(RtcpSenderTest, SendRr) {
pbosda903ea2015-10-02 02:36:56 -0700233 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700234 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
235 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200236 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
237 EXPECT_EQ(0U, parser()->receiver_report()->report_blocks().size());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000238}
239
asapersson22ff75a2015-08-21 00:02:47 -0700240TEST_F(RtcpSenderTest, SendRrWithOneReportBlock) {
241 const uint16_t kSeqNum = 11111;
242 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
pbosda903ea2015-10-02 02:36:56 -0700243 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700244 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
245 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200246 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
247 ASSERT_EQ(1U, parser()->receiver_report()->report_blocks().size());
248 const rtcp::ReportBlock& rb = parser()->receiver_report()->report_blocks()[0];
249 EXPECT_EQ(kRemoteSsrc, rb.source_ssrc());
250 EXPECT_EQ(0U, rb.fraction_lost());
Harald Alvestrand70206d62017-12-08 08:59:07 +0100251 EXPECT_EQ(0, rb.cumulative_lost_signed());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200252 EXPECT_EQ(kSeqNum, rb.extended_high_seq_num());
asapersson22ff75a2015-08-21 00:02:47 -0700253}
254
255TEST_F(RtcpSenderTest, SendRrWithTwoReportBlocks) {
256 const uint16_t kSeqNum = 11111;
257 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
258 InsertIncomingPacket(kRemoteSsrc + 1, kSeqNum + 1);
pbosda903ea2015-10-02 02:36:56 -0700259 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700260 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
261 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200262 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
263 EXPECT_EQ(2U, parser()->receiver_report()->report_blocks().size());
264 EXPECT_EQ(kRemoteSsrc,
265 parser()->receiver_report()->report_blocks()[0].source_ssrc());
266 EXPECT_EQ(kRemoteSsrc + 1,
267 parser()->receiver_report()->report_blocks()[1].source_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700268}
269
270TEST_F(RtcpSenderTest, SendSdes) {
pbosda903ea2015-10-02 02:36:56 -0700271 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700272 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
273 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
274 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200275 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
276 EXPECT_EQ(kSenderSsrc, parser()->sdes()->chunks()[0].ssrc);
277 EXPECT_EQ("alice@host", parser()->sdes()->chunks()[0].cname);
asapersson22ff75a2015-08-21 00:02:47 -0700278}
279
danilchap74e8df8f2017-03-16 08:04:08 -0700280TEST_F(RtcpSenderTest, SendSdesWithMaxChunks) {
281 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
282 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
283 const char cname[] = "smith@host";
284 for (size_t i = 0; i < 30; ++i) {
285 const uint32_t csrc = 0x1234 + i;
286 EXPECT_EQ(0, rtcp_sender_->AddMixedCNAME(csrc, cname));
287 }
288 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
289 EXPECT_EQ(1, parser()->sdes()->num_packets());
290 EXPECT_EQ(31U, parser()->sdes()->chunks().size());
291}
292
asapersson22ff75a2015-08-21 00:02:47 -0700293TEST_F(RtcpSenderTest, SdesIncludedInCompoundPacket) {
pbosda903ea2015-10-02 02:36:56 -0700294 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700295 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
296 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
297 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
298 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200299 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
asapersson22ff75a2015-08-21 00:02:47 -0700300}
301
302TEST_F(RtcpSenderTest, SendBye) {
pbosda903ea2015-10-02 02:36:56 -0700303 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700304 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
305 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200306 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700307}
308
309TEST_F(RtcpSenderTest, StopSendingTriggersBye) {
pbosda903ea2015-10-02 02:36:56 -0700310 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700311 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
312 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
313 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200314 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700315}
316
317TEST_F(RtcpSenderTest, SendApp) {
318 const uint8_t kSubType = 30;
319 uint32_t name = 'n' << 24;
320 name += 'a' << 16;
321 name += 'm' << 8;
322 name += 'e';
323 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
asapersson22ff75a2015-08-21 00:02:47 -0700324 EXPECT_EQ(0, rtcp_sender_->SetApplicationSpecificData(kSubType, name, kData,
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200325 sizeof(kData)));
pbosda903ea2015-10-02 02:36:56 -0700326 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700327 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
328 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200329 EXPECT_EQ(kSubType, parser()->app()->sub_type());
330 EXPECT_EQ(name, parser()->app()->name());
331 EXPECT_EQ(sizeof(kData), parser()->app()->data_size());
332 EXPECT_EQ(0, memcmp(kData, parser()->app()->data(), sizeof(kData)));
asapersson22ff75a2015-08-21 00:02:47 -0700333}
334
Erik Språng521875a2015-09-01 10:11:16 +0200335TEST_F(RtcpSenderTest, SendEmptyApp) {
336 const uint8_t kSubType = 30;
337 const uint32_t kName = 0x6E616D65;
338
339 EXPECT_EQ(
340 0, rtcp_sender_->SetApplicationSpecificData(kSubType, kName, nullptr, 0));
341
pbosda903ea2015-10-02 02:36:56 -0700342 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Erik Språng521875a2015-09-01 10:11:16 +0200343 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
344 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200345 EXPECT_EQ(kSubType, parser()->app()->sub_type());
346 EXPECT_EQ(kName, parser()->app()->name());
347 EXPECT_EQ(0U, parser()->app()->data_size());
Erik Språng521875a2015-09-01 10:11:16 +0200348}
349
asapersson22ff75a2015-08-21 00:02:47 -0700350TEST_F(RtcpSenderTest, SetInvalidApplicationSpecificData) {
351 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't'};
352 const uint16_t kInvalidDataLength = sizeof(kData) / sizeof(kData[0]);
Yves Gerey665174f2018-06-19 15:03:05 +0200353 EXPECT_EQ(-1,
354 rtcp_sender_->SetApplicationSpecificData(
355 0, 0, kData, kInvalidDataLength)); // Should by multiple of 4.
asapersson22ff75a2015-08-21 00:02:47 -0700356}
357
danilchap498ee8e2017-02-08 05:24:31 -0800358TEST_F(RtcpSenderTest, SendFir) {
pbosda903ea2015-10-02 02:36:56 -0700359 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700360 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
361 EXPECT_EQ(1, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200362 EXPECT_EQ(kSenderSsrc, parser()->fir()->sender_ssrc());
363 EXPECT_EQ(1U, parser()->fir()->requests().size());
364 EXPECT_EQ(kRemoteSsrc, parser()->fir()->requests()[0].ssrc);
365 uint8_t seq = parser()->fir()->requests()[0].seq_nr;
asapersson22ff75a2015-08-21 00:02:47 -0700366 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
367 EXPECT_EQ(2, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200368 EXPECT_EQ(seq + 1, parser()->fir()->requests()[0].seq_nr);
asapersson22ff75a2015-08-21 00:02:47 -0700369}
370
asapersson22ff75a2015-08-21 00:02:47 -0700371TEST_F(RtcpSenderTest, SendPli) {
pbosda903ea2015-10-02 02:36:56 -0700372 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700373 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
374 EXPECT_EQ(1, parser()->pli()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200375 EXPECT_EQ(kSenderSsrc, parser()->pli()->sender_ssrc());
376 EXPECT_EQ(kRemoteSsrc, parser()->pli()->media_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700377}
378
asapersson22ff75a2015-08-21 00:02:47 -0700379TEST_F(RtcpSenderTest, SendNack) {
pbosda903ea2015-10-02 02:36:56 -0700380 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700381 const uint16_t kList[] = {0, 1, 16};
Elad Alone86af2c2019-06-03 14:37:50 +0200382 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpNack,
383 ABSL_ARRAYSIZE(kList), kList));
asapersson22ff75a2015-08-21 00:02:47 -0700384 EXPECT_EQ(1, parser()->nack()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200385 EXPECT_EQ(kSenderSsrc, parser()->nack()->sender_ssrc());
386 EXPECT_EQ(kRemoteSsrc, parser()->nack()->media_ssrc());
387 EXPECT_THAT(parser()->nack()->packet_ids(), ElementsAre(0, 1, 16));
asapersson22ff75a2015-08-21 00:02:47 -0700388}
389
Elad Alone86af2c2019-06-03 14:37:50 +0200390TEST_F(RtcpSenderTest, SendLossNotificationBufferingNotAllowed) {
Elad Alon7d6a4c02019-02-25 13:00:51 +0100391 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
392 constexpr uint16_t kLastDecoded = 0x1234;
393 constexpr uint16_t kLastReceived = 0x4321;
394 constexpr bool kDecodabilityFlag = true;
Elad Alone86af2c2019-06-03 14:37:50 +0200395 constexpr bool kBufferingAllowed = false;
396 EXPECT_EQ(rtcp_sender_->SendLossNotification(feedback_state(), kLastDecoded,
397 kLastReceived, kDecodabilityFlag,
398 kBufferingAllowed),
399 0);
400 EXPECT_EQ(parser()->processed_rtcp_packets(), 1u);
401 EXPECT_EQ(parser()->loss_notification()->num_packets(), 1);
Elad Alon7d6a4c02019-02-25 13:00:51 +0100402 EXPECT_EQ(kSenderSsrc, parser()->loss_notification()->sender_ssrc());
403 EXPECT_EQ(kRemoteSsrc, parser()->loss_notification()->media_ssrc());
404}
405
Elad Alone86af2c2019-06-03 14:37:50 +0200406TEST_F(RtcpSenderTest, SendLossNotificationBufferingAllowed) {
407 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
408 constexpr uint16_t kLastDecoded = 0x1234;
409 constexpr uint16_t kLastReceived = 0x4321;
410 constexpr bool kDecodabilityFlag = true;
411 constexpr bool kBufferingAllowed = true;
412 EXPECT_EQ(rtcp_sender_->SendLossNotification(feedback_state(), kLastDecoded,
413 kLastReceived, kDecodabilityFlag,
414 kBufferingAllowed),
415 0);
416
417 // No RTCP messages sent yet.
418 ASSERT_EQ(parser()->processed_rtcp_packets(), 0u);
419
420 // Sending another messages triggers sending the LNTF messages as well.
421 const uint16_t kList[] = {0, 1, 16};
422 EXPECT_EQ(rtcp_sender_->SendRTCP(feedback_state(), kRtcpNack,
423 ABSL_ARRAYSIZE(kList), kList),
424 0);
425
426 // Exactly one packet was produced, and it contained both the buffered LNTF
427 // as well as the message that had triggered the packet.
428 EXPECT_EQ(parser()->processed_rtcp_packets(), 1u);
429 EXPECT_EQ(parser()->loss_notification()->num_packets(), 1);
430 EXPECT_EQ(parser()->loss_notification()->sender_ssrc(), kSenderSsrc);
431 EXPECT_EQ(parser()->loss_notification()->media_ssrc(), kRemoteSsrc);
432 EXPECT_EQ(parser()->nack()->num_packets(), 1);
433 EXPECT_EQ(parser()->nack()->sender_ssrc(), kSenderSsrc);
434 EXPECT_EQ(parser()->nack()->media_ssrc(), kRemoteSsrc);
435}
436
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200437TEST_F(RtcpSenderTest, RembNotIncludedBeforeSet) {
438 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
439
440 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
441
442 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
443 EXPECT_EQ(0, parser()->remb()->num_packets());
444}
445
446TEST_F(RtcpSenderTest, RembNotIncludedAfterUnset) {
danilchapba6aa902017-04-18 06:57:02 -0700447 const uint64_t kBitrate = 261011;
448 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
449 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200450 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
danilchapba6aa902017-04-18 06:57:02 -0700451 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
452 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200453 EXPECT_EQ(1, parser()->remb()->num_packets());
danilchapba6aa902017-04-18 06:57:02 -0700454
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200455 // Turn off REMB. rtcp_sender no longer should send it.
456 rtcp_sender_->UnsetRemb();
danilchapba6aa902017-04-18 06:57:02 -0700457 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
458 ASSERT_EQ(2, parser()->receiver_report()->num_packets());
459 EXPECT_EQ(1, parser()->remb()->num_packets());
Danil Chapovalov857a8fb2016-09-06 11:41:46 +0200460}
461
asapersson22ff75a2015-08-21 00:02:47 -0700462TEST_F(RtcpSenderTest, SendRemb) {
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200463 const uint64_t kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200464 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700465 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200466 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
467
468 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRemb);
469
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200470 EXPECT_EQ(1, parser()->remb()->num_packets());
471 EXPECT_EQ(kSenderSsrc, parser()->remb()->sender_ssrc());
472 EXPECT_EQ(kBitrate, parser()->remb()->bitrate_bps());
473 EXPECT_THAT(parser()->remb()->ssrcs(),
asapersson22ff75a2015-08-21 00:02:47 -0700474 ElementsAre(kRemoteSsrc, kRemoteSsrc + 1));
475}
476
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200477TEST_F(RtcpSenderTest, RembIncludedInEachCompoundPacketAfterSet) {
asapersson22ff75a2015-08-21 00:02:47 -0700478 const int kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200479 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700480 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200481 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
482
483 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200484 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700485 // REMB should be included in each compound packet.
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200486 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200487 EXPECT_EQ(2, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700488}
489
asapersson22ff75a2015-08-21 00:02:47 -0700490TEST_F(RtcpSenderTest, SendXrWithDlrr) {
pbosda903ea2015-10-02 02:36:56 -0700491 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000492 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
danilchap798896a2016-09-28 02:54:25 -0700493 rtcp::ReceiveTimeInfo last_xr_rr;
494 last_xr_rr.ssrc = 0x11111111;
495 last_xr_rr.last_rr = 0x22222222;
496 last_xr_rr.delay_since_last_rr = 0x33333333;
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200497 feedback_state.last_xr_rtis.push_back(last_xr_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000498 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200499 EXPECT_EQ(1, parser()->xr()->num_packets());
500 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200501 ASSERT_THAT(parser()->xr()->dlrr().sub_blocks(), SizeIs(1));
danilchap80ac24d2016-10-31 08:40:47 -0700502 EXPECT_EQ(last_xr_rr.ssrc, parser()->xr()->dlrr().sub_blocks()[0].ssrc);
503 EXPECT_EQ(last_xr_rr.last_rr, parser()->xr()->dlrr().sub_blocks()[0].last_rr);
danilchap798896a2016-09-28 02:54:25 -0700504 EXPECT_EQ(last_xr_rr.delay_since_last_rr,
danilchap80ac24d2016-10-31 08:40:47 -0700505 parser()->xr()->dlrr().sub_blocks()[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000506}
507
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200508TEST_F(RtcpSenderTest, SendXrWithMultipleDlrrSubBlocks) {
509 const size_t kNumReceivers = 2;
510 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
511 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
512 for (size_t i = 0; i < kNumReceivers; ++i) {
513 rtcp::ReceiveTimeInfo last_xr_rr;
514 last_xr_rr.ssrc = i;
515 last_xr_rr.last_rr = (i + 1) * 100;
516 last_xr_rr.delay_since_last_rr = (i + 2) * 200;
517 feedback_state.last_xr_rtis.push_back(last_xr_rr);
518 }
519
520 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
521 EXPECT_EQ(1, parser()->xr()->num_packets());
522 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
523 ASSERT_THAT(parser()->xr()->dlrr().sub_blocks(), SizeIs(kNumReceivers));
524 for (size_t i = 0; i < kNumReceivers; ++i) {
525 EXPECT_EQ(feedback_state.last_xr_rtis[i].ssrc,
526 parser()->xr()->dlrr().sub_blocks()[i].ssrc);
527 EXPECT_EQ(feedback_state.last_xr_rtis[i].last_rr,
528 parser()->xr()->dlrr().sub_blocks()[i].last_rr);
529 EXPECT_EQ(feedback_state.last_xr_rtis[i].delay_since_last_rr,
530 parser()->xr()->dlrr().sub_blocks()[i].delay_since_last_rr);
531 }
532}
533
asapersson22ff75a2015-08-21 00:02:47 -0700534TEST_F(RtcpSenderTest, SendXrWithRrtr) {
pbosda903ea2015-10-02 02:36:56 -0700535 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700536 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000537 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200538 NtpTime ntp = TimeMicrosToNtp(clock_.TimeInMicroseconds());
asapersson22ff75a2015-08-21 00:02:47 -0700539 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200540 EXPECT_EQ(1, parser()->xr()->num_packets());
541 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
danilchap80ac24d2016-10-31 08:40:47 -0700542 EXPECT_FALSE(parser()->xr()->dlrr());
danilchap80ac24d2016-10-31 08:40:47 -0700543 ASSERT_TRUE(parser()->xr()->rrtr());
danilchap21dc1892017-03-07 02:51:09 -0800544 EXPECT_EQ(ntp, parser()->xr()->rrtr()->ntp());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000545}
546
asapersson22ff75a2015-08-21 00:02:47 -0700547TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfSending) {
pbosda903ea2015-10-02 02:36:56 -0700548 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700549 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
550 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
551 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200552 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700553}
554
555TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfNotEnabled) {
pbosda903ea2015-10-02 02:36:56 -0700556 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700557 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000558 rtcp_sender_->SendRtcpXrReceiverReferenceTime(false);
asapersson22ff75a2015-08-21 00:02:47 -0700559 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200560 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000561}
562
asapersson22ff75a2015-08-21 00:02:47 -0700563TEST_F(RtcpSenderTest, TestRegisterRtcpPacketTypeObserver) {
564 RtcpPacketTypeCounterObserverImpl observer;
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +0000565 RtpRtcp::Configuration config;
566 config.clock = &clock_;
567 config.receive_statistics = receive_statistics_.get();
568 config.outgoing_transport = &test_transport_;
569 config.rtcp_packet_type_counter_observer = &observer;
570 config.rtcp_report_interval_ms = 1000;
571 rtcp_sender_.reset(new RTCPSender(config));
572
asapersson22ff75a2015-08-21 00:02:47 -0700573 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700574 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700575 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
576 EXPECT_EQ(1, parser()->pli()->num_packets());
577 EXPECT_EQ(kRemoteSsrc, observer.ssrc_);
578 EXPECT_EQ(1U, observer.counter_.pli_packets);
579 EXPECT_EQ(clock_.TimeInMilliseconds(),
580 observer.counter_.first_packet_time_ms);
581}
582
583TEST_F(RtcpSenderTest, SendTmmbr) {
584 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700585 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700586 rtcp_sender_->SetTargetBitrate(kBitrateBps);
587 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpTmmbr));
588 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200589 EXPECT_EQ(kSenderSsrc, parser()->tmmbr()->sender_ssrc());
590 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
591 EXPECT_EQ(kBitrateBps, parser()->tmmbr()->requests()[0].bitrate_bps());
asapersson22ff75a2015-08-21 00:02:47 -0700592 // TODO(asapersson): tmmbr_item()->Overhead() looks broken, always zero.
593}
594
595TEST_F(RtcpSenderTest, TmmbrIncludedInCompoundPacketIfEnabled) {
596 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700597 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700598 EXPECT_FALSE(rtcp_sender_->TMMBR());
599 rtcp_sender_->SetTMMBRStatus(true);
600 EXPECT_TRUE(rtcp_sender_->TMMBR());
601 rtcp_sender_->SetTargetBitrate(kBitrateBps);
602 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
603 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200604 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
asapersson22ff75a2015-08-21 00:02:47 -0700605 // TMMBR should be included in each compound packet.
606 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
607 EXPECT_EQ(2, parser()->tmmbr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700608
609 rtcp_sender_->SetTMMBRStatus(false);
610 EXPECT_FALSE(rtcp_sender_->TMMBR());
611}
612
613TEST_F(RtcpSenderTest, SendTmmbn) {
pbosda903ea2015-10-02 02:36:56 -0700614 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200615 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700616 std::vector<rtcp::TmmbItem> bounding_set;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200617 const uint32_t kBitrateBps = 32768000;
asapersson22ff75a2015-08-21 00:02:47 -0700618 const uint32_t kPacketOh = 40;
619 const uint32_t kSourceSsrc = 12345;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200620 const rtcp::TmmbItem tmmbn(kSourceSsrc, kBitrateBps, kPacketOh);
danilchap6eaa3a42016-05-09 10:59:50 -0700621 bounding_set.push_back(tmmbn);
danilchap853ecb22016-08-22 08:26:15 -0700622 rtcp_sender_->SetTmmbn(bounding_set);
danilchap6eaa3a42016-05-09 10:59:50 -0700623
asapersson22ff75a2015-08-21 00:02:47 -0700624 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
625 EXPECT_EQ(1, parser()->sender_report()->num_packets());
626 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200627 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
628 EXPECT_EQ(1U, parser()->tmmbn()->items().size());
629 EXPECT_EQ(kBitrateBps, parser()->tmmbn()->items()[0].bitrate_bps());
630 EXPECT_EQ(kPacketOh, parser()->tmmbn()->items()[0].packet_overhead());
631 EXPECT_EQ(kSourceSsrc, parser()->tmmbn()->items()[0].ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700632}
633
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000634// This test is written to verify actual behaviour. It does not seem
635// to make much sense to send an empty TMMBN, since there is no place
636// to put an actual limit here. It's just information that no limit
637// is set, which is kind of the starting assumption.
638// See http://code.google.com/p/webrtc/issues/detail?id=468 for one
639// situation where this caused confusion.
640TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndEmpty) {
pbosda903ea2015-10-02 02:36:56 -0700641 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200642 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700643 std::vector<rtcp::TmmbItem> bounding_set;
danilchap853ecb22016-08-22 08:26:15 -0700644 rtcp_sender_->SetTmmbn(bounding_set);
asapersson22ff75a2015-08-21 00:02:47 -0700645 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
646 EXPECT_EQ(1, parser()->sender_report()->num_packets());
647 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200648 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
649 EXPECT_EQ(0U, parser()->tmmbn()->items().size());
hta@webrtc.org65a4e4e2012-04-30 11:23:41 +0000650}
651
asapersson22ff75a2015-08-21 00:02:47 -0700652TEST_F(RtcpSenderTest, SendCompoundPliRemb) {
653 const int kBitrate = 261011;
654 std::vector<uint32_t> ssrcs;
655 ssrcs.push_back(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700656 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200657 rtcp_sender_->SetRemb(kBitrate, ssrcs);
asapersson22ff75a2015-08-21 00:02:47 -0700658 std::set<RTCPPacketType> packet_types;
659 packet_types.insert(kRtcpRemb);
660 packet_types.insert(kRtcpPli);
661 EXPECT_EQ(0, rtcp_sender_->SendCompoundRTCP(feedback_state(), packet_types));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200662 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700663 EXPECT_EQ(1, parser()->pli()->num_packets());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000664}
Erik Språnga38233a2015-07-24 09:58:18 +0200665
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800666// This test is written to verify that BYE is always the last packet
667// type in a RTCP compoud packet. The rtcp_sender_ is recreated with
668// mock_transport, which is used to check for whether BYE at the end
669// of a RTCP compound packet.
670TEST_F(RtcpSenderTest, ByeMustBeLast) {
671 MockTransport mock_transport;
672 EXPECT_CALL(mock_transport, SendRtcp(_, _))
Yves Gerey665174f2018-06-19 15:03:05 +0200673 .WillOnce(Invoke([](const uint8_t* data, size_t len) {
674 const uint8_t* next_packet = data;
675 const uint8_t* const packet_end = data + len;
676 rtcp::CommonHeader packet;
677 while (next_packet < packet_end) {
678 EXPECT_TRUE(packet.Parse(next_packet, packet_end - next_packet));
679 next_packet = packet.NextPacket();
680 if (packet.type() ==
681 rtcp::Bye::kPacketType) // Main test expectation.
682 EXPECT_EQ(0, packet_end - next_packet)
683 << "Bye packet should be last in a compound RTCP packet.";
684 if (next_packet == packet_end) // Validate test was set correctly.
685 EXPECT_EQ(packet.type(), rtcp::Bye::kPacketType)
686 << "Last packet in this test expected to be Bye.";
687 }
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800688
Yves Gerey665174f2018-06-19 15:03:05 +0200689 return true;
690 }));
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800691
692 // Re-configure rtcp_sender_ with mock_transport_
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +0000693 RtpRtcp::Configuration config;
694 config.clock = &clock_;
695 config.receive_statistics = receive_statistics_.get();
696 config.outgoing_transport = &mock_transport;
697 config.rtcp_report_interval_ms = 1000;
698 config.media_send_ssrc = kSenderSsrc;
699 rtcp_sender_.reset(new RTCPSender(config));
700
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800701 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
danilchap71fead22016-08-18 02:01:49 -0700702 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
Ilya Nikolaevskiy5e58bcb2018-10-24 13:34:32 +0200703 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds(),
Mirko Bonadei970f2f72019-02-28 14:57:52 +0100704 /*payload_type=*/0);
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800705
Niels Möller44b384d2018-10-05 11:15:57 +0200706 // Set up REMB info to be included with BYE.
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800707 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Niels Möller44b384d2018-10-05 11:15:57 +0200708 rtcp_sender_->SetRemb(1234, {});
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800709 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
710}
711
sprang5e38c962016-12-01 05:18:09 -0800712TEST_F(RtcpSenderTest, SendXrWithTargetBitrate) {
713 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
714 const size_t kNumSpatialLayers = 2;
715 const size_t kNumTemporalLayers = 2;
Erik Språng566124a2018-04-23 12:32:22 +0200716 VideoBitrateAllocation allocation;
sprang5e38c962016-12-01 05:18:09 -0800717 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
718 uint32_t start_bitrate_bps = (sl + 1) * 100000;
719 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl)
720 allocation.SetBitrate(sl, tl, start_bitrate_bps + (tl * 20000));
721 }
722 rtcp_sender_->SetVideoBitrateAllocation(allocation);
723
724 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
725 EXPECT_EQ(1, parser()->xr()->num_packets());
726 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
Danil Chapovalovd264df52018-06-14 12:59:38 +0200727 const absl::optional<rtcp::TargetBitrate>& target_bitrate =
sprang5e38c962016-12-01 05:18:09 -0800728 parser()->xr()->target_bitrate();
729 ASSERT_TRUE(target_bitrate);
730 const std::vector<rtcp::TargetBitrate::BitrateItem>& bitrates =
731 target_bitrate->GetTargetBitrates();
732 EXPECT_EQ(kNumSpatialLayers * kNumTemporalLayers, bitrates.size());
733
734 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
735 uint32_t start_bitrate_bps = (sl + 1) * 100000;
736 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl) {
737 size_t index = (sl * kNumSpatialLayers) + tl;
738 const rtcp::TargetBitrate::BitrateItem& item = bitrates[index];
739 EXPECT_EQ(sl, item.spatial_layer);
740 EXPECT_EQ(tl, item.temporal_layer);
741 EXPECT_EQ(start_bitrate_bps + (tl * 20000),
742 item.target_bitrate_kbps * 1000);
743 }
744 }
745}
746
Erik Språng8782a582018-10-04 15:36:06 +0200747TEST_F(RtcpSenderTest, SendImmediateXrWithTargetBitrate) {
748 // Initialize. Send a first report right away.
749 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
750 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
751 clock_.AdvanceTimeMilliseconds(5);
752
753 // Video bitrate allocation generated, save until next time we send a report.
754 VideoBitrateAllocation allocation;
755 allocation.SetBitrate(0, 0, 100000);
756 rtcp_sender_->SetVideoBitrateAllocation(allocation);
757 // First seen instance will be sent immediately.
758 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
759 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
760 clock_.AdvanceTimeMilliseconds(5);
761
762 // Update bitrate of existing layer, does not quality for immediate sending.
763 allocation.SetBitrate(0, 0, 150000);
764 rtcp_sender_->SetVideoBitrateAllocation(allocation);
765 EXPECT_FALSE(rtcp_sender_->TimeToSendRTCPReport(false));
766
767 // A new spatial layer enabled, signal this as soon as possible.
768 allocation.SetBitrate(1, 0, 200000);
769 rtcp_sender_->SetVideoBitrateAllocation(allocation);
770 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
771 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
772 clock_.AdvanceTimeMilliseconds(5);
773
774 // Explicitly disable top layer. The same set of layers now has a bitrate
775 // defined, but the explicit 0 indicates shutdown. Signal immediately.
776 allocation.SetBitrate(1, 0, 0);
777 EXPECT_FALSE(rtcp_sender_->TimeToSendRTCPReport(false));
778 rtcp_sender_->SetVideoBitrateAllocation(allocation);
779 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
780}
781
Erik Språng1cd73912018-10-05 12:57:59 +0200782TEST_F(RtcpSenderTest, SendTargetBitrateExplicitZeroOnStreamRemoval) {
783 // Set up and send a bitrate allocation with two layers.
784
785 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
786 VideoBitrateAllocation allocation;
787 allocation.SetBitrate(0, 0, 100000);
788 allocation.SetBitrate(1, 0, 200000);
789 rtcp_sender_->SetVideoBitrateAllocation(allocation);
790 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
791 absl::optional<rtcp::TargetBitrate> target_bitrate =
792 parser()->xr()->target_bitrate();
793 ASSERT_TRUE(target_bitrate);
794 std::vector<rtcp::TargetBitrate::BitrateItem> bitrates =
795 target_bitrate->GetTargetBitrates();
796 ASSERT_EQ(2u, bitrates.size());
797 EXPECT_EQ(bitrates[0].target_bitrate_kbps,
798 allocation.GetBitrate(0, 0) / 1000);
799 EXPECT_EQ(bitrates[1].target_bitrate_kbps,
800 allocation.GetBitrate(1, 0) / 1000);
801
802 // Create a new allocation, where the second stream is no longer available.
803 VideoBitrateAllocation new_allocation;
804 new_allocation.SetBitrate(0, 0, 150000);
805 rtcp_sender_->SetVideoBitrateAllocation(new_allocation);
806 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
807 target_bitrate = parser()->xr()->target_bitrate();
808 ASSERT_TRUE(target_bitrate);
809 bitrates = target_bitrate->GetTargetBitrates();
810
811 // Two bitrates should still be set, with an explicit entry indicating the
812 // removed stream is gone.
813 ASSERT_EQ(2u, bitrates.size());
814 EXPECT_EQ(bitrates[0].target_bitrate_kbps,
815 new_allocation.GetBitrate(0, 0) / 1000);
816 EXPECT_EQ(bitrates[1].target_bitrate_kbps, 0u);
817}
818
Mirko Bonadei9b1f24d2019-07-12 17:32:28 +0000819TEST_F(RtcpSenderTest, DoesntSchedulesInitialReportWhenSsrcSetOnConstruction) {
820 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
821 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
822 // New report should not have been scheduled yet.
823 clock_.AdvanceTimeMilliseconds(100);
824 EXPECT_FALSE(rtcp_sender_->TimeToSendRTCPReport(false));
825}
826
827TEST_F(RtcpSenderTest, DoesntSchedulesInitialReportOnFirstSetSsrc) {
828 // Set up without first SSRC not set at construction.
829 RtpRtcp::Configuration configuration = GetDefaultConfig();
830 configuration.media_send_ssrc = absl::nullopt;
831
832 rtcp_sender_.reset(new RTCPSender(configuration));
833 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
834 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
835 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds(),
836 /*payload_type=*/0);
837 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
838
839 // Set SSRC for the first time. New report should not be scheduled.
840 rtcp_sender_->SetSSRC(kSenderSsrc);
841 clock_.AdvanceTimeMilliseconds(100);
842 EXPECT_FALSE(rtcp_sender_->TimeToSendRTCPReport(false));
843}
844
845TEST_F(RtcpSenderTest, SchedulesReportOnSsrcChange) {
846 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
847 rtcp_sender_->SetSSRC(kSenderSsrc + 1);
848 clock_.AdvanceTimeMilliseconds(100);
849 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
850}
851
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000852} // namespace webrtc