blob: b6b3c34f515c0851e629b3a7f5568d86065e16e7 [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
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +020013#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
15#include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
16#include "modules/rtp_rtcp/source/rtcp_sender.h"
Niels Möller1f3206c2018-09-14 08:26:32 +020017#include "modules/rtp_rtcp/source/rtp_packet_received.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "modules/rtp_rtcp/source/rtp_rtcp_impl.h"
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +020019#include "modules/rtp_rtcp/source/time_util.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "rtc_base/rate_limiter.h"
21#include "test/gmock.h"
22#include "test/gtest.h"
23#include "test/mock_transport.h"
24#include "test/rtcp_packet_parser.h"
asapersson22ff75a2015-08-21 00:02:47 -070025
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -080026using ::testing::_;
asapersson22ff75a2015-08-21 00:02:47 -070027using ::testing::ElementsAre;
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -080028using ::testing::Invoke;
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +020029using ::testing::SizeIs;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000030
31namespace webrtc {
32
asapersson22ff75a2015-08-21 00:02:47 -070033class RtcpPacketTypeCounterObserverImpl : public RtcpPacketTypeCounterObserver {
34 public:
35 RtcpPacketTypeCounterObserverImpl() : ssrc_(0) {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +000036 ~RtcpPacketTypeCounterObserverImpl() override = default;
asapersson22ff75a2015-08-21 00:02:47 -070037 void RtcpPacketTypesCounterUpdated(
38 uint32_t ssrc,
39 const RtcpPacketTypeCounter& packet_counter) override {
40 ssrc_ = ssrc;
41 counter_ = packet_counter;
42 }
43 uint32_t ssrc_;
44 RtcpPacketTypeCounter counter_;
45};
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000046
Niels Möller8fb57462018-11-13 10:08:33 +010047class TestTransport : public Transport {
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000048 public:
asapersson22ff75a2015-08-21 00:02:47 -070049 TestTransport() {}
50
stefan1d8a5062015-10-02 03:39:33 -070051 bool SendRtp(const uint8_t* /*data*/,
52 size_t /*len*/,
53 const PacketOptions& options) override {
pbos2d566682015-09-28 09:59:31 -070054 return false;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000055 }
pbos2d566682015-09-28 09:59:31 -070056 bool SendRtcp(const uint8_t* data, size_t len) override {
Danil Chapovalovba6f7be2016-09-02 18:29:10 +020057 parser_.Parse(data, len);
pbos2d566682015-09-28 09:59:31 -070058 return true;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000059 }
asapersson22ff75a2015-08-21 00:02:47 -070060 test::RtcpPacketParser parser_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000061};
62
Erik Språnga38233a2015-07-24 09:58:18 +020063namespace {
asapersson22ff75a2015-08-21 00:02:47 -070064static const uint32_t kSenderSsrc = 0x11111111;
65static const uint32_t kRemoteSsrc = 0x22222222;
Danil Chapovalov70ffead2016-07-20 15:26:59 +020066static const uint32_t kStartRtpTimestamp = 0x34567;
67static const uint32_t kRtpTimestamp = 0x45678;
Yves Gerey665174f2018-06-19 15:03:05 +020068} // namespace
Erik Språnga38233a2015-07-24 09:58:18 +020069
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000070class RtcpSenderTest : public ::testing::Test {
71 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +000072 RtcpSenderTest()
asapersson22ff75a2015-08-21 00:02:47 -070073 : clock_(1335900000),
Erik Språng737336d2016-07-29 12:59:36 +020074 receive_statistics_(ReceiveStatistics::Create(&clock_)),
75 retransmission_rate_limiter_(&clock_, 1000) {
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000076 RtpRtcp::Configuration configuration;
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000077 configuration.audio = false;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +000078 configuration.clock = &clock_;
asapersson22ff75a2015-08-21 00:02:47 -070079 configuration.outgoing_transport = &test_transport_;
Erik Språng737336d2016-07-29 12:59:36 +020080 configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080081 configuration.rtcp_report_interval_ms = 1000;
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000082
asapersson22ff75a2015-08-21 00:02:47 -070083 rtp_rtcp_impl_.reset(new ModuleRtpRtcpImpl(configuration));
sprang86fd9ed2015-09-29 04:45:43 -070084 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -080085 nullptr, nullptr, &test_transport_,
Jiawei Ou8b5d9d82018-11-15 16:44:37 -080086 configuration.rtcp_report_interval_ms));
asapersson22ff75a2015-08-21 00:02:47 -070087 rtcp_sender_->SetSSRC(kSenderSsrc);
88 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
danilchap71fead22016-08-18 02:01:49 -070089 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
Ilya Nikolaevskiy5e58bcb2018-10-24 13:34:32 +020090 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds(),
Mirko Bonadei970f2f72019-02-28 14:57:52 +010091 /*payload_type=*/0);
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000092 }
Erik Språnga38233a2015-07-24 09:58:18 +020093
asapersson22ff75a2015-08-21 00:02:47 -070094 void InsertIncomingPacket(uint32_t remote_ssrc, uint16_t seq_num) {
Niels Möller1f3206c2018-09-14 08:26:32 +020095 RtpPacketReceived packet;
96 packet.SetSsrc(remote_ssrc);
97 packet.SetSequenceNumber(seq_num);
98 packet.SetTimestamp(12345);
99 packet.SetPayloadSize(100 - 12);
100 receive_statistics_->OnRtpPacket(packet);
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000101 }
102
asapersson22ff75a2015-08-21 00:02:47 -0700103 test::RtcpPacketParser* parser() { return &test_transport_.parser_; }
104
105 RTCPSender::FeedbackState feedback_state() {
106 return rtp_rtcp_impl_->GetFeedbackState();
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000107 }
108
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000109 SimulatedClock clock_;
asapersson22ff75a2015-08-21 00:02:47 -0700110 TestTransport test_transport_;
kwiberg84be5112016-04-27 01:19:58 -0700111 std::unique_ptr<ReceiveStatistics> receive_statistics_;
112 std::unique_ptr<ModuleRtpRtcpImpl> rtp_rtcp_impl_;
113 std::unique_ptr<RTCPSender> rtcp_sender_;
Erik Språng737336d2016-07-29 12:59:36 +0200114 RateLimiter retransmission_rate_limiter_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000115};
116
asapersson22ff75a2015-08-21 00:02:47 -0700117TEST_F(RtcpSenderTest, SetRtcpStatus) {
pbosda903ea2015-10-02 02:36:56 -0700118 EXPECT_EQ(RtcpMode::kOff, rtcp_sender_->Status());
119 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
120 EXPECT_EQ(RtcpMode::kReducedSize, rtcp_sender_->Status());
asapersson22ff75a2015-08-21 00:02:47 -0700121}
122
123TEST_F(RtcpSenderTest, SetSendingStatus) {
124 EXPECT_FALSE(rtcp_sender_->Sending());
125 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
126 EXPECT_TRUE(rtcp_sender_->Sending());
127}
128
129TEST_F(RtcpSenderTest, NoPacketSentIfOff) {
pbosda903ea2015-10-02 02:36:56 -0700130 rtcp_sender_->SetRTCPStatus(RtcpMode::kOff);
asapersson22ff75a2015-08-21 00:02:47 -0700131 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000132}
133
asapersson22ff75a2015-08-21 00:02:47 -0700134TEST_F(RtcpSenderTest, SendSr) {
135 const uint32_t kPacketCount = 0x12345;
136 const uint32_t kOctetCount = 0x23456;
pbosda903ea2015-10-02 02:36:56 -0700137 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000138 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200139 rtcp_sender_->SetSendingStatus(feedback_state, true);
asapersson22ff75a2015-08-21 00:02:47 -0700140 feedback_state.packets_sent = kPacketCount;
141 feedback_state.media_bytes_sent = kOctetCount;
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200142 NtpTime ntp = TimeMicrosToNtp(clock_.TimeInMicroseconds());
asapersson22ff75a2015-08-21 00:02:47 -0700143 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
144 EXPECT_EQ(1, parser()->sender_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200145 EXPECT_EQ(kSenderSsrc, parser()->sender_report()->sender_ssrc());
danilchap21dc1892017-03-07 02:51:09 -0800146 EXPECT_EQ(ntp, parser()->sender_report()->ntp());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200147 EXPECT_EQ(kPacketCount, parser()->sender_report()->sender_packet_count());
148 EXPECT_EQ(kOctetCount, parser()->sender_report()->sender_octet_count());
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200149 EXPECT_EQ(kStartRtpTimestamp + kRtpTimestamp,
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200150 parser()->sender_report()->rtp_timestamp());
151 EXPECT_EQ(0U, parser()->sender_report()->report_blocks().size());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000152}
153
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200154TEST_F(RtcpSenderTest, SendConsecutiveSrWithExactSlope) {
155 const uint32_t kPacketCount = 0x12345;
156 const uint32_t kOctetCount = 0x23456;
157 const int kTimeBetweenSRsUs = 10043; // Not exact value in milliseconds.
158 const int kExtraPackets = 30;
159 // Make sure clock is not exactly at some milliseconds point.
160 clock_.AdvanceTimeMicroseconds(kTimeBetweenSRsUs);
161 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
162 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
163 rtcp_sender_->SetSendingStatus(feedback_state, true);
164 feedback_state.packets_sent = kPacketCount;
165 feedback_state.media_bytes_sent = kOctetCount;
166
167 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
168 EXPECT_EQ(1, parser()->sender_report()->num_packets());
169 NtpTime ntp1 = parser()->sender_report()->ntp();
170 uint32_t rtp1 = parser()->sender_report()->rtp_timestamp();
171
172 // Send more SRs to ensure slope is always exact for different offsets
173 for (int packets = 1; packets <= kExtraPackets; ++packets) {
174 clock_.AdvanceTimeMicroseconds(kTimeBetweenSRsUs);
175 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
176 EXPECT_EQ(packets + 1, parser()->sender_report()->num_packets());
177
178 NtpTime ntp2 = parser()->sender_report()->ntp();
179 uint32_t rtp2 = parser()->sender_report()->rtp_timestamp();
180
181 uint32_t ntp_diff_in_rtp_units =
182 (ntp2.ToMs() - ntp1.ToMs()) * (kVideoPayloadTypeFrequency / 1000);
183 EXPECT_EQ(rtp2 - rtp1, ntp_diff_in_rtp_units);
184 }
185}
186
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200187TEST_F(RtcpSenderTest, DoNotSendSrBeforeRtp) {
188 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800189 nullptr, nullptr, &test_transport_, 1000));
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200190 rtcp_sender_->SetSSRC(kSenderSsrc);
191 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
192 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
193 rtcp_sender_->SetSendingStatus(feedback_state(), true);
194
195 // Sender Report shouldn't be send as an SR nor as a Report.
196 rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr);
197 EXPECT_EQ(0, parser()->sender_report()->num_packets());
198 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
199 EXPECT_EQ(0, parser()->sender_report()->num_packets());
200 // Other packets (e.g. Pli) are allowed, even if useless.
201 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
202 EXPECT_EQ(1, parser()->pli()->num_packets());
203}
204
205TEST_F(RtcpSenderTest, DoNotSendCompundBeforeRtp) {
206 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800207 nullptr, nullptr, &test_transport_, 1000));
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200208 rtcp_sender_->SetSSRC(kSenderSsrc);
209 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
210 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
211 rtcp_sender_->SetSendingStatus(feedback_state(), true);
212
213 // In compound mode no packets are allowed (e.g. Pli) because compound mode
214 // should start with Sender Report.
215 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
216 EXPECT_EQ(0, parser()->pli()->num_packets());
217}
218
asapersson22ff75a2015-08-21 00:02:47 -0700219TEST_F(RtcpSenderTest, SendRr) {
pbosda903ea2015-10-02 02:36:56 -0700220 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700221 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
222 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200223 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
224 EXPECT_EQ(0U, parser()->receiver_report()->report_blocks().size());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000225}
226
asapersson22ff75a2015-08-21 00:02:47 -0700227TEST_F(RtcpSenderTest, SendRrWithOneReportBlock) {
228 const uint16_t kSeqNum = 11111;
229 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
pbosda903ea2015-10-02 02:36:56 -0700230 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700231 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
232 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200233 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
234 ASSERT_EQ(1U, parser()->receiver_report()->report_blocks().size());
235 const rtcp::ReportBlock& rb = parser()->receiver_report()->report_blocks()[0];
236 EXPECT_EQ(kRemoteSsrc, rb.source_ssrc());
237 EXPECT_EQ(0U, rb.fraction_lost());
Harald Alvestrand70206d62017-12-08 08:59:07 +0100238 EXPECT_EQ(0, rb.cumulative_lost_signed());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200239 EXPECT_EQ(kSeqNum, rb.extended_high_seq_num());
asapersson22ff75a2015-08-21 00:02:47 -0700240}
241
242TEST_F(RtcpSenderTest, SendRrWithTwoReportBlocks) {
243 const uint16_t kSeqNum = 11111;
244 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
245 InsertIncomingPacket(kRemoteSsrc + 1, kSeqNum + 1);
pbosda903ea2015-10-02 02:36:56 -0700246 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700247 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
248 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200249 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
250 EXPECT_EQ(2U, parser()->receiver_report()->report_blocks().size());
251 EXPECT_EQ(kRemoteSsrc,
252 parser()->receiver_report()->report_blocks()[0].source_ssrc());
253 EXPECT_EQ(kRemoteSsrc + 1,
254 parser()->receiver_report()->report_blocks()[1].source_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700255}
256
257TEST_F(RtcpSenderTest, SendSdes) {
pbosda903ea2015-10-02 02:36:56 -0700258 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700259 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
260 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
261 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200262 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
263 EXPECT_EQ(kSenderSsrc, parser()->sdes()->chunks()[0].ssrc);
264 EXPECT_EQ("alice@host", parser()->sdes()->chunks()[0].cname);
asapersson22ff75a2015-08-21 00:02:47 -0700265}
266
danilchap74e8df8f2017-03-16 08:04:08 -0700267TEST_F(RtcpSenderTest, SendSdesWithMaxChunks) {
268 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
269 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
270 const char cname[] = "smith@host";
271 for (size_t i = 0; i < 30; ++i) {
272 const uint32_t csrc = 0x1234 + i;
273 EXPECT_EQ(0, rtcp_sender_->AddMixedCNAME(csrc, cname));
274 }
275 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
276 EXPECT_EQ(1, parser()->sdes()->num_packets());
277 EXPECT_EQ(31U, parser()->sdes()->chunks().size());
278}
279
asapersson22ff75a2015-08-21 00:02:47 -0700280TEST_F(RtcpSenderTest, SdesIncludedInCompoundPacket) {
pbosda903ea2015-10-02 02:36:56 -0700281 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700282 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
283 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
284 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
285 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200286 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
asapersson22ff75a2015-08-21 00:02:47 -0700287}
288
289TEST_F(RtcpSenderTest, SendBye) {
pbosda903ea2015-10-02 02:36:56 -0700290 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700291 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
292 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200293 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700294}
295
296TEST_F(RtcpSenderTest, StopSendingTriggersBye) {
pbosda903ea2015-10-02 02:36:56 -0700297 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700298 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
299 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
300 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200301 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700302}
303
304TEST_F(RtcpSenderTest, SendApp) {
305 const uint8_t kSubType = 30;
306 uint32_t name = 'n' << 24;
307 name += 'a' << 16;
308 name += 'm' << 8;
309 name += 'e';
310 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
asapersson22ff75a2015-08-21 00:02:47 -0700311 EXPECT_EQ(0, rtcp_sender_->SetApplicationSpecificData(kSubType, name, kData,
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200312 sizeof(kData)));
pbosda903ea2015-10-02 02:36:56 -0700313 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700314 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
315 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200316 EXPECT_EQ(kSubType, parser()->app()->sub_type());
317 EXPECT_EQ(name, parser()->app()->name());
318 EXPECT_EQ(sizeof(kData), parser()->app()->data_size());
319 EXPECT_EQ(0, memcmp(kData, parser()->app()->data(), sizeof(kData)));
asapersson22ff75a2015-08-21 00:02:47 -0700320}
321
Erik Språng521875a2015-09-01 10:11:16 +0200322TEST_F(RtcpSenderTest, SendEmptyApp) {
323 const uint8_t kSubType = 30;
324 const uint32_t kName = 0x6E616D65;
325
326 EXPECT_EQ(
327 0, rtcp_sender_->SetApplicationSpecificData(kSubType, kName, nullptr, 0));
328
pbosda903ea2015-10-02 02:36:56 -0700329 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Erik Språng521875a2015-09-01 10:11:16 +0200330 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
331 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200332 EXPECT_EQ(kSubType, parser()->app()->sub_type());
333 EXPECT_EQ(kName, parser()->app()->name());
334 EXPECT_EQ(0U, parser()->app()->data_size());
Erik Språng521875a2015-09-01 10:11:16 +0200335}
336
asapersson22ff75a2015-08-21 00:02:47 -0700337TEST_F(RtcpSenderTest, SetInvalidApplicationSpecificData) {
338 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't'};
339 const uint16_t kInvalidDataLength = sizeof(kData) / sizeof(kData[0]);
Yves Gerey665174f2018-06-19 15:03:05 +0200340 EXPECT_EQ(-1,
341 rtcp_sender_->SetApplicationSpecificData(
342 0, 0, kData, kInvalidDataLength)); // Should by multiple of 4.
asapersson22ff75a2015-08-21 00:02:47 -0700343}
344
danilchap498ee8e2017-02-08 05:24:31 -0800345TEST_F(RtcpSenderTest, SendFir) {
pbosda903ea2015-10-02 02:36:56 -0700346 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700347 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
348 EXPECT_EQ(1, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200349 EXPECT_EQ(kSenderSsrc, parser()->fir()->sender_ssrc());
350 EXPECT_EQ(1U, parser()->fir()->requests().size());
351 EXPECT_EQ(kRemoteSsrc, parser()->fir()->requests()[0].ssrc);
352 uint8_t seq = parser()->fir()->requests()[0].seq_nr;
asapersson22ff75a2015-08-21 00:02:47 -0700353 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
354 EXPECT_EQ(2, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200355 EXPECT_EQ(seq + 1, parser()->fir()->requests()[0].seq_nr);
asapersson22ff75a2015-08-21 00:02:47 -0700356}
357
asapersson22ff75a2015-08-21 00:02:47 -0700358TEST_F(RtcpSenderTest, SendPli) {
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(), kRtcpPli));
361 EXPECT_EQ(1, parser()->pli()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200362 EXPECT_EQ(kSenderSsrc, parser()->pli()->sender_ssrc());
363 EXPECT_EQ(kRemoteSsrc, parser()->pli()->media_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700364}
365
asapersson22ff75a2015-08-21 00:02:47 -0700366TEST_F(RtcpSenderTest, SendNack) {
pbosda903ea2015-10-02 02:36:56 -0700367 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700368 const uint16_t kList[] = {0, 1, 16};
369 const int32_t kListLength = sizeof(kList) / sizeof(kList[0]);
370 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpNack, kListLength,
371 kList));
372 EXPECT_EQ(1, parser()->nack()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200373 EXPECT_EQ(kSenderSsrc, parser()->nack()->sender_ssrc());
374 EXPECT_EQ(kRemoteSsrc, parser()->nack()->media_ssrc());
375 EXPECT_THAT(parser()->nack()->packet_ids(), ElementsAre(0, 1, 16));
asapersson22ff75a2015-08-21 00:02:47 -0700376}
377
Elad Alon7d6a4c02019-02-25 13:00:51 +0100378TEST_F(RtcpSenderTest, SendLossNotification) {
379 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
380 constexpr uint16_t kLastDecoded = 0x1234;
381 constexpr uint16_t kLastReceived = 0x4321;
382 constexpr bool kDecodabilityFlag = true;
383 const int32_t result = rtcp_sender_->SendLossNotification(
384 feedback_state(), kLastDecoded, kLastReceived, kDecodabilityFlag);
385 EXPECT_EQ(result, 0);
386 EXPECT_EQ(1, parser()->loss_notification()->num_packets());
387 EXPECT_EQ(kSenderSsrc, parser()->loss_notification()->sender_ssrc());
388 EXPECT_EQ(kRemoteSsrc, parser()->loss_notification()->media_ssrc());
389}
390
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200391TEST_F(RtcpSenderTest, RembNotIncludedBeforeSet) {
392 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
393
394 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
395
396 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
397 EXPECT_EQ(0, parser()->remb()->num_packets());
398}
399
400TEST_F(RtcpSenderTest, RembNotIncludedAfterUnset) {
danilchapba6aa902017-04-18 06:57:02 -0700401 const uint64_t kBitrate = 261011;
402 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
403 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200404 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
danilchapba6aa902017-04-18 06:57:02 -0700405 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
406 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200407 EXPECT_EQ(1, parser()->remb()->num_packets());
danilchapba6aa902017-04-18 06:57:02 -0700408
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200409 // Turn off REMB. rtcp_sender no longer should send it.
410 rtcp_sender_->UnsetRemb();
danilchapba6aa902017-04-18 06:57:02 -0700411 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
412 ASSERT_EQ(2, parser()->receiver_report()->num_packets());
413 EXPECT_EQ(1, parser()->remb()->num_packets());
Danil Chapovalov857a8fb2016-09-06 11:41:46 +0200414}
415
asapersson22ff75a2015-08-21 00:02:47 -0700416TEST_F(RtcpSenderTest, SendRemb) {
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200417 const uint64_t kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200418 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700419 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200420 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
421
422 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRemb);
423
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200424 EXPECT_EQ(1, parser()->remb()->num_packets());
425 EXPECT_EQ(kSenderSsrc, parser()->remb()->sender_ssrc());
426 EXPECT_EQ(kBitrate, parser()->remb()->bitrate_bps());
427 EXPECT_THAT(parser()->remb()->ssrcs(),
asapersson22ff75a2015-08-21 00:02:47 -0700428 ElementsAre(kRemoteSsrc, kRemoteSsrc + 1));
429}
430
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200431TEST_F(RtcpSenderTest, RembIncludedInEachCompoundPacketAfterSet) {
asapersson22ff75a2015-08-21 00:02:47 -0700432 const int kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200433 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700434 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200435 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
436
437 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200438 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700439 // REMB should be included in each compound packet.
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200440 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200441 EXPECT_EQ(2, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700442}
443
asapersson22ff75a2015-08-21 00:02:47 -0700444TEST_F(RtcpSenderTest, SendXrWithDlrr) {
pbosda903ea2015-10-02 02:36:56 -0700445 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000446 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
danilchap798896a2016-09-28 02:54:25 -0700447 rtcp::ReceiveTimeInfo last_xr_rr;
448 last_xr_rr.ssrc = 0x11111111;
449 last_xr_rr.last_rr = 0x22222222;
450 last_xr_rr.delay_since_last_rr = 0x33333333;
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200451 feedback_state.last_xr_rtis.push_back(last_xr_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000452 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200453 EXPECT_EQ(1, parser()->xr()->num_packets());
454 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200455 ASSERT_THAT(parser()->xr()->dlrr().sub_blocks(), SizeIs(1));
danilchap80ac24d2016-10-31 08:40:47 -0700456 EXPECT_EQ(last_xr_rr.ssrc, parser()->xr()->dlrr().sub_blocks()[0].ssrc);
457 EXPECT_EQ(last_xr_rr.last_rr, parser()->xr()->dlrr().sub_blocks()[0].last_rr);
danilchap798896a2016-09-28 02:54:25 -0700458 EXPECT_EQ(last_xr_rr.delay_since_last_rr,
danilchap80ac24d2016-10-31 08:40:47 -0700459 parser()->xr()->dlrr().sub_blocks()[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000460}
461
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200462TEST_F(RtcpSenderTest, SendXrWithMultipleDlrrSubBlocks) {
463 const size_t kNumReceivers = 2;
464 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
465 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
466 for (size_t i = 0; i < kNumReceivers; ++i) {
467 rtcp::ReceiveTimeInfo last_xr_rr;
468 last_xr_rr.ssrc = i;
469 last_xr_rr.last_rr = (i + 1) * 100;
470 last_xr_rr.delay_since_last_rr = (i + 2) * 200;
471 feedback_state.last_xr_rtis.push_back(last_xr_rr);
472 }
473
474 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
475 EXPECT_EQ(1, parser()->xr()->num_packets());
476 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
477 ASSERT_THAT(parser()->xr()->dlrr().sub_blocks(), SizeIs(kNumReceivers));
478 for (size_t i = 0; i < kNumReceivers; ++i) {
479 EXPECT_EQ(feedback_state.last_xr_rtis[i].ssrc,
480 parser()->xr()->dlrr().sub_blocks()[i].ssrc);
481 EXPECT_EQ(feedback_state.last_xr_rtis[i].last_rr,
482 parser()->xr()->dlrr().sub_blocks()[i].last_rr);
483 EXPECT_EQ(feedback_state.last_xr_rtis[i].delay_since_last_rr,
484 parser()->xr()->dlrr().sub_blocks()[i].delay_since_last_rr);
485 }
486}
487
asapersson22ff75a2015-08-21 00:02:47 -0700488TEST_F(RtcpSenderTest, SendXrWithRrtr) {
pbosda903ea2015-10-02 02:36:56 -0700489 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700490 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000491 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200492 NtpTime ntp = TimeMicrosToNtp(clock_.TimeInMicroseconds());
asapersson22ff75a2015-08-21 00:02:47 -0700493 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200494 EXPECT_EQ(1, parser()->xr()->num_packets());
495 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
danilchap80ac24d2016-10-31 08:40:47 -0700496 EXPECT_FALSE(parser()->xr()->dlrr());
danilchap80ac24d2016-10-31 08:40:47 -0700497 ASSERT_TRUE(parser()->xr()->rrtr());
danilchap21dc1892017-03-07 02:51:09 -0800498 EXPECT_EQ(ntp, parser()->xr()->rrtr()->ntp());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000499}
500
asapersson22ff75a2015-08-21 00:02:47 -0700501TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfSending) {
pbosda903ea2015-10-02 02:36:56 -0700502 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700503 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
504 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
505 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200506 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700507}
508
509TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfNotEnabled) {
pbosda903ea2015-10-02 02:36:56 -0700510 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700511 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000512 rtcp_sender_->SendRtcpXrReceiverReferenceTime(false);
asapersson22ff75a2015-08-21 00:02:47 -0700513 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200514 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000515}
516
asapersson22ff75a2015-08-21 00:02:47 -0700517TEST_F(RtcpSenderTest, TestRegisterRtcpPacketTypeObserver) {
518 RtcpPacketTypeCounterObserverImpl observer;
sprang86fd9ed2015-09-29 04:45:43 -0700519 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800520 &observer, nullptr, &test_transport_,
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800521 1000));
asapersson22ff75a2015-08-21 00:02:47 -0700522 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700523 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700524 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
525 EXPECT_EQ(1, parser()->pli()->num_packets());
526 EXPECT_EQ(kRemoteSsrc, observer.ssrc_);
527 EXPECT_EQ(1U, observer.counter_.pli_packets);
528 EXPECT_EQ(clock_.TimeInMilliseconds(),
529 observer.counter_.first_packet_time_ms);
530}
531
532TEST_F(RtcpSenderTest, SendTmmbr) {
533 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700534 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700535 rtcp_sender_->SetTargetBitrate(kBitrateBps);
536 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpTmmbr));
537 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200538 EXPECT_EQ(kSenderSsrc, parser()->tmmbr()->sender_ssrc());
539 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
540 EXPECT_EQ(kBitrateBps, parser()->tmmbr()->requests()[0].bitrate_bps());
asapersson22ff75a2015-08-21 00:02:47 -0700541 // TODO(asapersson): tmmbr_item()->Overhead() looks broken, always zero.
542}
543
544TEST_F(RtcpSenderTest, TmmbrIncludedInCompoundPacketIfEnabled) {
545 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700546 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700547 EXPECT_FALSE(rtcp_sender_->TMMBR());
548 rtcp_sender_->SetTMMBRStatus(true);
549 EXPECT_TRUE(rtcp_sender_->TMMBR());
550 rtcp_sender_->SetTargetBitrate(kBitrateBps);
551 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
552 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200553 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
asapersson22ff75a2015-08-21 00:02:47 -0700554 // TMMBR should be included in each compound packet.
555 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
556 EXPECT_EQ(2, parser()->tmmbr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700557
558 rtcp_sender_->SetTMMBRStatus(false);
559 EXPECT_FALSE(rtcp_sender_->TMMBR());
560}
561
562TEST_F(RtcpSenderTest, SendTmmbn) {
pbosda903ea2015-10-02 02:36:56 -0700563 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200564 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700565 std::vector<rtcp::TmmbItem> bounding_set;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200566 const uint32_t kBitrateBps = 32768000;
asapersson22ff75a2015-08-21 00:02:47 -0700567 const uint32_t kPacketOh = 40;
568 const uint32_t kSourceSsrc = 12345;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200569 const rtcp::TmmbItem tmmbn(kSourceSsrc, kBitrateBps, kPacketOh);
danilchap6eaa3a42016-05-09 10:59:50 -0700570 bounding_set.push_back(tmmbn);
danilchap853ecb22016-08-22 08:26:15 -0700571 rtcp_sender_->SetTmmbn(bounding_set);
danilchap6eaa3a42016-05-09 10:59:50 -0700572
asapersson22ff75a2015-08-21 00:02:47 -0700573 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
574 EXPECT_EQ(1, parser()->sender_report()->num_packets());
575 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200576 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
577 EXPECT_EQ(1U, parser()->tmmbn()->items().size());
578 EXPECT_EQ(kBitrateBps, parser()->tmmbn()->items()[0].bitrate_bps());
579 EXPECT_EQ(kPacketOh, parser()->tmmbn()->items()[0].packet_overhead());
580 EXPECT_EQ(kSourceSsrc, parser()->tmmbn()->items()[0].ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700581}
582
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000583// This test is written to verify actual behaviour. It does not seem
584// to make much sense to send an empty TMMBN, since there is no place
585// to put an actual limit here. It's just information that no limit
586// is set, which is kind of the starting assumption.
587// See http://code.google.com/p/webrtc/issues/detail?id=468 for one
588// situation where this caused confusion.
589TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndEmpty) {
pbosda903ea2015-10-02 02:36:56 -0700590 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200591 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700592 std::vector<rtcp::TmmbItem> bounding_set;
danilchap853ecb22016-08-22 08:26:15 -0700593 rtcp_sender_->SetTmmbn(bounding_set);
asapersson22ff75a2015-08-21 00:02:47 -0700594 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
595 EXPECT_EQ(1, parser()->sender_report()->num_packets());
596 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200597 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
598 EXPECT_EQ(0U, parser()->tmmbn()->items().size());
hta@webrtc.org65a4e4e2012-04-30 11:23:41 +0000599}
600
asapersson22ff75a2015-08-21 00:02:47 -0700601TEST_F(RtcpSenderTest, SendCompoundPliRemb) {
602 const int kBitrate = 261011;
603 std::vector<uint32_t> ssrcs;
604 ssrcs.push_back(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700605 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200606 rtcp_sender_->SetRemb(kBitrate, ssrcs);
asapersson22ff75a2015-08-21 00:02:47 -0700607 std::set<RTCPPacketType> packet_types;
608 packet_types.insert(kRtcpRemb);
609 packet_types.insert(kRtcpPli);
610 EXPECT_EQ(0, rtcp_sender_->SendCompoundRTCP(feedback_state(), packet_types));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200611 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700612 EXPECT_EQ(1, parser()->pli()->num_packets());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000613}
Erik Språnga38233a2015-07-24 09:58:18 +0200614
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800615// This test is written to verify that BYE is always the last packet
616// type in a RTCP compoud packet. The rtcp_sender_ is recreated with
617// mock_transport, which is used to check for whether BYE at the end
618// of a RTCP compound packet.
619TEST_F(RtcpSenderTest, ByeMustBeLast) {
620 MockTransport mock_transport;
621 EXPECT_CALL(mock_transport, SendRtcp(_, _))
Yves Gerey665174f2018-06-19 15:03:05 +0200622 .WillOnce(Invoke([](const uint8_t* data, size_t len) {
623 const uint8_t* next_packet = data;
624 const uint8_t* const packet_end = data + len;
625 rtcp::CommonHeader packet;
626 while (next_packet < packet_end) {
627 EXPECT_TRUE(packet.Parse(next_packet, packet_end - next_packet));
628 next_packet = packet.NextPacket();
629 if (packet.type() ==
630 rtcp::Bye::kPacketType) // Main test expectation.
631 EXPECT_EQ(0, packet_end - next_packet)
632 << "Bye packet should be last in a compound RTCP packet.";
633 if (next_packet == packet_end) // Validate test was set correctly.
634 EXPECT_EQ(packet.type(), rtcp::Bye::kPacketType)
635 << "Last packet in this test expected to be Bye.";
636 }
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800637
Yves Gerey665174f2018-06-19 15:03:05 +0200638 return true;
639 }));
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800640
641 // Re-configure rtcp_sender_ with mock_transport_
642 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800643 nullptr, nullptr, &mock_transport, 1000));
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800644 rtcp_sender_->SetSSRC(kSenderSsrc);
645 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
danilchap71fead22016-08-18 02:01:49 -0700646 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
Ilya Nikolaevskiy5e58bcb2018-10-24 13:34:32 +0200647 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds(),
Mirko Bonadei970f2f72019-02-28 14:57:52 +0100648 /*payload_type=*/0);
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800649
Niels Möller44b384d2018-10-05 11:15:57 +0200650 // Set up REMB info to be included with BYE.
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800651 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Niels Möller44b384d2018-10-05 11:15:57 +0200652 rtcp_sender_->SetRemb(1234, {});
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800653 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
654}
655
sprang5e38c962016-12-01 05:18:09 -0800656TEST_F(RtcpSenderTest, SendXrWithTargetBitrate) {
657 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
658 const size_t kNumSpatialLayers = 2;
659 const size_t kNumTemporalLayers = 2;
Erik Språng566124a2018-04-23 12:32:22 +0200660 VideoBitrateAllocation allocation;
sprang5e38c962016-12-01 05:18:09 -0800661 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
662 uint32_t start_bitrate_bps = (sl + 1) * 100000;
663 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl)
664 allocation.SetBitrate(sl, tl, start_bitrate_bps + (tl * 20000));
665 }
666 rtcp_sender_->SetVideoBitrateAllocation(allocation);
667
668 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
669 EXPECT_EQ(1, parser()->xr()->num_packets());
670 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
Danil Chapovalovd264df52018-06-14 12:59:38 +0200671 const absl::optional<rtcp::TargetBitrate>& target_bitrate =
sprang5e38c962016-12-01 05:18:09 -0800672 parser()->xr()->target_bitrate();
673 ASSERT_TRUE(target_bitrate);
674 const std::vector<rtcp::TargetBitrate::BitrateItem>& bitrates =
675 target_bitrate->GetTargetBitrates();
676 EXPECT_EQ(kNumSpatialLayers * kNumTemporalLayers, bitrates.size());
677
678 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
679 uint32_t start_bitrate_bps = (sl + 1) * 100000;
680 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl) {
681 size_t index = (sl * kNumSpatialLayers) + tl;
682 const rtcp::TargetBitrate::BitrateItem& item = bitrates[index];
683 EXPECT_EQ(sl, item.spatial_layer);
684 EXPECT_EQ(tl, item.temporal_layer);
685 EXPECT_EQ(start_bitrate_bps + (tl * 20000),
686 item.target_bitrate_kbps * 1000);
687 }
688 }
689}
690
Erik Språng8782a582018-10-04 15:36:06 +0200691TEST_F(RtcpSenderTest, SendImmediateXrWithTargetBitrate) {
692 // Initialize. Send a first report right away.
693 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
694 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
695 clock_.AdvanceTimeMilliseconds(5);
696
697 // Video bitrate allocation generated, save until next time we send a report.
698 VideoBitrateAllocation allocation;
699 allocation.SetBitrate(0, 0, 100000);
700 rtcp_sender_->SetVideoBitrateAllocation(allocation);
701 // First seen instance will be sent immediately.
702 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
703 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
704 clock_.AdvanceTimeMilliseconds(5);
705
706 // Update bitrate of existing layer, does not quality for immediate sending.
707 allocation.SetBitrate(0, 0, 150000);
708 rtcp_sender_->SetVideoBitrateAllocation(allocation);
709 EXPECT_FALSE(rtcp_sender_->TimeToSendRTCPReport(false));
710
711 // A new spatial layer enabled, signal this as soon as possible.
712 allocation.SetBitrate(1, 0, 200000);
713 rtcp_sender_->SetVideoBitrateAllocation(allocation);
714 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
715 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
716 clock_.AdvanceTimeMilliseconds(5);
717
718 // Explicitly disable top layer. The same set of layers now has a bitrate
719 // defined, but the explicit 0 indicates shutdown. Signal immediately.
720 allocation.SetBitrate(1, 0, 0);
721 EXPECT_FALSE(rtcp_sender_->TimeToSendRTCPReport(false));
722 rtcp_sender_->SetVideoBitrateAllocation(allocation);
723 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
724}
725
Erik Språng1cd73912018-10-05 12:57:59 +0200726TEST_F(RtcpSenderTest, SendTargetBitrateExplicitZeroOnStreamRemoval) {
727 // Set up and send a bitrate allocation with two layers.
728
729 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
730 VideoBitrateAllocation allocation;
731 allocation.SetBitrate(0, 0, 100000);
732 allocation.SetBitrate(1, 0, 200000);
733 rtcp_sender_->SetVideoBitrateAllocation(allocation);
734 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
735 absl::optional<rtcp::TargetBitrate> target_bitrate =
736 parser()->xr()->target_bitrate();
737 ASSERT_TRUE(target_bitrate);
738 std::vector<rtcp::TargetBitrate::BitrateItem> bitrates =
739 target_bitrate->GetTargetBitrates();
740 ASSERT_EQ(2u, bitrates.size());
741 EXPECT_EQ(bitrates[0].target_bitrate_kbps,
742 allocation.GetBitrate(0, 0) / 1000);
743 EXPECT_EQ(bitrates[1].target_bitrate_kbps,
744 allocation.GetBitrate(1, 0) / 1000);
745
746 // Create a new allocation, where the second stream is no longer available.
747 VideoBitrateAllocation new_allocation;
748 new_allocation.SetBitrate(0, 0, 150000);
749 rtcp_sender_->SetVideoBitrateAllocation(new_allocation);
750 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
751 target_bitrate = parser()->xr()->target_bitrate();
752 ASSERT_TRUE(target_bitrate);
753 bitrates = target_bitrate->GetTargetBitrates();
754
755 // Two bitrates should still be set, with an explicit entry indicating the
756 // removed stream is gone.
757 ASSERT_EQ(2u, bitrates.size());
758 EXPECT_EQ(bitrates[0].target_bitrate_kbps,
759 new_allocation.GetBitrate(0, 0) / 1000);
760 EXPECT_EQ(bitrates[1].target_bitrate_kbps, 0u);
761}
762
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000763} // namespace webrtc