blob: a2f1d2140b63bf97088a4fbcff78772580c6301b [file] [log] [blame]
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001/*
henrike@webrtc.orgd6d014f2012-02-16 02:18:09 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
kwiberg84be5112016-04-27 01:19:58 -070011#include <memory>
12
Mirko Bonadei71207422017-09-15 13:58:09 +020013#include "common_types.h" // NOLINT(build/include)
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"
19#include "rtc_base/rate_limiter.h"
20#include "test/gmock.h"
21#include "test/gtest.h"
22#include "test/mock_transport.h"
23#include "test/rtcp_packet_parser.h"
asapersson22ff75a2015-08-21 00:02:47 -070024
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -080025using ::testing::_;
asapersson22ff75a2015-08-21 00:02:47 -070026using ::testing::ElementsAre;
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -080027using ::testing::Invoke;
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +020028using ::testing::SizeIs;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000029
30namespace webrtc {
31
asapersson22ff75a2015-08-21 00:02:47 -070032class RtcpPacketTypeCounterObserverImpl : public RtcpPacketTypeCounterObserver {
33 public:
34 RtcpPacketTypeCounterObserverImpl() : ssrc_(0) {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +000035 ~RtcpPacketTypeCounterObserverImpl() override = default;
asapersson22ff75a2015-08-21 00:02:47 -070036 void RtcpPacketTypesCounterUpdated(
37 uint32_t ssrc,
38 const RtcpPacketTypeCounter& packet_counter) override {
39 ssrc_ = ssrc;
40 counter_ = packet_counter;
41 }
42 uint32_t ssrc_;
43 RtcpPacketTypeCounter counter_;
44};
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000045
Yves Gerey665174f2018-06-19 15:03:05 +020046class TestTransport : public Transport, public RtpData {
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000047 public:
asapersson22ff75a2015-08-21 00:02:47 -070048 TestTransport() {}
49
stefan1d8a5062015-10-02 03:39:33 -070050 bool SendRtp(const uint8_t* /*data*/,
51 size_t /*len*/,
52 const PacketOptions& options) override {
pbos2d566682015-09-28 09:59:31 -070053 return false;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000054 }
pbos2d566682015-09-28 09:59:31 -070055 bool SendRtcp(const uint8_t* data, size_t len) override {
Danil Chapovalovba6f7be2016-09-02 18:29:10 +020056 parser_.Parse(data, len);
pbos2d566682015-09-28 09:59:31 -070057 return true;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000058 }
asapersson22ff75a2015-08-21 00:02:47 -070059 int OnReceivedPayloadData(const uint8_t* payload_data,
perkj16ccfdf2017-02-28 14:41:05 -080060 size_t payload_size,
asapersson22ff75a2015-08-21 00:02:47 -070061 const WebRtcRTPHeader* rtp_header) override {
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000062 return 0;
63 }
asapersson22ff75a2015-08-21 00:02:47 -070064 test::RtcpPacketParser parser_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000065};
66
Erik Språnga38233a2015-07-24 09:58:18 +020067namespace {
asapersson22ff75a2015-08-21 00:02:47 -070068static const uint32_t kSenderSsrc = 0x11111111;
69static const uint32_t kRemoteSsrc = 0x22222222;
Danil Chapovalov70ffead2016-07-20 15:26:59 +020070static const uint32_t kStartRtpTimestamp = 0x34567;
71static const uint32_t kRtpTimestamp = 0x45678;
Yves Gerey665174f2018-06-19 15:03:05 +020072} // namespace
Erik Språnga38233a2015-07-24 09:58:18 +020073
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000074class RtcpSenderTest : public ::testing::Test {
75 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +000076 RtcpSenderTest()
asapersson22ff75a2015-08-21 00:02:47 -070077 : clock_(1335900000),
Erik Språng737336d2016-07-29 12:59:36 +020078 receive_statistics_(ReceiveStatistics::Create(&clock_)),
79 retransmission_rate_limiter_(&clock_, 1000) {
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000080 RtpRtcp::Configuration configuration;
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000081 configuration.audio = false;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +000082 configuration.clock = &clock_;
asapersson22ff75a2015-08-21 00:02:47 -070083 configuration.outgoing_transport = &test_transport_;
Erik Språng737336d2016-07-29 12:59:36 +020084 configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
pwestin@webrtc.org2853dde2012-05-11 11:08:54 +000085
asapersson22ff75a2015-08-21 00:02:47 -070086 rtp_rtcp_impl_.reset(new ModuleRtpRtcpImpl(configuration));
sprang86fd9ed2015-09-29 04:45:43 -070087 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -080088 nullptr, nullptr, &test_transport_,
89 configuration.rtcp_interval_config));
asapersson22ff75a2015-08-21 00:02:47 -070090 rtcp_sender_->SetSSRC(kSenderSsrc);
91 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
danilchap71fead22016-08-18 02:01:49 -070092 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
Ilya Nikolaevskiy5e58bcb2018-10-24 13:34:32 +020093 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds(),
94 /*paylpad_type=*/0);
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +000095 }
Erik Språnga38233a2015-07-24 09:58:18 +020096
asapersson22ff75a2015-08-21 00:02:47 -070097 void InsertIncomingPacket(uint32_t remote_ssrc, uint16_t seq_num) {
Niels Möller1f3206c2018-09-14 08:26:32 +020098 RtpPacketReceived packet;
99 packet.SetSsrc(remote_ssrc);
100 packet.SetSequenceNumber(seq_num);
101 packet.SetTimestamp(12345);
102 packet.SetPayloadSize(100 - 12);
103 receive_statistics_->OnRtpPacket(packet);
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000104 }
105
asapersson22ff75a2015-08-21 00:02:47 -0700106 test::RtcpPacketParser* parser() { return &test_transport_.parser_; }
107
108 RTCPSender::FeedbackState feedback_state() {
109 return rtp_rtcp_impl_->GetFeedbackState();
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000110 }
111
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000112 SimulatedClock clock_;
asapersson22ff75a2015-08-21 00:02:47 -0700113 TestTransport test_transport_;
kwiberg84be5112016-04-27 01:19:58 -0700114 std::unique_ptr<ReceiveStatistics> receive_statistics_;
115 std::unique_ptr<ModuleRtpRtcpImpl> rtp_rtcp_impl_;
116 std::unique_ptr<RTCPSender> rtcp_sender_;
Erik Språng737336d2016-07-29 12:59:36 +0200117 RateLimiter retransmission_rate_limiter_;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000118};
119
asapersson22ff75a2015-08-21 00:02:47 -0700120TEST_F(RtcpSenderTest, SetRtcpStatus) {
pbosda903ea2015-10-02 02:36:56 -0700121 EXPECT_EQ(RtcpMode::kOff, rtcp_sender_->Status());
122 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
123 EXPECT_EQ(RtcpMode::kReducedSize, rtcp_sender_->Status());
asapersson22ff75a2015-08-21 00:02:47 -0700124}
125
126TEST_F(RtcpSenderTest, SetSendingStatus) {
127 EXPECT_FALSE(rtcp_sender_->Sending());
128 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
129 EXPECT_TRUE(rtcp_sender_->Sending());
130}
131
132TEST_F(RtcpSenderTest, NoPacketSentIfOff) {
pbosda903ea2015-10-02 02:36:56 -0700133 rtcp_sender_->SetRTCPStatus(RtcpMode::kOff);
asapersson22ff75a2015-08-21 00:02:47 -0700134 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000135}
136
asapersson22ff75a2015-08-21 00:02:47 -0700137TEST_F(RtcpSenderTest, SendSr) {
138 const uint32_t kPacketCount = 0x12345;
139 const uint32_t kOctetCount = 0x23456;
pbosda903ea2015-10-02 02:36:56 -0700140 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000141 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200142 rtcp_sender_->SetSendingStatus(feedback_state, true);
asapersson22ff75a2015-08-21 00:02:47 -0700143 feedback_state.packets_sent = kPacketCount;
144 feedback_state.media_bytes_sent = kOctetCount;
danilchap21dc1892017-03-07 02:51:09 -0800145 NtpTime ntp = clock_.CurrentNtpTime();
asapersson22ff75a2015-08-21 00:02:47 -0700146 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpSr));
147 EXPECT_EQ(1, parser()->sender_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200148 EXPECT_EQ(kSenderSsrc, parser()->sender_report()->sender_ssrc());
danilchap21dc1892017-03-07 02:51:09 -0800149 EXPECT_EQ(ntp, parser()->sender_report()->ntp());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200150 EXPECT_EQ(kPacketCount, parser()->sender_report()->sender_packet_count());
151 EXPECT_EQ(kOctetCount, parser()->sender_report()->sender_octet_count());
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200152 EXPECT_EQ(kStartRtpTimestamp + kRtpTimestamp,
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200153 parser()->sender_report()->rtp_timestamp());
154 EXPECT_EQ(0U, parser()->sender_report()->report_blocks().size());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000155}
156
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200157TEST_F(RtcpSenderTest, DoNotSendSrBeforeRtp) {
158 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800159 nullptr, nullptr, &test_transport_,
160 RtcpIntervalConfig{}));
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200161 rtcp_sender_->SetSSRC(kSenderSsrc);
162 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
163 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
164 rtcp_sender_->SetSendingStatus(feedback_state(), true);
165
166 // Sender Report shouldn't be send as an SR nor as a Report.
167 rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr);
168 EXPECT_EQ(0, parser()->sender_report()->num_packets());
169 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
170 EXPECT_EQ(0, parser()->sender_report()->num_packets());
171 // Other packets (e.g. Pli) are allowed, even if useless.
172 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
173 EXPECT_EQ(1, parser()->pli()->num_packets());
174}
175
176TEST_F(RtcpSenderTest, DoNotSendCompundBeforeRtp) {
177 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800178 nullptr, nullptr, &test_transport_,
179 RtcpIntervalConfig{}));
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200180 rtcp_sender_->SetSSRC(kSenderSsrc);
181 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
182 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
183 rtcp_sender_->SetSendingStatus(feedback_state(), true);
184
185 // In compound mode no packets are allowed (e.g. Pli) because compound mode
186 // should start with Sender Report.
187 EXPECT_EQ(-1, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
188 EXPECT_EQ(0, parser()->pli()->num_packets());
189}
190
asapersson22ff75a2015-08-21 00:02:47 -0700191TEST_F(RtcpSenderTest, SendRr) {
pbosda903ea2015-10-02 02:36:56 -0700192 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700193 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
194 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200195 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
196 EXPECT_EQ(0U, parser()->receiver_report()->report_blocks().size());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000197}
198
asapersson22ff75a2015-08-21 00:02:47 -0700199TEST_F(RtcpSenderTest, SendRrWithOneReportBlock) {
200 const uint16_t kSeqNum = 11111;
201 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
pbosda903ea2015-10-02 02:36:56 -0700202 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700203 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
204 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200205 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
206 ASSERT_EQ(1U, parser()->receiver_report()->report_blocks().size());
207 const rtcp::ReportBlock& rb = parser()->receiver_report()->report_blocks()[0];
208 EXPECT_EQ(kRemoteSsrc, rb.source_ssrc());
209 EXPECT_EQ(0U, rb.fraction_lost());
Harald Alvestrand70206d62017-12-08 08:59:07 +0100210 EXPECT_EQ(0, rb.cumulative_lost_signed());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200211 EXPECT_EQ(kSeqNum, rb.extended_high_seq_num());
asapersson22ff75a2015-08-21 00:02:47 -0700212}
213
214TEST_F(RtcpSenderTest, SendRrWithTwoReportBlocks) {
215 const uint16_t kSeqNum = 11111;
216 InsertIncomingPacket(kRemoteSsrc, kSeqNum);
217 InsertIncomingPacket(kRemoteSsrc + 1, kSeqNum + 1);
pbosda903ea2015-10-02 02:36:56 -0700218 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700219 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr));
220 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200221 EXPECT_EQ(kSenderSsrc, parser()->receiver_report()->sender_ssrc());
222 EXPECT_EQ(2U, parser()->receiver_report()->report_blocks().size());
223 EXPECT_EQ(kRemoteSsrc,
224 parser()->receiver_report()->report_blocks()[0].source_ssrc());
225 EXPECT_EQ(kRemoteSsrc + 1,
226 parser()->receiver_report()->report_blocks()[1].source_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700227}
228
229TEST_F(RtcpSenderTest, SendSdes) {
pbosda903ea2015-10-02 02:36:56 -0700230 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700231 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
232 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
233 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200234 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
235 EXPECT_EQ(kSenderSsrc, parser()->sdes()->chunks()[0].ssrc);
236 EXPECT_EQ("alice@host", parser()->sdes()->chunks()[0].cname);
asapersson22ff75a2015-08-21 00:02:47 -0700237}
238
danilchap74e8df8f2017-03-16 08:04:08 -0700239TEST_F(RtcpSenderTest, SendSdesWithMaxChunks) {
240 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
241 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
242 const char cname[] = "smith@host";
243 for (size_t i = 0; i < 30; ++i) {
244 const uint32_t csrc = 0x1234 + i;
245 EXPECT_EQ(0, rtcp_sender_->AddMixedCNAME(csrc, cname));
246 }
247 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSdes));
248 EXPECT_EQ(1, parser()->sdes()->num_packets());
249 EXPECT_EQ(31U, parser()->sdes()->chunks().size());
250}
251
asapersson22ff75a2015-08-21 00:02:47 -0700252TEST_F(RtcpSenderTest, SdesIncludedInCompoundPacket) {
pbosda903ea2015-10-02 02:36:56 -0700253 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700254 EXPECT_EQ(0, rtcp_sender_->SetCNAME("alice@host"));
255 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
256 EXPECT_EQ(1, parser()->receiver_report()->num_packets());
257 EXPECT_EQ(1, parser()->sdes()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200258 EXPECT_EQ(1U, parser()->sdes()->chunks().size());
asapersson22ff75a2015-08-21 00:02:47 -0700259}
260
261TEST_F(RtcpSenderTest, SendBye) {
pbosda903ea2015-10-02 02:36:56 -0700262 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700263 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
264 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200265 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700266}
267
268TEST_F(RtcpSenderTest, StopSendingTriggersBye) {
pbosda903ea2015-10-02 02:36:56 -0700269 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700270 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
271 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
272 EXPECT_EQ(1, parser()->bye()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200273 EXPECT_EQ(kSenderSsrc, parser()->bye()->sender_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700274}
275
276TEST_F(RtcpSenderTest, SendApp) {
277 const uint8_t kSubType = 30;
278 uint32_t name = 'n' << 24;
279 name += 'a' << 16;
280 name += 'm' << 8;
281 name += 'e';
282 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
asapersson22ff75a2015-08-21 00:02:47 -0700283 EXPECT_EQ(0, rtcp_sender_->SetApplicationSpecificData(kSubType, name, kData,
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200284 sizeof(kData)));
pbosda903ea2015-10-02 02:36:56 -0700285 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700286 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
287 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200288 EXPECT_EQ(kSubType, parser()->app()->sub_type());
289 EXPECT_EQ(name, parser()->app()->name());
290 EXPECT_EQ(sizeof(kData), parser()->app()->data_size());
291 EXPECT_EQ(0, memcmp(kData, parser()->app()->data(), sizeof(kData)));
asapersson22ff75a2015-08-21 00:02:47 -0700292}
293
Erik Språng521875a2015-09-01 10:11:16 +0200294TEST_F(RtcpSenderTest, SendEmptyApp) {
295 const uint8_t kSubType = 30;
296 const uint32_t kName = 0x6E616D65;
297
298 EXPECT_EQ(
299 0, rtcp_sender_->SetApplicationSpecificData(kSubType, kName, nullptr, 0));
300
pbosda903ea2015-10-02 02:36:56 -0700301 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Erik Språng521875a2015-09-01 10:11:16 +0200302 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpApp));
303 EXPECT_EQ(1, parser()->app()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200304 EXPECT_EQ(kSubType, parser()->app()->sub_type());
305 EXPECT_EQ(kName, parser()->app()->name());
306 EXPECT_EQ(0U, parser()->app()->data_size());
Erik Språng521875a2015-09-01 10:11:16 +0200307}
308
asapersson22ff75a2015-08-21 00:02:47 -0700309TEST_F(RtcpSenderTest, SetInvalidApplicationSpecificData) {
310 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't'};
311 const uint16_t kInvalidDataLength = sizeof(kData) / sizeof(kData[0]);
Yves Gerey665174f2018-06-19 15:03:05 +0200312 EXPECT_EQ(-1,
313 rtcp_sender_->SetApplicationSpecificData(
314 0, 0, kData, kInvalidDataLength)); // Should by multiple of 4.
asapersson22ff75a2015-08-21 00:02:47 -0700315}
316
danilchap498ee8e2017-02-08 05:24:31 -0800317TEST_F(RtcpSenderTest, SendFir) {
pbosda903ea2015-10-02 02:36:56 -0700318 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700319 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
320 EXPECT_EQ(1, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200321 EXPECT_EQ(kSenderSsrc, parser()->fir()->sender_ssrc());
322 EXPECT_EQ(1U, parser()->fir()->requests().size());
323 EXPECT_EQ(kRemoteSsrc, parser()->fir()->requests()[0].ssrc);
324 uint8_t seq = parser()->fir()->requests()[0].seq_nr;
asapersson22ff75a2015-08-21 00:02:47 -0700325 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpFir));
326 EXPECT_EQ(2, parser()->fir()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200327 EXPECT_EQ(seq + 1, parser()->fir()->requests()[0].seq_nr);
asapersson22ff75a2015-08-21 00:02:47 -0700328}
329
asapersson22ff75a2015-08-21 00:02:47 -0700330TEST_F(RtcpSenderTest, SendPli) {
pbosda903ea2015-10-02 02:36:56 -0700331 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700332 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
333 EXPECT_EQ(1, parser()->pli()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200334 EXPECT_EQ(kSenderSsrc, parser()->pli()->sender_ssrc());
335 EXPECT_EQ(kRemoteSsrc, parser()->pli()->media_ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700336}
337
asapersson22ff75a2015-08-21 00:02:47 -0700338TEST_F(RtcpSenderTest, SendNack) {
pbosda903ea2015-10-02 02:36:56 -0700339 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700340 const uint16_t kList[] = {0, 1, 16};
341 const int32_t kListLength = sizeof(kList) / sizeof(kList[0]);
342 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpNack, kListLength,
343 kList));
344 EXPECT_EQ(1, parser()->nack()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200345 EXPECT_EQ(kSenderSsrc, parser()->nack()->sender_ssrc());
346 EXPECT_EQ(kRemoteSsrc, parser()->nack()->media_ssrc());
347 EXPECT_THAT(parser()->nack()->packet_ids(), ElementsAre(0, 1, 16));
asapersson22ff75a2015-08-21 00:02:47 -0700348}
349
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200350TEST_F(RtcpSenderTest, RembNotIncludedBeforeSet) {
351 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
352
353 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
354
355 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
356 EXPECT_EQ(0, parser()->remb()->num_packets());
357}
358
359TEST_F(RtcpSenderTest, RembNotIncludedAfterUnset) {
danilchapba6aa902017-04-18 06:57:02 -0700360 const uint64_t kBitrate = 261011;
361 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
362 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200363 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
danilchapba6aa902017-04-18 06:57:02 -0700364 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
365 ASSERT_EQ(1, parser()->receiver_report()->num_packets());
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200366 EXPECT_EQ(1, parser()->remb()->num_packets());
danilchapba6aa902017-04-18 06:57:02 -0700367
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200368 // Turn off REMB. rtcp_sender no longer should send it.
369 rtcp_sender_->UnsetRemb();
danilchapba6aa902017-04-18 06:57:02 -0700370 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRr);
371 ASSERT_EQ(2, parser()->receiver_report()->num_packets());
372 EXPECT_EQ(1, parser()->remb()->num_packets());
Danil Chapovalov857a8fb2016-09-06 11:41:46 +0200373}
374
asapersson22ff75a2015-08-21 00:02:47 -0700375TEST_F(RtcpSenderTest, SendRemb) {
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200376 const uint64_t kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200377 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700378 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200379 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
380
381 rtcp_sender_->SendRTCP(feedback_state(), kRtcpRemb);
382
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200383 EXPECT_EQ(1, parser()->remb()->num_packets());
384 EXPECT_EQ(kSenderSsrc, parser()->remb()->sender_ssrc());
385 EXPECT_EQ(kBitrate, parser()->remb()->bitrate_bps());
386 EXPECT_THAT(parser()->remb()->ssrcs(),
asapersson22ff75a2015-08-21 00:02:47 -0700387 ElementsAre(kRemoteSsrc, kRemoteSsrc + 1));
388}
389
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200390TEST_F(RtcpSenderTest, RembIncludedInEachCompoundPacketAfterSet) {
asapersson22ff75a2015-08-21 00:02:47 -0700391 const int kBitrate = 261011;
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200392 const std::vector<uint32_t> kSsrcs = {kRemoteSsrc, kRemoteSsrc + 1};
pbosda903ea2015-10-02 02:36:56 -0700393 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200394 rtcp_sender_->SetRemb(kBitrate, kSsrcs);
395
396 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200397 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700398 // REMB should be included in each compound packet.
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200399 rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport);
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200400 EXPECT_EQ(2, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700401}
402
asapersson22ff75a2015-08-21 00:02:47 -0700403TEST_F(RtcpSenderTest, SendXrWithDlrr) {
pbosda903ea2015-10-02 02:36:56 -0700404 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000405 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
danilchap798896a2016-09-28 02:54:25 -0700406 rtcp::ReceiveTimeInfo last_xr_rr;
407 last_xr_rr.ssrc = 0x11111111;
408 last_xr_rr.last_rr = 0x22222222;
409 last_xr_rr.delay_since_last_rr = 0x33333333;
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200410 feedback_state.last_xr_rtis.push_back(last_xr_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000411 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200412 EXPECT_EQ(1, parser()->xr()->num_packets());
413 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200414 ASSERT_THAT(parser()->xr()->dlrr().sub_blocks(), SizeIs(1));
danilchap80ac24d2016-10-31 08:40:47 -0700415 EXPECT_EQ(last_xr_rr.ssrc, parser()->xr()->dlrr().sub_blocks()[0].ssrc);
416 EXPECT_EQ(last_xr_rr.last_rr, parser()->xr()->dlrr().sub_blocks()[0].last_rr);
danilchap798896a2016-09-28 02:54:25 -0700417 EXPECT_EQ(last_xr_rr.delay_since_last_rr,
danilchap80ac24d2016-10-31 08:40:47 -0700418 parser()->xr()->dlrr().sub_blocks()[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000419}
420
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200421TEST_F(RtcpSenderTest, SendXrWithMultipleDlrrSubBlocks) {
422 const size_t kNumReceivers = 2;
423 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
424 RTCPSender::FeedbackState feedback_state = rtp_rtcp_impl_->GetFeedbackState();
425 for (size_t i = 0; i < kNumReceivers; ++i) {
426 rtcp::ReceiveTimeInfo last_xr_rr;
427 last_xr_rr.ssrc = i;
428 last_xr_rr.last_rr = (i + 1) * 100;
429 last_xr_rr.delay_since_last_rr = (i + 2) * 200;
430 feedback_state.last_xr_rtis.push_back(last_xr_rr);
431 }
432
433 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpReport));
434 EXPECT_EQ(1, parser()->xr()->num_packets());
435 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
436 ASSERT_THAT(parser()->xr()->dlrr().sub_blocks(), SizeIs(kNumReceivers));
437 for (size_t i = 0; i < kNumReceivers; ++i) {
438 EXPECT_EQ(feedback_state.last_xr_rtis[i].ssrc,
439 parser()->xr()->dlrr().sub_blocks()[i].ssrc);
440 EXPECT_EQ(feedback_state.last_xr_rtis[i].last_rr,
441 parser()->xr()->dlrr().sub_blocks()[i].last_rr);
442 EXPECT_EQ(feedback_state.last_xr_rtis[i].delay_since_last_rr,
443 parser()->xr()->dlrr().sub_blocks()[i].delay_since_last_rr);
444 }
445}
446
asapersson22ff75a2015-08-21 00:02:47 -0700447TEST_F(RtcpSenderTest, SendXrWithRrtr) {
pbosda903ea2015-10-02 02:36:56 -0700448 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700449 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000450 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
danilchap21dc1892017-03-07 02:51:09 -0800451 NtpTime ntp = clock_.CurrentNtpTime();
asapersson22ff75a2015-08-21 00:02:47 -0700452 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());
danilchap80ac24d2016-10-31 08:40:47 -0700455 EXPECT_FALSE(parser()->xr()->dlrr());
danilchap80ac24d2016-10-31 08:40:47 -0700456 ASSERT_TRUE(parser()->xr()->rrtr());
danilchap21dc1892017-03-07 02:51:09 -0800457 EXPECT_EQ(ntp, parser()->xr()->rrtr()->ntp());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000458}
459
asapersson22ff75a2015-08-21 00:02:47 -0700460TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfSending) {
pbosda903ea2015-10-02 02:36:56 -0700461 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700462 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), true));
463 rtcp_sender_->SendRtcpXrReceiverReferenceTime(true);
464 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200465 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700466}
467
468TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfNotEnabled) {
pbosda903ea2015-10-02 02:36:56 -0700469 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700470 EXPECT_EQ(0, rtcp_sender_->SetSendingStatus(feedback_state(), false));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000471 rtcp_sender_->SendRtcpXrReceiverReferenceTime(false);
asapersson22ff75a2015-08-21 00:02:47 -0700472 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200473 EXPECT_EQ(0, parser()->xr()->num_packets());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000474}
475
asapersson22ff75a2015-08-21 00:02:47 -0700476TEST_F(RtcpSenderTest, TestRegisterRtcpPacketTypeObserver) {
477 RtcpPacketTypeCounterObserverImpl observer;
sprang86fd9ed2015-09-29 04:45:43 -0700478 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800479 &observer, nullptr, &test_transport_,
480 RtcpIntervalConfig{}));
asapersson22ff75a2015-08-21 00:02:47 -0700481 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700482 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700483 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpPli));
484 EXPECT_EQ(1, parser()->pli()->num_packets());
485 EXPECT_EQ(kRemoteSsrc, observer.ssrc_);
486 EXPECT_EQ(1U, observer.counter_.pli_packets);
487 EXPECT_EQ(clock_.TimeInMilliseconds(),
488 observer.counter_.first_packet_time_ms);
489}
490
491TEST_F(RtcpSenderTest, SendTmmbr) {
492 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700493 rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
asapersson22ff75a2015-08-21 00:02:47 -0700494 rtcp_sender_->SetTargetBitrate(kBitrateBps);
495 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpTmmbr));
496 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200497 EXPECT_EQ(kSenderSsrc, parser()->tmmbr()->sender_ssrc());
498 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
499 EXPECT_EQ(kBitrateBps, parser()->tmmbr()->requests()[0].bitrate_bps());
asapersson22ff75a2015-08-21 00:02:47 -0700500 // TODO(asapersson): tmmbr_item()->Overhead() looks broken, always zero.
501}
502
503TEST_F(RtcpSenderTest, TmmbrIncludedInCompoundPacketIfEnabled) {
504 const unsigned int kBitrateBps = 312000;
pbosda903ea2015-10-02 02:36:56 -0700505 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
asapersson22ff75a2015-08-21 00:02:47 -0700506 EXPECT_FALSE(rtcp_sender_->TMMBR());
507 rtcp_sender_->SetTMMBRStatus(true);
508 EXPECT_TRUE(rtcp_sender_->TMMBR());
509 rtcp_sender_->SetTargetBitrate(kBitrateBps);
510 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
511 EXPECT_EQ(1, parser()->tmmbr()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200512 EXPECT_EQ(1U, parser()->tmmbr()->requests().size());
asapersson22ff75a2015-08-21 00:02:47 -0700513 // TMMBR should be included in each compound packet.
514 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
515 EXPECT_EQ(2, parser()->tmmbr()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700516
517 rtcp_sender_->SetTMMBRStatus(false);
518 EXPECT_FALSE(rtcp_sender_->TMMBR());
519}
520
521TEST_F(RtcpSenderTest, SendTmmbn) {
pbosda903ea2015-10-02 02:36:56 -0700522 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200523 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700524 std::vector<rtcp::TmmbItem> bounding_set;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200525 const uint32_t kBitrateBps = 32768000;
asapersson22ff75a2015-08-21 00:02:47 -0700526 const uint32_t kPacketOh = 40;
527 const uint32_t kSourceSsrc = 12345;
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200528 const rtcp::TmmbItem tmmbn(kSourceSsrc, kBitrateBps, kPacketOh);
danilchap6eaa3a42016-05-09 10:59:50 -0700529 bounding_set.push_back(tmmbn);
danilchap853ecb22016-08-22 08:26:15 -0700530 rtcp_sender_->SetTmmbn(bounding_set);
danilchap6eaa3a42016-05-09 10:59:50 -0700531
asapersson22ff75a2015-08-21 00:02:47 -0700532 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
533 EXPECT_EQ(1, parser()->sender_report()->num_packets());
534 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200535 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
536 EXPECT_EQ(1U, parser()->tmmbn()->items().size());
537 EXPECT_EQ(kBitrateBps, parser()->tmmbn()->items()[0].bitrate_bps());
538 EXPECT_EQ(kPacketOh, parser()->tmmbn()->items()[0].packet_overhead());
539 EXPECT_EQ(kSourceSsrc, parser()->tmmbn()->items()[0].ssrc());
asapersson22ff75a2015-08-21 00:02:47 -0700540}
541
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000542// This test is written to verify actual behaviour. It does not seem
543// to make much sense to send an empty TMMBN, since there is no place
544// to put an actual limit here. It's just information that no limit
545// is set, which is kind of the starting assumption.
546// See http://code.google.com/p/webrtc/issues/detail?id=468 for one
547// situation where this caused confusion.
548TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndEmpty) {
pbosda903ea2015-10-02 02:36:56 -0700549 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalov70ffead2016-07-20 15:26:59 +0200550 rtcp_sender_->SetSendingStatus(feedback_state(), true);
danilchap6eaa3a42016-05-09 10:59:50 -0700551 std::vector<rtcp::TmmbItem> bounding_set;
danilchap853ecb22016-08-22 08:26:15 -0700552 rtcp_sender_->SetTmmbn(bounding_set);
asapersson22ff75a2015-08-21 00:02:47 -0700553 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpSr));
554 EXPECT_EQ(1, parser()->sender_report()->num_packets());
555 EXPECT_EQ(1, parser()->tmmbn()->num_packets());
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200556 EXPECT_EQ(kSenderSsrc, parser()->tmmbn()->sender_ssrc());
557 EXPECT_EQ(0U, parser()->tmmbn()->items().size());
hta@webrtc.org65a4e4e2012-04-30 11:23:41 +0000558}
559
asapersson22ff75a2015-08-21 00:02:47 -0700560TEST_F(RtcpSenderTest, SendCompoundPliRemb) {
561 const int kBitrate = 261011;
562 std::vector<uint32_t> ssrcs;
563 ssrcs.push_back(kRemoteSsrc);
pbosda903ea2015-10-02 02:36:56 -0700564 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Danil Chapovalovf74d6412017-10-18 13:32:57 +0200565 rtcp_sender_->SetRemb(kBitrate, ssrcs);
asapersson22ff75a2015-08-21 00:02:47 -0700566 std::set<RTCPPacketType> packet_types;
567 packet_types.insert(kRtcpRemb);
568 packet_types.insert(kRtcpPli);
569 EXPECT_EQ(0, rtcp_sender_->SendCompoundRTCP(feedback_state(), packet_types));
Danil Chapovalovba6f7be2016-09-02 18:29:10 +0200570 EXPECT_EQ(1, parser()->remb()->num_packets());
asapersson22ff75a2015-08-21 00:02:47 -0700571 EXPECT_EQ(1, parser()->pli()->num_packets());
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000572}
Erik Språnga38233a2015-07-24 09:58:18 +0200573
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800574// This test is written to verify that BYE is always the last packet
575// type in a RTCP compoud packet. The rtcp_sender_ is recreated with
576// mock_transport, which is used to check for whether BYE at the end
577// of a RTCP compound packet.
578TEST_F(RtcpSenderTest, ByeMustBeLast) {
579 MockTransport mock_transport;
580 EXPECT_CALL(mock_transport, SendRtcp(_, _))
Yves Gerey665174f2018-06-19 15:03:05 +0200581 .WillOnce(Invoke([](const uint8_t* data, size_t len) {
582 const uint8_t* next_packet = data;
583 const uint8_t* const packet_end = data + len;
584 rtcp::CommonHeader packet;
585 while (next_packet < packet_end) {
586 EXPECT_TRUE(packet.Parse(next_packet, packet_end - next_packet));
587 next_packet = packet.NextPacket();
588 if (packet.type() ==
589 rtcp::Bye::kPacketType) // Main test expectation.
590 EXPECT_EQ(0, packet_end - next_packet)
591 << "Bye packet should be last in a compound RTCP packet.";
592 if (next_packet == packet_end) // Validate test was set correctly.
593 EXPECT_EQ(packet.type(), rtcp::Bye::kPacketType)
594 << "Last packet in this test expected to be Bye.";
595 }
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800596
Yves Gerey665174f2018-06-19 15:03:05 +0200597 return true;
598 }));
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800599
600 // Re-configure rtcp_sender_ with mock_transport_
601 rtcp_sender_.reset(new RTCPSender(false, &clock_, receive_statistics_.get(),
Jiawei Ou3587b832018-01-31 22:08:26 -0800602 nullptr, nullptr, &mock_transport,
603 RtcpIntervalConfig{}));
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800604 rtcp_sender_->SetSSRC(kSenderSsrc);
605 rtcp_sender_->SetRemoteSSRC(kRemoteSsrc);
danilchap71fead22016-08-18 02:01:49 -0700606 rtcp_sender_->SetTimestampOffset(kStartRtpTimestamp);
Ilya Nikolaevskiy5e58bcb2018-10-24 13:34:32 +0200607 rtcp_sender_->SetLastRtpTime(kRtpTimestamp, clock_.TimeInMilliseconds(),
608 /*paylpad_type=*/0);
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800609
Niels Möller44b384d2018-10-05 11:15:57 +0200610 // Set up REMB info to be included with BYE.
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800611 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
Niels Möller44b384d2018-10-05 11:15:57 +0200612 rtcp_sender_->SetRemb(1234, {});
aleungbroadsoft0e2e50c2016-02-18 08:33:26 -0800613 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpBye));
614}
615
sprang5e38c962016-12-01 05:18:09 -0800616TEST_F(RtcpSenderTest, SendXrWithTargetBitrate) {
617 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
618 const size_t kNumSpatialLayers = 2;
619 const size_t kNumTemporalLayers = 2;
Erik Språng566124a2018-04-23 12:32:22 +0200620 VideoBitrateAllocation allocation;
sprang5e38c962016-12-01 05:18:09 -0800621 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
622 uint32_t start_bitrate_bps = (sl + 1) * 100000;
623 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl)
624 allocation.SetBitrate(sl, tl, start_bitrate_bps + (tl * 20000));
625 }
626 rtcp_sender_->SetVideoBitrateAllocation(allocation);
627
628 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
629 EXPECT_EQ(1, parser()->xr()->num_packets());
630 EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
Danil Chapovalovd264df52018-06-14 12:59:38 +0200631 const absl::optional<rtcp::TargetBitrate>& target_bitrate =
sprang5e38c962016-12-01 05:18:09 -0800632 parser()->xr()->target_bitrate();
633 ASSERT_TRUE(target_bitrate);
634 const std::vector<rtcp::TargetBitrate::BitrateItem>& bitrates =
635 target_bitrate->GetTargetBitrates();
636 EXPECT_EQ(kNumSpatialLayers * kNumTemporalLayers, bitrates.size());
637
638 for (size_t sl = 0; sl < kNumSpatialLayers; ++sl) {
639 uint32_t start_bitrate_bps = (sl + 1) * 100000;
640 for (size_t tl = 0; tl < kNumTemporalLayers; ++tl) {
641 size_t index = (sl * kNumSpatialLayers) + tl;
642 const rtcp::TargetBitrate::BitrateItem& item = bitrates[index];
643 EXPECT_EQ(sl, item.spatial_layer);
644 EXPECT_EQ(tl, item.temporal_layer);
645 EXPECT_EQ(start_bitrate_bps + (tl * 20000),
646 item.target_bitrate_kbps * 1000);
647 }
648 }
649}
650
Erik Språng8782a582018-10-04 15:36:06 +0200651TEST_F(RtcpSenderTest, SendImmediateXrWithTargetBitrate) {
652 // Initialize. Send a first report right away.
653 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
654 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
655 clock_.AdvanceTimeMilliseconds(5);
656
657 // Video bitrate allocation generated, save until next time we send a report.
658 VideoBitrateAllocation allocation;
659 allocation.SetBitrate(0, 0, 100000);
660 rtcp_sender_->SetVideoBitrateAllocation(allocation);
661 // First seen instance will be sent immediately.
662 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
663 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
664 clock_.AdvanceTimeMilliseconds(5);
665
666 // Update bitrate of existing layer, does not quality for immediate sending.
667 allocation.SetBitrate(0, 0, 150000);
668 rtcp_sender_->SetVideoBitrateAllocation(allocation);
669 EXPECT_FALSE(rtcp_sender_->TimeToSendRTCPReport(false));
670
671 // A new spatial layer enabled, signal this as soon as possible.
672 allocation.SetBitrate(1, 0, 200000);
673 rtcp_sender_->SetVideoBitrateAllocation(allocation);
674 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
675 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
676 clock_.AdvanceTimeMilliseconds(5);
677
678 // Explicitly disable top layer. The same set of layers now has a bitrate
679 // defined, but the explicit 0 indicates shutdown. Signal immediately.
680 allocation.SetBitrate(1, 0, 0);
681 EXPECT_FALSE(rtcp_sender_->TimeToSendRTCPReport(false));
682 rtcp_sender_->SetVideoBitrateAllocation(allocation);
683 EXPECT_TRUE(rtcp_sender_->TimeToSendRTCPReport(false));
684}
685
Erik Språng1cd73912018-10-05 12:57:59 +0200686TEST_F(RtcpSenderTest, SendTargetBitrateExplicitZeroOnStreamRemoval) {
687 // Set up and send a bitrate allocation with two layers.
688
689 rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
690 VideoBitrateAllocation allocation;
691 allocation.SetBitrate(0, 0, 100000);
692 allocation.SetBitrate(1, 0, 200000);
693 rtcp_sender_->SetVideoBitrateAllocation(allocation);
694 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
695 absl::optional<rtcp::TargetBitrate> target_bitrate =
696 parser()->xr()->target_bitrate();
697 ASSERT_TRUE(target_bitrate);
698 std::vector<rtcp::TargetBitrate::BitrateItem> bitrates =
699 target_bitrate->GetTargetBitrates();
700 ASSERT_EQ(2u, bitrates.size());
701 EXPECT_EQ(bitrates[0].target_bitrate_kbps,
702 allocation.GetBitrate(0, 0) / 1000);
703 EXPECT_EQ(bitrates[1].target_bitrate_kbps,
704 allocation.GetBitrate(1, 0) / 1000);
705
706 // Create a new allocation, where the second stream is no longer available.
707 VideoBitrateAllocation new_allocation;
708 new_allocation.SetBitrate(0, 0, 150000);
709 rtcp_sender_->SetVideoBitrateAllocation(new_allocation);
710 EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state(), kRtcpReport));
711 target_bitrate = parser()->xr()->target_bitrate();
712 ASSERT_TRUE(target_bitrate);
713 bitrates = target_bitrate->GetTargetBitrates();
714
715 // Two bitrates should still be set, with an explicit entry indicating the
716 // removed stream is gone.
717 ASSERT_EQ(2u, bitrates.size());
718 EXPECT_EQ(bitrates[0].target_bitrate_kbps,
719 new_allocation.GetBitrate(0, 0) / 1000);
720 EXPECT_EQ(bitrates[1].target_bitrate_kbps, 0u);
721}
722
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000723} // namespace webrtc