blob: 41bc153790837651c55ee453e7afe2c3f80f8228 [file] [log] [blame]
hta@webrtc.org47059b52012-05-02 07:46:22 +00001/*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
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_receiver.h"
12
kwiberg84be5112016-04-27 01:19:58 -070013#include <memory>
14
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "api/array_view.h"
Henrik Boströmf2047872019-05-16 13:32:20 +020016#include "api/units/timestamp.h"
Erik Språngeeaa8f92018-05-17 12:35:56 +020017#include "api/video/video_bitrate_allocation.h"
Jiawei Ou4206a0a2018-07-20 15:49:43 -070018#include "api/video/video_bitrate_allocator.h"
Henrik Boströmf2047872019-05-16 13:32:20 +020019#include "modules/rtp_rtcp/include/report_block_data.h"
Sebastian Janssonef9daee2018-02-22 14:49:02 +010020#include "modules/rtp_rtcp/mocks/mock_rtcp_bandwidth_observer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "modules/rtp_rtcp/source/byte_io.h"
22#include "modules/rtp_rtcp/source/rtcp_packet.h"
23#include "modules/rtp_rtcp/source/rtcp_packet/app.h"
24#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
25#include "modules/rtp_rtcp/source/rtcp_packet/compound_packet.h"
26#include "modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.h"
27#include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
28#include "modules/rtp_rtcp/source/rtcp_packet/fir.h"
29#include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
30#include "modules/rtp_rtcp/source/rtcp_packet/pli.h"
31#include "modules/rtp_rtcp/source/rtcp_packet/rapid_resync_request.h"
32#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
33#include "modules/rtp_rtcp/source/rtcp_packet/remb.h"
34#include "modules/rtp_rtcp/source/rtcp_packet/sdes.h"
35#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
36#include "modules/rtp_rtcp/source/rtcp_packet/tmmbr.h"
37#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020038#include "modules/rtp_rtcp/source/time_util.h"
39#include "rtc_base/arraysize.h"
Henrik Boströmf2047872019-05-16 13:32:20 +020040#include "rtc_base/fake_clock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020041#include "rtc_base/random.h"
42#include "system_wrappers/include/ntp_time.h"
43#include "test/gmock.h"
44#include "test/gtest.h"
hta@webrtc.org47059b52012-05-02 07:46:22 +000045
46namespace webrtc {
danilchap1e714ae2016-09-05 09:57:22 -070047namespace {
hta@webrtc.org47059b52012-05-02 07:46:22 +000048
Henrik Boströmf2047872019-05-16 13:32:20 +020049using rtcp::ReceiveTimeInfo;
danilchap1e714ae2016-09-05 09:57:22 -070050using ::testing::_;
51using ::testing::AllOf;
52using ::testing::ElementsAreArray;
53using ::testing::Field;
Henrik Boströmf2047872019-05-16 13:32:20 +020054using ::testing::InSequence;
danilchap1e714ae2016-09-05 09:57:22 -070055using ::testing::IsEmpty;
56using ::testing::NiceMock;
57using ::testing::Property;
58using ::testing::SizeIs;
59using ::testing::StrEq;
60using ::testing::StrictMock;
61using ::testing::UnorderedElementsAre;
hta@webrtc.org47059b52012-05-02 07:46:22 +000062
danilchap1e714ae2016-09-05 09:57:22 -070063class MockRtcpPacketTypeCounterObserver : public RtcpPacketTypeCounterObserver {
hta@webrtc.org47059b52012-05-02 07:46:22 +000064 public:
danilchap1e714ae2016-09-05 09:57:22 -070065 MOCK_METHOD2(RtcpPacketTypesCounterUpdated,
66 void(uint32_t, const RtcpPacketTypeCounter&));
hta@webrtc.org47059b52012-05-02 07:46:22 +000067};
68
danilchap1e714ae2016-09-05 09:57:22 -070069class MockRtcpIntraFrameObserver : public RtcpIntraFrameObserver {
70 public:
71 MOCK_METHOD1(OnReceivedIntraFrameRequest, void(uint32_t));
danilchap1e714ae2016-09-05 09:57:22 -070072};
73
Elad Alon0a8562e2019-04-09 11:55:13 +020074class MockRtcpLossNotificationObserver : public RtcpLossNotificationObserver {
75 public:
76 ~MockRtcpLossNotificationObserver() override = default;
77 MOCK_METHOD4(OnReceivedLossNotification,
78 void(uint32_t ssrc,
79 uint16_t seq_num_of_last_decodable,
80 uint16_t seq_num_of_last_received,
81 bool decodability_flag));
82};
83
danilchap1e714ae2016-09-05 09:57:22 -070084class MockRtcpCallbackImpl : public RtcpStatisticsCallback {
85 public:
86 MOCK_METHOD2(StatisticsUpdated, void(const RtcpStatistics&, uint32_t));
Niels Möller4d7c4052019-08-05 12:45:19 +020087};
88
89class MockCnameCallbackImpl : public RtcpCnameCallback {
90 public:
91 MOCK_METHOD2(OnCname, void(uint32_t, absl::string_view));
danilchap1e714ae2016-09-05 09:57:22 -070092};
93
Henrik Boströmf2047872019-05-16 13:32:20 +020094class MockReportBlockDataObserverImpl : public ReportBlockDataObserver {
95 public:
96 MOCK_METHOD1(OnReportBlockDataUpdated, void(ReportBlockData));
97};
98
danilchap1e714ae2016-09-05 09:57:22 -070099class MockTransportFeedbackObserver : public TransportFeedbackObserver {
100 public:
Erik Språng30a276b2019-04-23 12:00:11 +0200101 MOCK_METHOD1(OnAddPacket, void(const RtpPacketSendInfo&));
danilchap1e714ae2016-09-05 09:57:22 -0700102 MOCK_METHOD1(OnTransportFeedback, void(const rtcp::TransportFeedback&));
103};
104
danilchap1e714ae2016-09-05 09:57:22 -0700105class MockModuleRtpRtcp : public RTCPReceiver::ModuleRtpRtcp {
106 public:
107 MOCK_METHOD1(SetTmmbn, void(std::vector<rtcp::TmmbItem>));
108 MOCK_METHOD0(OnRequestSendReport, void());
109 MOCK_METHOD1(OnReceivedNack, void(const std::vector<uint16_t>&));
110 MOCK_METHOD1(OnReceivedRtcpReportBlocks, void(const ReportBlockList&));
111};
112
spranga790d832016-12-02 07:29:44 -0800113class MockVideoBitrateAllocationObserver
114 : public VideoBitrateAllocationObserver {
115 public:
116 MOCK_METHOD1(OnBitrateAllocationUpdated,
Erik Språng566124a2018-04-23 12:32:22 +0200117 void(const VideoBitrateAllocation& allocation));
spranga790d832016-12-02 07:29:44 -0800118};
119
danilchap1e714ae2016-09-05 09:57:22 -0700120// SSRC of remote peer, that sends rtcp packet to the rtcp receiver under test.
121constexpr uint32_t kSenderSsrc = 0x10203;
122// SSRCs of local peer, that rtcp packet addressed to.
123constexpr uint32_t kReceiverMainSsrc = 0x123456;
124// RtcpReceiver can accept several ssrc, e.g. regular and rtx streams.
125constexpr uint32_t kReceiverExtraSsrc = 0x1234567;
126// SSRCs to ignore (i.e. not configured in RtcpReceiver).
127constexpr uint32_t kNotToUsSsrc = 0x654321;
128constexpr uint32_t kUnknownSenderSsrc = 0x54321;
129
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800130constexpr int64_t kRtcpIntervalMs = 1000;
131
danilchap1e714ae2016-09-05 09:57:22 -0700132} // namespace
133
hta@webrtc.org47059b52012-05-02 07:46:22 +0000134class RtcpReceiverTest : public ::testing::Test {
135 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000136 RtcpReceiverTest()
danilchap1e714ae2016-09-05 09:57:22 -0700137 : system_clock_(1335900000),
Mirko Bonadei3b676722019-07-12 17:35:05 +0000138 rtcp_receiver_(
139 [&] {
140 RtpRtcp::Configuration config;
141 config.clock = &system_clock_;
142 config.receiver_only = false;
143 config.rtcp_packet_type_counter_observer =
144 &packet_type_counter_observer_;
145 config.bandwidth_callback = &bandwidth_observer_;
146 config.intra_frame_callback = &intra_frame_observer_;
147 config.rtcp_loss_notification_observer =
148 &rtcp_loss_notification_observer_;
149 config.transport_feedback_callback =
150 &transport_feedback_observer_;
151 config.bitrate_allocation_observer =
152 &bitrate_allocation_observer_;
153 config.rtcp_report_interval_ms = kRtcpIntervalMs;
Erik Språng54d5d2c2019-08-20 17:22:36 +0200154 config.local_media_ssrc = kReceiverMainSsrc;
Mirko Bonadei3b676722019-07-12 17:35:05 +0000155 config.rtx_send_ssrc = kReceiverExtraSsrc;
156 return config;
157 }(),
158 &rtp_rtcp_impl_) {}
danilchap1e714ae2016-09-05 09:57:22 -0700159 void SetUp() {
danilchap1e714ae2016-09-05 09:57:22 -0700160 rtcp_receiver_.SetRemoteSSRC(kSenderSsrc);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000161 }
Erik Språng737336d2016-07-29 12:59:36 +0200162
danilchap1e714ae2016-09-05 09:57:22 -0700163 void InjectRtcpPacket(rtc::ArrayView<const uint8_t> raw) {
164 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
hta@webrtc.org47059b52012-05-02 07:46:22 +0000165 }
166
danilchap1e714ae2016-09-05 09:57:22 -0700167 void InjectRtcpPacket(const rtcp::RtcpPacket& packet) {
168 rtc::Buffer raw = packet.Build();
169 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
170 }
171
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000172 SimulatedClock system_clock_;
danilchap1e714ae2016-09-05 09:57:22 -0700173 // Callbacks to packet_type_counter_observer are frequent but most of the time
174 // are not interesting.
175 NiceMock<MockRtcpPacketTypeCounterObserver> packet_type_counter_observer_;
176 StrictMock<MockRtcpBandwidthObserver> bandwidth_observer_;
177 StrictMock<MockRtcpIntraFrameObserver> intra_frame_observer_;
Elad Alon0a8562e2019-04-09 11:55:13 +0200178 StrictMock<MockRtcpLossNotificationObserver> rtcp_loss_notification_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700179 StrictMock<MockTransportFeedbackObserver> transport_feedback_observer_;
spranga790d832016-12-02 07:29:44 -0800180 StrictMock<MockVideoBitrateAllocationObserver> bitrate_allocation_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700181 StrictMock<MockModuleRtpRtcp> rtp_rtcp_impl_;
hta@webrtc.org47059b52012-05-02 07:46:22 +0000182
danilchap1e714ae2016-09-05 09:57:22 -0700183 RTCPReceiver rtcp_receiver_;
184};
hta@webrtc.org47059b52012-05-02 07:46:22 +0000185
186TEST_F(RtcpReceiverTest, BrokenPacketIsIgnored) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000187 const uint8_t bad_packet[] = {0, 0, 0, 0};
danilchap1e714ae2016-09-05 09:57:22 -0700188 EXPECT_CALL(packet_type_counter_observer_,
189 RtcpPacketTypesCounterUpdated(_, _))
190 .Times(0);
191 InjectRtcpPacket(bad_packet);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000192}
193
danilchap50da1d32016-03-10 13:13:52 -0800194TEST_F(RtcpReceiverTest, InvalidFeedbackPacketIsIgnored) {
195 // Too short feedback packet.
danilchap1e714ae2016-09-05 09:57:22 -0700196 const uint8_t bad_packet[] = {0x81, rtcp::Rtpfb::kPacketType, 0, 0};
197
198 // TODO(danilchap): Add expectation RtcpPacketTypesCounterUpdated
199 // is not called once parser would be adjusted to avoid that callback on
200 // semi-valid packets.
201 InjectRtcpPacket(bad_packet);
danilchap50da1d32016-03-10 13:13:52 -0800202}
203
hta@webrtc.org47059b52012-05-02 07:46:22 +0000204TEST_F(RtcpReceiverTest, InjectSrPacket) {
danilchapa04d9c32017-07-25 04:03:39 -0700205 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
danilchap1e714ae2016-09-05 09:57:22 -0700206
207 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000208 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700209 sr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700210
211 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
212 EXPECT_CALL(bandwidth_observer_,
213 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
214 InjectRtcpPacket(sr);
215
danilchapa04d9c32017-07-25 04:03:39 -0700216 EXPECT_TRUE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
hta@webrtc.org47059b52012-05-02 07:46:22 +0000217}
218
danilchap1e714ae2016-09-05 09:57:22 -0700219TEST_F(RtcpReceiverTest, InjectSrPacketFromUnknownSender) {
220 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000221 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700222 sr.SetSenderSsrc(kUnknownSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700223
224 // The parser will handle report blocks in Sender Report from other than his
225 // expected peer.
226 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
227 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, now));
228 InjectRtcpPacket(sr);
229
230 // But will not flag that he's gotten sender information.
danilchapa04d9c32017-07-25 04:03:39 -0700231 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000232}
233
Danil Chapovalova094fd12016-02-22 18:59:36 +0100234TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesRTT) {
235 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100236 const int64_t kRttMs = r.Rand(1, 9 * 3600 * 1000);
237 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
238 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100239
Danil Chapovalova094fd12016-02-22 18:59:36 +0100240 int64_t rtt_ms = 0;
241 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700242 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100243
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200244 uint32_t sent_ntp =
245 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100246 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
247
248 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700249 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100250 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700251 block.SetMediaSsrc(kReceiverMainSsrc);
252 block.SetLastSr(sent_ntp);
253 block.SetDelayLastSr(kDelayNtp);
254 sr.AddReportBlock(block);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100255
danilchap1e714ae2016-09-05 09:57:22 -0700256 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
257 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
258 InjectRtcpPacket(sr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100259
260 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700261 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100262 EXPECT_NEAR(kRttMs, rtt_ms, 1);
263}
264
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100265TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesNegativeRTTAsOne) {
266 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100267 const int64_t kRttMs = r.Rand(-3600 * 1000, -1);
268 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
269 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
270
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100271 int64_t rtt_ms = 0;
272 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700273 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100274
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200275 uint32_t sent_ntp =
276 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100277 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
278
279 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700280 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100281 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700282 block.SetMediaSsrc(kReceiverMainSsrc);
283 block.SetLastSr(sent_ntp);
284 block.SetDelayLastSr(kDelayNtp);
285 sr.AddReportBlock(block);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100286
danilchap1e714ae2016-09-05 09:57:22 -0700287 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
288 EXPECT_CALL(bandwidth_observer_,
289 OnReceivedRtcpReceiverReport(SizeIs(1), _, _));
290 InjectRtcpPacket(sr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100291
292 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700293 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100294 EXPECT_EQ(1, rtt_ms);
295}
296
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100297TEST_F(
298 RtcpReceiverTest,
299 TwoReportBlocksWithLastOneWithoutLastSrCalculatesRttForBandwidthObserver) {
300 const int64_t kRttMs = 120;
301 const uint32_t kDelayNtp = 123000;
302 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
303
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200304 uint32_t sent_ntp =
305 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100306 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
307
308 rtcp::SenderReport sr;
309 sr.SetSenderSsrc(kSenderSsrc);
310 rtcp::ReportBlock block;
311 block.SetMediaSsrc(kReceiverMainSsrc);
312 block.SetLastSr(sent_ntp);
313 block.SetDelayLastSr(kDelayNtp);
314 sr.AddReportBlock(block);
315 block.SetMediaSsrc(kReceiverExtraSsrc);
316 block.SetLastSr(0);
317 sr.AddReportBlock(block);
318
319 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
320 EXPECT_CALL(bandwidth_observer_,
321 OnReceivedRtcpReceiverReport(SizeIs(2), kRttMs, _));
322 InjectRtcpPacket(sr);
323}
324
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000325TEST_F(RtcpReceiverTest, InjectRrPacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700326 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000327 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700328 rr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700329
330 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
331 EXPECT_CALL(bandwidth_observer_,
332 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
333 InjectRtcpPacket(rr);
334
danilchap1e714ae2016-09-05 09:57:22 -0700335 std::vector<RTCPReportBlock> report_blocks;
336 rtcp_receiver_.StatisticsReceived(&report_blocks);
337 EXPECT_TRUE(report_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000338}
339
340TEST_F(RtcpReceiverTest, InjectRrPacketWithReportBlockNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700341 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000342 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700343 rb.SetMediaSsrc(kNotToUsSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000344 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700345 rr.SetSenderSsrc(kSenderSsrc);
346 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000347
danilchap1e714ae2016-09-05 09:57:22 -0700348 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
349 EXPECT_CALL(bandwidth_observer_,
350 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
351 InjectRtcpPacket(rr);
352
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200353 EXPECT_EQ(0, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000354 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700355 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000356 EXPECT_TRUE(received_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000357}
358
359TEST_F(RtcpReceiverTest, InjectRrPacketWithOneReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700360 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000361
362 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700363 rb.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000364 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700365 rr.SetSenderSsrc(kSenderSsrc);
366 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000367
danilchap1e714ae2016-09-05 09:57:22 -0700368 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
369 EXPECT_CALL(bandwidth_observer_,
370 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
371 InjectRtcpPacket(rr);
372
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200373 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
374 std::vector<RTCPReportBlock> received_blocks;
375 rtcp_receiver_.StatisticsReceived(&received_blocks);
376 EXPECT_EQ(1u, received_blocks.size());
377}
378
379TEST_F(RtcpReceiverTest, InjectSrPacketWithOneReportBlock) {
380 int64_t now = system_clock_.TimeInMilliseconds();
381
382 rtcp::ReportBlock rb;
383 rb.SetMediaSsrc(kReceiverMainSsrc);
384 rtcp::SenderReport sr;
385 sr.SetSenderSsrc(kSenderSsrc);
386 sr.AddReportBlock(rb);
387
388 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
389 EXPECT_CALL(bandwidth_observer_,
390 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
391 InjectRtcpPacket(sr);
392
393 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000394 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700395 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000396 EXPECT_EQ(1u, received_blocks.size());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000397}
398
399TEST_F(RtcpReceiverTest, InjectRrPacketWithTwoReportBlocks) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000400 const uint16_t kSequenceNumbers[] = {10, 12423};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000401 const uint32_t kCumLost[] = {13, 555};
402 const uint8_t kFracLost[] = {20, 11};
danilchap1e714ae2016-09-05 09:57:22 -0700403 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000404
405 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700406 rb1.SetMediaSsrc(kReceiverMainSsrc);
407 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
408 rb1.SetFractionLost(10);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000409
410 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700411 rb2.SetMediaSsrc(kReceiverExtraSsrc);
412 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
413 rb2.SetFractionLost(0);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000414
415 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700416 rr1.SetSenderSsrc(kSenderSsrc);
417 rr1.AddReportBlock(rb1);
418 rr1.AddReportBlock(rb2);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000419
danilchap1e714ae2016-09-05 09:57:22 -0700420 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
421 EXPECT_CALL(bandwidth_observer_,
422 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
423 InjectRtcpPacket(rr1);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000424
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200425 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700426 std::vector<RTCPReportBlock> received_blocks;
427 rtcp_receiver_.StatisticsReceived(&received_blocks);
428 EXPECT_THAT(received_blocks,
srte3e69e5c2017-08-09 06:13:45 -0700429 UnorderedElementsAre(Field(&RTCPReportBlock::fraction_lost, 0),
430 Field(&RTCPReportBlock::fraction_lost, 10)));
danilchap1e714ae2016-09-05 09:57:22 -0700431
432 // Insert next receiver report with same ssrc but new values.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000433 rtcp::ReportBlock rb3;
danilchap822a16f2016-09-27 09:27:47 -0700434 rb3.SetMediaSsrc(kReceiverMainSsrc);
435 rb3.SetExtHighestSeqNum(kSequenceNumbers[0]);
436 rb3.SetFractionLost(kFracLost[0]);
437 rb3.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000438
439 rtcp::ReportBlock rb4;
danilchap822a16f2016-09-27 09:27:47 -0700440 rb4.SetMediaSsrc(kReceiverExtraSsrc);
441 rb4.SetExtHighestSeqNum(kSequenceNumbers[1]);
442 rb4.SetFractionLost(kFracLost[1]);
443 rb4.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000444
445 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700446 rr2.SetSenderSsrc(kSenderSsrc);
447 rr2.AddReportBlock(rb3);
448 rr2.AddReportBlock(rb4);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000449
danilchap1e714ae2016-09-05 09:57:22 -0700450 // Advance time to make 1st sent time and 2nd sent time different.
451 system_clock_.AdvanceTimeMilliseconds(500);
452 now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000453
danilchap1e714ae2016-09-05 09:57:22 -0700454 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
455 EXPECT_CALL(bandwidth_observer_,
456 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
457 InjectRtcpPacket(rr2);
458
459 received_blocks.clear();
460 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000461 EXPECT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700462 EXPECT_THAT(
463 received_blocks,
464 UnorderedElementsAre(
465 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
466 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
467 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
468 Field(&RTCPReportBlock::extended_highest_sequence_number,
469 kSequenceNumbers[0])),
470 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverExtraSsrc),
471 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
472 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
473 Field(&RTCPReportBlock::extended_highest_sequence_number,
474 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000475}
476
477TEST_F(RtcpReceiverTest, InjectRrPacketsFromTwoRemoteSsrcs) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000478 const uint32_t kSenderSsrc2 = 0x20304;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000479 const uint16_t kSequenceNumbers[] = {10, 12423};
Sebastian Jansson9701e0c2018-08-09 11:21:11 +0200480 const int32_t kCumLost[] = {13, 555};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000481 const uint8_t kFracLost[] = {20, 11};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000482
483 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700484 rb1.SetMediaSsrc(kReceiverMainSsrc);
485 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
486 rb1.SetFractionLost(kFracLost[0]);
487 rb1.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000488 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700489 rr1.SetSenderSsrc(kSenderSsrc);
490 rr1.AddReportBlock(rb1);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000491
danilchap1e714ae2016-09-05 09:57:22 -0700492 int64_t now = system_clock_.TimeInMilliseconds();
493
494 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
495 EXPECT_CALL(bandwidth_observer_,
496 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
497 InjectRtcpPacket(rr1);
498
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200499 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000500
501 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700502 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000503 EXPECT_EQ(1u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700504 EXPECT_EQ(kSenderSsrc, received_blocks[0].sender_ssrc);
505 EXPECT_EQ(kReceiverMainSsrc, received_blocks[0].source_ssrc);
506 EXPECT_EQ(kFracLost[0], received_blocks[0].fraction_lost);
507 EXPECT_EQ(kCumLost[0], received_blocks[0].packets_lost);
508 EXPECT_EQ(kSequenceNumbers[0],
509 received_blocks[0].extended_highest_sequence_number);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000510
511 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700512 rb2.SetMediaSsrc(kReceiverMainSsrc);
513 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
514 rb2.SetFractionLost(kFracLost[1]);
515 rb2.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000516 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700517 rr2.SetSenderSsrc(kSenderSsrc2);
518 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -0700519
520 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
521 EXPECT_CALL(bandwidth_observer_,
522 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
523 InjectRtcpPacket(rr2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000524
525 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700526 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000527 ASSERT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700528 EXPECT_THAT(
529 received_blocks,
530 UnorderedElementsAre(
531 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
532 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc),
533 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
534 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
535 Field(&RTCPReportBlock::extended_highest_sequence_number,
536 kSequenceNumbers[0])),
537 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
538 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc2),
539 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
540 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
541 Field(&RTCPReportBlock::extended_highest_sequence_number,
542 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000543}
544
545TEST_F(RtcpReceiverTest, GetRtt) {
danilchap28b03eb2016-10-05 06:59:44 -0700546 const uint32_t kSentCompactNtp = 0x1234;
547 const uint32_t kDelayCompactNtp = 0x222;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000548 // No report block received.
Erik Språng6b8d3552015-09-24 15:06:57 +0200549 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700550 -1, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000551
552 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700553 rb.SetMediaSsrc(kReceiverMainSsrc);
danilchap28b03eb2016-10-05 06:59:44 -0700554 rb.SetLastSr(kSentCompactNtp);
555 rb.SetDelayLastSr(kDelayCompactNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700556
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000557 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700558 rr.SetSenderSsrc(kSenderSsrc);
559 rr.AddReportBlock(rb);
danilchap1e714ae2016-09-05 09:57:22 -0700560 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000561
danilchap1e714ae2016-09-05 09:57:22 -0700562 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
563 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
564 InjectRtcpPacket(rr);
565
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200566 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700567 EXPECT_EQ(
568 0, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000569}
570
danilchap1e714ae2016-09-05 09:57:22 -0700571// Ij packets are ignored.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000572TEST_F(RtcpReceiverTest, InjectIjWithNoItem) {
danilchapf8506cb2015-11-13 07:33:20 -0800573 rtcp::ExtendedJitterReport ij;
danilchap1e714ae2016-09-05 09:57:22 -0700574 InjectRtcpPacket(ij);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000575}
576
danilchap1e714ae2016-09-05 09:57:22 -0700577// App packets are ignored.
578TEST_F(RtcpReceiverTest, InjectApp) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000579 rtcp::App app;
danilchap822a16f2016-09-27 09:27:47 -0700580 app.SetSubType(30);
581 app.SetName(0x17a177e);
danilchap1e714ae2016-09-05 09:57:22 -0700582 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
danilchap822a16f2016-09-27 09:27:47 -0700583 app.SetData(kData, sizeof(kData));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000584
danilchap1e714ae2016-09-05 09:57:22 -0700585 InjectRtcpPacket(app);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000586}
587
588TEST_F(RtcpReceiverTest, InjectSdesWithOneChunk) {
danilchap1e714ae2016-09-05 09:57:22 -0700589 const char kCname[] = "alice@host";
Niels Möller4d7c4052019-08-05 12:45:19 +0200590 MockCnameCallbackImpl callback;
591 rtcp_receiver_.RegisterRtcpCnameCallback(&callback);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000592 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700593 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000594
Niels Möller4d7c4052019-08-05 12:45:19 +0200595 EXPECT_CALL(callback, OnCname(kSenderSsrc, StrEq(kCname)));
danilchap1e714ae2016-09-05 09:57:22 -0700596 InjectRtcpPacket(sdes);
597
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000598 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700599 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
600 EXPECT_EQ(0, strncmp(cName, kCname, RTCP_CNAME_SIZE));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000601}
602
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000603TEST_F(RtcpReceiverTest, InjectByePacket_RemovesCname) {
danilchap1e714ae2016-09-05 09:57:22 -0700604 const char kCname[] = "alice@host";
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000605 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700606 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000607
danilchap1e714ae2016-09-05 09:57:22 -0700608 InjectRtcpPacket(sdes);
609
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000610 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700611 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000612
613 // Verify that BYE removes the CNAME.
614 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700615 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700616
617 InjectRtcpPacket(bye);
618
619 EXPECT_EQ(-1, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000620}
621
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000622TEST_F(RtcpReceiverTest, InjectByePacket_RemovesReportBlocks) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000623 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700624 rb1.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000625 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700626 rb2.SetMediaSsrc(kReceiverExtraSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000627 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700628 rr.SetSenderSsrc(kSenderSsrc);
629 rr.AddReportBlock(rb1);
630 rr.AddReportBlock(rb2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000631
danilchap1e714ae2016-09-05 09:57:22 -0700632 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
633 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
634 InjectRtcpPacket(rr);
635
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000636 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700637 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000638 EXPECT_EQ(2u, received_blocks.size());
639
640 // Verify that BYE removes the report blocks.
641 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700642 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700643
644 InjectRtcpPacket(bye);
645
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000646 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700647 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000648 EXPECT_TRUE(received_blocks.empty());
649
danilchap1e714ae2016-09-05 09:57:22 -0700650 // Inject packet again.
651 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
652 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
653 InjectRtcpPacket(rr);
654
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000655 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700656 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000657 EXPECT_EQ(2u, received_blocks.size());
658}
659
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200660TEST_F(RtcpReceiverTest, InjectByePacketRemovesReferenceTimeInfo) {
661 rtcp::ExtendedReports xr;
662 xr.SetSenderSsrc(kSenderSsrc);
663 rtcp::Rrtr rrtr;
664 rrtr.SetNtp(NtpTime(0x10203, 0x40506));
665 xr.SetRrtr(rrtr);
666 InjectRtcpPacket(xr);
667
668 rtcp::Bye bye;
669 bye.SetSenderSsrc(kSenderSsrc);
670 InjectRtcpPacket(bye);
671
672 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
673}
674
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000675TEST_F(RtcpReceiverTest, InjectPliPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000676 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700677 pli.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700678
679 EXPECT_CALL(
680 packet_type_counter_observer_,
681 RtcpPacketTypesCounterUpdated(
682 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 1)));
683 EXPECT_CALL(intra_frame_observer_,
684 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
685 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000686}
687
688TEST_F(RtcpReceiverTest, PliPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000689 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700690 pli.SetMediaSsrc(kNotToUsSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700691
692 EXPECT_CALL(
693 packet_type_counter_observer_,
694 RtcpPacketTypesCounterUpdated(
695 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 0)));
696 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
697 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000698}
699
700TEST_F(RtcpReceiverTest, InjectFirPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000701 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700702 fir.AddRequestTo(kReceiverMainSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700703
704 EXPECT_CALL(
705 packet_type_counter_observer_,
706 RtcpPacketTypesCounterUpdated(
707 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::fir_packets, 1)));
708 EXPECT_CALL(intra_frame_observer_,
709 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
710 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000711}
712
713TEST_F(RtcpReceiverTest, FirPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000714 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700715 fir.AddRequestTo(kNotToUsSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700716
717 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
718 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000719}
720
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100721TEST_F(RtcpReceiverTest, ExtendedReportsPacketWithZeroReportBlocksIgnored) {
722 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700723 xr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700724
725 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000726}
727
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100728TEST_F(RtcpReceiverTest, InjectExtendedReportsReceiverReferenceTimePacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700729 const NtpTime kNtp(0x10203, 0x40506);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000730 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700731 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100732 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700733 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700734 xr.SetRrtr(rrtr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000735
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200736 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
737 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
738 EXPECT_THAT(last_xr_rtis, IsEmpty());
danilchap1e714ae2016-09-05 09:57:22 -0700739
740 InjectRtcpPacket(xr);
741
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200742 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
743 ASSERT_THAT(last_xr_rtis, SizeIs(1));
744 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
745 EXPECT_EQ(CompactNtp(kNtp), last_xr_rtis[0].last_rr);
746 EXPECT_EQ(0U, last_xr_rtis[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000747}
748
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100749TEST_F(RtcpReceiverTest, ExtendedReportsDlrrPacketNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700750 // Allow calculate rtt using dlrr/rrtr, simulating media receiver side.
751 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000752
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100753 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700754 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700755 xr.AddDlrrItem(ReceiveTimeInfo(kNotToUsSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700756
757 InjectRtcpPacket(xr);
758
759 int64_t rtt_ms = 0;
760 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000761}
762
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100763TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithSubBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700764 const uint32_t kLastRR = 0x12345;
765 const uint32_t kDelay = 0x23456;
766 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
767 int64_t rtt_ms = 0;
768 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000769
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100770 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700771 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700772 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
danilchap1e714ae2016-09-05 09:57:22 -0700773
774 InjectRtcpPacket(xr);
775
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200776 uint32_t compact_ntp_now =
777 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700778 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
779 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
780 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000781}
782
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100783TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithMultipleSubBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700784 const uint32_t kLastRR = 0x12345;
785 const uint32_t kDelay = 0x56789;
786 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000787
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100788 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700789 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700790 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
791 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 1, 0x12345, 0x67890));
792 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 2, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700793
794 InjectRtcpPacket(xr);
795
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200796 uint32_t compact_ntp_now =
797 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700798 int64_t rtt_ms = 0;
799 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
800 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
801 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000802}
803
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100804TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithMultipleReportBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700805 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000806
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000807 rtcp::Rrtr rrtr;
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100808 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700809 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700810 xr.SetRrtr(rrtr);
811 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700812
813 InjectRtcpPacket(xr);
814
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200815 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
816 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
817 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700818 int64_t rtt_ms = 0;
819 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000820}
821
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100822TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithUnknownReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700823 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000824
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000825 rtcp::Rrtr rrtr;
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100826 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700827 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700828 xr.SetRrtr(rrtr);
829 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700830
danilchap69e59e62016-02-17 03:11:42 -0800831 rtc::Buffer packet = xr.Build();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000832 // Modify the DLRR block to have an unsupported block type, from 5 to 6.
danilchap1e714ae2016-09-05 09:57:22 -0700833 ASSERT_EQ(5, packet.data()[20]);
834 packet.data()[20] = 6;
835 InjectRtcpPacket(packet);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000836
danilchap1e714ae2016-09-05 09:57:22 -0700837 // Validate Rrtr was received and processed.
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200838 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
839 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
840 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700841 // Validate Dlrr report wasn't processed.
842 int64_t rtt_ms = 0;
843 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000844}
845
danilchap1e714ae2016-09-05 09:57:22 -0700846TEST_F(RtcpReceiverTest, TestExtendedReportsRrRttInitiallyFalse) {
847 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
848
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000849 int64_t rtt_ms;
danilchap1e714ae2016-09-05 09:57:22 -0700850 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000851}
852
danilchap1e714ae2016-09-05 09:57:22 -0700853TEST_F(RtcpReceiverTest, RttCalculatedAfterExtendedReportsDlrr) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100854 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100855 const int64_t kRttMs = rand.Rand(1, 9 * 3600 * 1000);
856 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
857 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700858 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200859 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalova094fd12016-02-22 18:59:36 +0100860 uint32_t sent_ntp = CompactNtp(now);
861 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
862
Danil Chapovalova094fd12016-02-22 18:59:36 +0100863 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700864 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700865 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700866
867 InjectRtcpPacket(xr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100868
869 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700870 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100871 EXPECT_NEAR(kRttMs, rtt_ms, 1);
872}
873
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100874TEST_F(RtcpReceiverTest, XrDlrrCalculatesNegativeRttAsOne) {
875 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100876 const int64_t kRttMs = rand.Rand(-3600 * 1000, -1);
877 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
878 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200879 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100880 uint32_t sent_ntp = CompactNtp(now);
881 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
danilchap1e714ae2016-09-05 09:57:22 -0700882 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100883
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100884 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700885 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700886 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700887
888 InjectRtcpPacket(xr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100889
890 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700891 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100892 EXPECT_EQ(1, rtt_ms);
893}
894
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200895TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfoInitiallyEmpty) {
896 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000897}
898
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200899TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfo) {
Danil Chapovalovfc47ed62015-12-07 14:46:35 +0100900 const NtpTime kNtp(0x10203, 0x40506);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100901 const uint32_t kNtpMid = CompactNtp(kNtp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000902
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000903 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700904 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100905 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700906 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700907 xr.SetRrtr(rrtr);
danilchap1e714ae2016-09-05 09:57:22 -0700908
909 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000910
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000911 system_clock_.AdvanceTimeMilliseconds(1000);
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200912
913 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
914 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
915 ASSERT_THAT(last_xr_rtis, SizeIs(1));
916 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
917 EXPECT_EQ(kNtpMid, last_xr_rtis[0].last_rr);
918 EXPECT_EQ(65536U, last_xr_rtis[0].delay_since_last_rr);
919}
920
921TEST_F(RtcpReceiverTest,
922 ReceivedRrtrFromSameSsrcUpdatesReceivedReferenceTimeInfo) {
923 const NtpTime kNtp1(0x10203, 0x40506);
924 const NtpTime kNtp2(0x11223, 0x44556);
925 const int64_t kDelayMs = 2000;
926
927 rtcp::ExtendedReports xr;
928 xr.SetSenderSsrc(kSenderSsrc);
929 rtcp::Rrtr rrtr1;
930 rrtr1.SetNtp(kNtp1);
931 xr.SetRrtr(rrtr1);
932 InjectRtcpPacket(xr);
933 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
934 rtcp::Rrtr rrtr2;
935 rrtr2.SetNtp(kNtp2);
936 xr.SetRrtr(rrtr2);
937 InjectRtcpPacket(xr);
938 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
939
940 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
941 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
942 ASSERT_THAT(last_xr_rtis, SizeIs(1));
943 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
944 EXPECT_EQ(CompactNtp(kNtp2), last_xr_rtis[0].last_rr);
945 EXPECT_EQ(kDelayMs * 65536 / 1000, last_xr_rtis[0].delay_since_last_rr);
946}
947
948TEST_F(RtcpReceiverTest, StoresLastReceivedRrtrPerSsrc) {
949 const size_t kNumBufferedReports = 1;
950 const size_t kNumReports =
951 rtcp::ExtendedReports::kMaxNumberOfDlrrItems + kNumBufferedReports;
952 for (size_t i = 0; i < kNumReports; ++i) {
953 rtcp::ExtendedReports xr;
954 xr.SetSenderSsrc(i * 100);
955 rtcp::Rrtr rrtr;
956 rrtr.SetNtp(NtpTime(i * 200, i * 300));
957 xr.SetRrtr(rrtr);
958 InjectRtcpPacket(xr);
959 system_clock_.AdvanceTimeMilliseconds(1000);
960 }
961
962 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
963 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
964 ASSERT_THAT(last_xr_rtis,
965 SizeIs(rtcp::ExtendedReports::kMaxNumberOfDlrrItems));
966 for (size_t i = 0; i < rtcp::ExtendedReports::kMaxNumberOfDlrrItems; ++i) {
967 EXPECT_EQ(i * 100, last_xr_rtis[i].ssrc);
968 EXPECT_EQ(CompactNtp(NtpTime(i * 200, i * 300)), last_xr_rtis[i].last_rr);
969 EXPECT_EQ(65536U * (kNumReports - i), last_xr_rtis[i].delay_since_last_rr);
970 }
971
972 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
973 ASSERT_THAT(last_xr_rtis, SizeIs(kNumBufferedReports));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000974}
975
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000976TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000977 const uint16_t kSequenceNumber = 1234;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000978 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000979
980 // No RR received, shouldn't trigger a timeout.
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800981 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
982 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000983
984 // Add a RR and advance the clock just enough to not trigger a timeout.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000985 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700986 rb1.SetMediaSsrc(kReceiverMainSsrc);
987 rb1.SetExtHighestSeqNum(kSequenceNumber);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000988 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700989 rr1.SetSenderSsrc(kSenderSsrc);
990 rr1.AddReportBlock(rb1);
danilchap1e714ae2016-09-05 09:57:22 -0700991
992 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
993 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
994 InjectRtcpPacket(rr1);
995
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000996 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs - 1);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800997 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
998 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000999
1000 // Add a RR with the same extended max as the previous RR to trigger a
1001 // sequence number timeout, but not a RR timeout.
danilchap1e714ae2016-09-05 09:57:22 -07001002 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1003 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1004 InjectRtcpPacket(rr1);
1005
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001006 system_clock_.AdvanceTimeMilliseconds(2);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001007 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1008 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001009
1010 // Advance clock enough to trigger an RR timeout too.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001011 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001012 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001013
1014 // We should only get one timeout even though we still haven't received a new
1015 // RR.
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001016 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1017 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001018
1019 // Add a new RR with increase sequence number to reset timers.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001020 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001021 rb2.SetMediaSsrc(kReceiverMainSsrc);
1022 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001023 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001024 rr2.SetSenderSsrc(kSenderSsrc);
1025 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001026
1027 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1028 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1029 InjectRtcpPacket(rr2);
1030
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001031 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1032 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001033
1034 // Verify we can get a timeout again once we've received new RR.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001035 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -07001036 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1037 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1038 InjectRtcpPacket(rr2);
1039
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001040 system_clock_.AdvanceTimeMilliseconds(kRtcpIntervalMs + 1);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001041 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1042 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
danilchap1e714ae2016-09-05 09:57:22 -07001043
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001044 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001045 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001046}
1047
hta@webrtc.org47059b52012-05-02 07:46:22 +00001048TEST_F(RtcpReceiverTest, TmmbrReceivedWithNoIncomingPacket) {
danilchap1e714ae2016-09-05 09:57:22 -07001049 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001050}
1051
1052TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) {
danilchap1e714ae2016-09-05 09:57:22 -07001053 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001054 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001055 tmmbr.SetSenderSsrc(kSenderSsrc);
1056 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001057 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001058 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001059 rtcp::CompoundPacket compound;
1060 compound.Append(&sr);
1061 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001062
danilchap1e714ae2016-09-05 09:57:22 -07001063 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1064 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(SizeIs(1)));
1065 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1066 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1067 InjectRtcpPacket(compound);
1068
1069 std::vector<rtcp::TmmbItem> tmmbr_received = rtcp_receiver_.TmmbrReceived();
1070 ASSERT_EQ(1u, tmmbr_received.size());
1071 EXPECT_EQ(kBitrateBps, tmmbr_received[0].bitrate_bps());
1072 EXPECT_EQ(kSenderSsrc, tmmbr_received[0].ssrc());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001073}
1074
1075TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -07001076 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001077 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001078 tmmbr.SetSenderSsrc(kSenderSsrc);
1079 tmmbr.AddTmmbr(rtcp::TmmbItem(kNotToUsSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001080
1081 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001082 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001083 rtcp::CompoundPacket compound;
1084 compound.Append(&sr);
1085 compound.Append(&tmmbr);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001086
danilchap1e714ae2016-09-05 09:57:22 -07001087 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1088 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1089 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1090 InjectRtcpPacket(compound);
1091
1092 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001093}
1094
1095TEST_F(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001096 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001097 tmmbr.SetSenderSsrc(kSenderSsrc);
1098 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 0, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001099 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001100 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001101 rtcp::CompoundPacket compound;
1102 compound.Append(&sr);
1103 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001104
danilchap1e714ae2016-09-05 09:57:22 -07001105 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1106 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1107 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1108 InjectRtcpPacket(compound);
1109
1110 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001111}
1112
hta@webrtc.org404843e2012-05-02 09:56:45 +00001113TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001114 // Inject 3 packets "from" kSenderSsrc, kSenderSsrc+1, kSenderSsrc+2.
hta@webrtc.org404843e2012-05-02 09:56:45 +00001115 // The times of arrival are starttime + 0, starttime + 5 and starttime + 10.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001116 for (uint32_t ssrc = kSenderSsrc; ssrc < kSenderSsrc + 3; ++ssrc) {
1117 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001118 tmmbr.SetSenderSsrc(ssrc);
1119 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 30000, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001120 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001121 sr.SetSenderSsrc(ssrc);
danilchap7a4116a2016-03-14 08:19:28 -07001122 rtcp::CompoundPacket compound;
1123 compound.Append(&sr);
1124 compound.Append(&tmmbr);
danilchap1e714ae2016-09-05 09:57:22 -07001125
1126 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1127 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(_));
1128 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1129 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_));
1130 InjectRtcpPacket(compound);
1131
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001132 // 5 seconds between each packet.
1133 system_clock_.AdvanceTimeMilliseconds(5000);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001134 }
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001135 // It is now starttime + 15.
danilchap1e714ae2016-09-05 09:57:22 -07001136 std::vector<rtcp::TmmbItem> candidate_set = rtcp_receiver_.TmmbrReceived();
1137 ASSERT_EQ(3u, candidate_set.size());
1138 EXPECT_EQ(30000U, candidate_set[0].bitrate_bps());
1139
hta@webrtc.org404843e2012-05-02 09:56:45 +00001140 // We expect the timeout to be 25 seconds. Advance the clock by 12
1141 // seconds, timing out the first packet.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001142 system_clock_.AdvanceTimeMilliseconds(12000);
danilchap1e714ae2016-09-05 09:57:22 -07001143 candidate_set = rtcp_receiver_.TmmbrReceived();
1144 ASSERT_EQ(2u, candidate_set.size());
danilchap287e5482016-08-16 15:15:39 -07001145 EXPECT_EQ(kSenderSsrc + 1, candidate_set[0].ssrc());
hta@webrtc.org404843e2012-05-02 09:56:45 +00001146}
1147
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001148TEST_F(RtcpReceiverTest, Callbacks) {
danilchap1e714ae2016-09-05 09:57:22 -07001149 MockRtcpCallbackImpl callback;
1150 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001151
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001152 const uint8_t kFractionLoss = 3;
1153 const uint32_t kCumulativeLoss = 7;
1154 const uint32_t kJitter = 9;
1155 const uint16_t kSequenceNumber = 1234;
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001156
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001157 // First packet, all numbers should just propagate.
1158 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -07001159 rb1.SetMediaSsrc(kReceiverMainSsrc);
1160 rb1.SetExtHighestSeqNum(kSequenceNumber);
1161 rb1.SetFractionLost(kFractionLoss);
1162 rb1.SetCumulativeLost(kCumulativeLoss);
1163 rb1.SetJitter(kJitter);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001164
1165 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -07001166 rr1.SetSenderSsrc(kSenderSsrc);
1167 rr1.AddReportBlock(rb1);
srte186d9c32017-08-04 05:03:53 -07001168 EXPECT_CALL(callback,
1169 StatisticsUpdated(
1170 AllOf(Field(&RtcpStatistics::fraction_lost, kFractionLoss),
1171 Field(&RtcpStatistics::packets_lost, kCumulativeLoss),
1172 Field(&RtcpStatistics::extended_highest_sequence_number,
1173 kSequenceNumber),
1174 Field(&RtcpStatistics::jitter, kJitter)),
1175 kReceiverMainSsrc));
danilchap1e714ae2016-09-05 09:57:22 -07001176 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1177 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1178 InjectRtcpPacket(rr1);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001179
danilchap1e714ae2016-09-05 09:57:22 -07001180 rtcp_receiver_.RegisterRtcpStatisticsCallback(nullptr);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001181
danilchap1e714ae2016-09-05 09:57:22 -07001182 // Add arbitrary numbers, callback should not be called.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001183 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001184 rb2.SetMediaSsrc(kReceiverMainSsrc);
1185 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
1186 rb2.SetFractionLost(42);
1187 rb2.SetCumulativeLost(137);
1188 rb2.SetJitter(4711);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001189
1190 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001191 rr2.SetSenderSsrc(kSenderSsrc);
1192 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001193
1194 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1195 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1196 EXPECT_CALL(callback, StatisticsUpdated(_, _)).Times(0);
1197 InjectRtcpPacket(rr2);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001198}
hta@webrtc.org404843e2012-05-02 09:56:45 +00001199
Henrik Boströmf2047872019-05-16 13:32:20 +02001200TEST_F(RtcpReceiverTest,
1201 VerifyBlockAndTimestampObtainedFromReportBlockDataObserver) {
1202 MockReportBlockDataObserverImpl observer;
1203 rtcp_receiver_.SetReportBlockDataObserver(&observer);
1204
1205 const uint8_t kFractionLoss = 3;
1206 const uint32_t kCumulativeLoss = 7;
1207 const uint32_t kJitter = 9;
1208 const uint16_t kSequenceNumber = 1234;
1209 const int64_t kUtcNowUs = 42;
1210
1211 // The "report_block_timestamp_utc_us" is obtained from the global UTC clock
1212 // (not the simulcated |system_clock_|) and requires a scoped fake clock.
1213 rtc::ScopedFakeClock fake_clock;
1214 fake_clock.SetTime(Timestamp::us(kUtcNowUs));
1215
1216 rtcp::ReportBlock rtcp_block;
1217 rtcp_block.SetMediaSsrc(kReceiverMainSsrc);
1218 rtcp_block.SetExtHighestSeqNum(kSequenceNumber);
1219 rtcp_block.SetFractionLost(kFractionLoss);
1220 rtcp_block.SetCumulativeLost(kCumulativeLoss);
1221 rtcp_block.SetJitter(kJitter);
1222
1223 rtcp::ReceiverReport rtcp_report;
1224 rtcp_report.SetSenderSsrc(kSenderSsrc);
1225 rtcp_report.AddReportBlock(rtcp_block);
1226 EXPECT_CALL(observer, OnReportBlockDataUpdated)
1227 .WillOnce([&](ReportBlockData report_block_data) {
1228 const auto& report_block = report_block_data.report_block();
1229 EXPECT_EQ(rtcp_block.source_ssrc(), report_block.source_ssrc);
1230 EXPECT_EQ(kSenderSsrc, report_block.sender_ssrc);
1231 EXPECT_EQ(rtcp_block.fraction_lost(), report_block.fraction_lost);
1232 EXPECT_EQ(rtcp_block.cumulative_lost_signed(),
1233 report_block.packets_lost);
1234 EXPECT_EQ(rtcp_block.extended_high_seq_num(),
1235 report_block.extended_highest_sequence_number);
1236 EXPECT_EQ(rtcp_block.jitter(), report_block.jitter);
1237 EXPECT_EQ(kUtcNowUs, report_block_data.report_block_timestamp_utc_us());
1238 // No RTT is calculated in this test.
1239 EXPECT_EQ(0u, report_block_data.num_rtts());
1240 });
1241 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1242 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1243 InjectRtcpPacket(rtcp_report);
1244}
1245
1246TEST_F(RtcpReceiverTest, VerifyRttObtainedFromReportBlockDataObserver) {
1247 MockReportBlockDataObserverImpl observer;
1248 rtcp_receiver_.SetReportBlockDataObserver(&observer);
1249
1250 const int64_t kRttMs = 120;
1251 const uint32_t kDelayNtp = 123000;
1252 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
1253
1254 uint32_t sent_ntp =
1255 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
1256 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
1257
1258 rtcp::SenderReport sr;
1259 sr.SetSenderSsrc(kSenderSsrc);
1260 rtcp::ReportBlock block;
1261 block.SetMediaSsrc(kReceiverMainSsrc);
1262 block.SetLastSr(sent_ntp);
1263 block.SetDelayLastSr(kDelayNtp);
1264 sr.AddReportBlock(block);
1265 block.SetMediaSsrc(kReceiverExtraSsrc);
1266 block.SetLastSr(0);
1267 sr.AddReportBlock(block);
1268
1269 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1270 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1271 InSequence sequence;
1272 EXPECT_CALL(observer, OnReportBlockDataUpdated)
1273 .WillOnce([&](ReportBlockData report_block_data) {
1274 EXPECT_EQ(kReceiverMainSsrc,
1275 report_block_data.report_block().source_ssrc);
1276 EXPECT_EQ(1u, report_block_data.num_rtts());
1277 EXPECT_EQ(kRttMs, report_block_data.min_rtt_ms());
1278 EXPECT_EQ(kRttMs, report_block_data.max_rtt_ms());
1279 EXPECT_EQ(kRttMs, report_block_data.sum_rtt_ms());
1280 EXPECT_EQ(kRttMs, report_block_data.last_rtt_ms());
1281 });
1282 EXPECT_CALL(observer, OnReportBlockDataUpdated)
1283 .WillOnce([](ReportBlockData report_block_data) {
1284 EXPECT_EQ(kReceiverExtraSsrc,
1285 report_block_data.report_block().source_ssrc);
1286 EXPECT_EQ(0u, report_block_data.num_rtts());
1287 });
1288 InjectRtcpPacket(sr);
1289}
1290
1291TEST_F(RtcpReceiverTest, GetReportBlockDataAfterOneReportBlock) {
1292 const uint16_t kSequenceNumber = 1234;
1293
1294 rtcp::ReportBlock rtcp_block;
1295 rtcp_block.SetMediaSsrc(kReceiverMainSsrc);
1296 rtcp_block.SetExtHighestSeqNum(kSequenceNumber);
1297
1298 rtcp::ReceiverReport rtcp_report;
1299 rtcp_report.SetSenderSsrc(kSenderSsrc);
1300 rtcp_report.AddReportBlock(rtcp_block);
1301 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1302 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1303 InjectRtcpPacket(rtcp_report);
1304
1305 auto report_block_datas = rtcp_receiver_.GetLatestReportBlockData();
1306 ASSERT_THAT(report_block_datas, SizeIs(1));
1307 EXPECT_EQ(kReceiverMainSsrc,
1308 report_block_datas[0].report_block().source_ssrc);
1309 EXPECT_EQ(
1310 kSequenceNumber,
1311 report_block_datas[0].report_block().extended_highest_sequence_number);
1312}
1313
1314TEST_F(RtcpReceiverTest, GetReportBlockDataAfterTwoReportBlocksOfSameSsrc) {
1315 const uint16_t kSequenceNumber1 = 1234;
1316 const uint16_t kSequenceNumber2 = 1235;
1317
1318 rtcp::ReportBlock rtcp_block1;
1319 rtcp_block1.SetMediaSsrc(kReceiverMainSsrc);
1320 rtcp_block1.SetExtHighestSeqNum(kSequenceNumber1);
1321
1322 rtcp::ReceiverReport rtcp_report1;
1323 rtcp_report1.SetSenderSsrc(kSenderSsrc);
1324 rtcp_report1.AddReportBlock(rtcp_block1);
1325 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1326 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1327 InjectRtcpPacket(rtcp_report1);
1328
1329 // Inject a report block with an increased the sequence number for the same
1330 // source SSRC.
1331 rtcp::ReportBlock rtcp_block2;
1332 rtcp_block2.SetMediaSsrc(kReceiverMainSsrc);
1333 rtcp_block2.SetExtHighestSeqNum(kSequenceNumber2);
1334
1335 rtcp::ReceiverReport rtcp_report2;
1336 rtcp_report2.SetSenderSsrc(kSenderSsrc);
1337 rtcp_report2.AddReportBlock(rtcp_block2);
1338 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1339 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1340 InjectRtcpPacket(rtcp_report2);
1341
1342 // Only the latest block should be returned.
1343 auto report_block_datas = rtcp_receiver_.GetLatestReportBlockData();
1344 ASSERT_THAT(report_block_datas, SizeIs(1));
1345 EXPECT_EQ(kReceiverMainSsrc,
1346 report_block_datas[0].report_block().source_ssrc);
1347 EXPECT_EQ(
1348 kSequenceNumber2,
1349 report_block_datas[0].report_block().extended_highest_sequence_number);
1350}
1351
1352TEST_F(RtcpReceiverTest,
1353 GetReportBlockDataAfterTwoReportBlocksOfDifferentSsrcs) {
1354 const uint16_t kSequenceNumber1 = 1234;
1355 const uint16_t kSequenceNumber2 = 42;
1356
1357 rtcp::ReportBlock rtcp_block1;
1358 rtcp_block1.SetMediaSsrc(kReceiverMainSsrc);
1359 rtcp_block1.SetExtHighestSeqNum(kSequenceNumber1);
1360
1361 rtcp::ReceiverReport rtcp_report1;
1362 rtcp_report1.SetSenderSsrc(kSenderSsrc);
1363 rtcp_report1.AddReportBlock(rtcp_block1);
1364 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1365 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1366 InjectRtcpPacket(rtcp_report1);
1367
1368 // Inject a report block for a different source SSRC.
1369 rtcp::ReportBlock rtcp_block2;
1370 rtcp_block2.SetMediaSsrc(kReceiverExtraSsrc);
1371 rtcp_block2.SetExtHighestSeqNum(kSequenceNumber2);
1372
1373 rtcp::ReceiverReport rtcp_report2;
1374 rtcp_report2.SetSenderSsrc(kSenderSsrc);
1375 rtcp_report2.AddReportBlock(rtcp_block2);
1376 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1377 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1378 InjectRtcpPacket(rtcp_report2);
1379
1380 // Both report blocks should be returned.
1381 auto report_block_datas = rtcp_receiver_.GetLatestReportBlockData();
1382 ASSERT_THAT(report_block_datas, SizeIs(2));
1383 EXPECT_EQ(kReceiverMainSsrc,
1384 report_block_datas[0].report_block().source_ssrc);
1385 EXPECT_EQ(
1386 kSequenceNumber1,
1387 report_block_datas[0].report_block().extended_highest_sequence_number);
1388 EXPECT_EQ(kReceiverExtraSsrc,
1389 report_block_datas[1].report_block().source_ssrc);
1390 EXPECT_EQ(
1391 kSequenceNumber2,
1392 report_block_datas[1].report_block().extended_highest_sequence_number);
1393}
1394
sprang49f9cdb2015-10-01 03:06:57 -07001395TEST_F(RtcpReceiverTest, ReceivesTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001396 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001397 packet.SetMediaSsrc(kReceiverMainSsrc);
1398 packet.SetSenderSsrc(kSenderSsrc);
1399 packet.SetBase(1, 1000);
1400 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001401
danilchap1e714ae2016-09-05 09:57:22 -07001402 EXPECT_CALL(
1403 transport_feedback_observer_,
1404 OnTransportFeedback(AllOf(
1405 Property(&rtcp::TransportFeedback::media_ssrc, kReceiverMainSsrc),
1406 Property(&rtcp::TransportFeedback::sender_ssrc, kSenderSsrc))));
1407 InjectRtcpPacket(packet);
sprang49f9cdb2015-10-01 03:06:57 -07001408}
1409
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001410TEST_F(RtcpReceiverTest, ReceivesRemb) {
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001411 const uint32_t kBitrateBps = 500000;
1412 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001413 remb.SetSenderSsrc(kSenderSsrc);
1414 remb.SetBitrateBps(kBitrateBps);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001415
danilchap1e714ae2016-09-05 09:57:22 -07001416 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1417 InjectRtcpPacket(remb);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001418}
1419
sprang49f9cdb2015-10-01 03:06:57 -07001420TEST_F(RtcpReceiverTest, HandlesInvalidTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001421 // Send a compound packet with a TransportFeedback followed by something else.
1422 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001423 packet.SetMediaSsrc(kReceiverMainSsrc);
1424 packet.SetSenderSsrc(kSenderSsrc);
1425 packet.SetBase(1, 1000);
1426 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001427
1428 static uint32_t kBitrateBps = 50000;
1429 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001430 remb.SetSenderSsrc(kSenderSsrc);
1431 remb.SetBitrateBps(kBitrateBps);
danilchap7a4116a2016-03-14 08:19:28 -07001432 rtcp::CompoundPacket compound;
1433 compound.Append(&packet);
1434 compound.Append(&remb);
1435 rtc::Buffer built_packet = compound.Build();
sprang49f9cdb2015-10-01 03:06:57 -07001436
1437 // Modify the TransportFeedback packet so that it is invalid.
1438 const size_t kStatusCountOffset = 14;
Yves Gerey665174f2018-06-19 15:03:05 +02001439 ByteWriter<uint16_t>::WriteBigEndian(&built_packet.data()[kStatusCountOffset],
1440 42);
sprang49f9cdb2015-10-01 03:06:57 -07001441
danilchap1e714ae2016-09-05 09:57:22 -07001442 // Stress no transport feedback is expected.
1443 EXPECT_CALL(transport_feedback_observer_, OnTransportFeedback(_)).Times(0);
1444 // But remb should be processed and cause a callback
1445 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1446 InjectRtcpPacket(built_packet);
sprang49f9cdb2015-10-01 03:06:57 -07001447}
1448
danilchap1e714ae2016-09-05 09:57:22 -07001449TEST_F(RtcpReceiverTest, Nack) {
1450 const uint16_t kNackList1[] = {1, 2, 3, 5};
danilchap142f0192016-10-20 08:22:42 -07001451 const uint16_t kNackList23[] = {5, 7, 30, 40, 41, 58, 59, 61, 63};
1452 const size_t kNackListLength2 = 4;
1453 const size_t kNackListLength3 = arraysize(kNackList23) - kNackListLength2;
danilchap1e714ae2016-09-05 09:57:22 -07001454 std::set<uint16_t> nack_set;
1455 nack_set.insert(std::begin(kNackList1), std::end(kNackList1));
danilchap142f0192016-10-20 08:22:42 -07001456 nack_set.insert(std::begin(kNackList23), std::end(kNackList23));
danilchap1e714ae2016-09-05 09:57:22 -07001457
danilchap142f0192016-10-20 08:22:42 -07001458 rtcp::Nack nack1;
1459 nack1.SetSenderSsrc(kSenderSsrc);
1460 nack1.SetMediaSsrc(kReceiverMainSsrc);
1461 nack1.SetPacketIds(kNackList1, arraysize(kNackList1));
danilchap1e714ae2016-09-05 09:57:22 -07001462
1463 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList1)));
danilchap1e714ae2016-09-05 09:57:22 -07001464 EXPECT_CALL(packet_type_counter_observer_,
1465 RtcpPacketTypesCounterUpdated(
1466 kReceiverMainSsrc,
1467 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
danilchap142f0192016-10-20 08:22:42 -07001468 arraysize(kNackList1)),
1469 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1470 arraysize(kNackList1)))));
1471 InjectRtcpPacket(nack1);
1472
1473 rtcp::Nack nack2;
1474 nack2.SetSenderSsrc(kSenderSsrc);
1475 nack2.SetMediaSsrc(kReceiverMainSsrc);
1476 nack2.SetPacketIds(kNackList23, kNackListLength2);
1477
1478 rtcp::Nack nack3;
1479 nack3.SetSenderSsrc(kSenderSsrc);
1480 nack3.SetMediaSsrc(kReceiverMainSsrc);
1481 nack3.SetPacketIds(kNackList23 + kNackListLength2, kNackListLength3);
1482
1483 rtcp::CompoundPacket two_nacks;
1484 two_nacks.Append(&nack2);
1485 two_nacks.Append(&nack3);
1486
1487 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList23)));
1488 EXPECT_CALL(packet_type_counter_observer_,
1489 RtcpPacketTypesCounterUpdated(
1490 kReceiverMainSsrc,
1491 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
1492 arraysize(kNackList1) + arraysize(kNackList23)),
danilchap1e714ae2016-09-05 09:57:22 -07001493 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1494 nack_set.size()))));
danilchap142f0192016-10-20 08:22:42 -07001495 InjectRtcpPacket(two_nacks);
danilchap1e714ae2016-09-05 09:57:22 -07001496}
1497
1498TEST_F(RtcpReceiverTest, NackNotForUsIgnored) {
1499 const uint16_t kNackList1[] = {1, 2, 3, 5};
1500 const size_t kNackListLength1 = std::end(kNackList1) - std::begin(kNackList1);
1501
1502 rtcp::Nack nack;
danilchap822a16f2016-09-27 09:27:47 -07001503 nack.SetSenderSsrc(kSenderSsrc);
1504 nack.SetMediaSsrc(kNotToUsSsrc);
1505 nack.SetPacketIds(kNackList1, kNackListLength1);
danilchap1e714ae2016-09-05 09:57:22 -07001506
1507 EXPECT_CALL(packet_type_counter_observer_,
1508 RtcpPacketTypesCounterUpdated(
1509 _, Field(&RtcpPacketTypeCounter::nack_requests, 0)));
1510 InjectRtcpPacket(nack);
1511}
1512
1513TEST_F(RtcpReceiverTest, ForceSenderReport) {
1514 rtcp::RapidResyncRequest rr;
danilchap822a16f2016-09-27 09:27:47 -07001515 rr.SetSenderSsrc(kSenderSsrc);
1516 rr.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -07001517
1518 EXPECT_CALL(rtp_rtcp_impl_, OnRequestSendReport());
1519 InjectRtcpPacket(rr);
1520}
hta@webrtc.org47059b52012-05-02 07:46:22 +00001521
spranga790d832016-12-02 07:29:44 -08001522TEST_F(RtcpReceiverTest, ReceivesTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001523 VideoBitrateAllocation expected_allocation;
spranga790d832016-12-02 07:29:44 -08001524 expected_allocation.SetBitrate(0, 0, 10000);
1525 expected_allocation.SetBitrate(0, 1, 20000);
1526 expected_allocation.SetBitrate(1, 0, 40000);
1527 expected_allocation.SetBitrate(1, 1, 80000);
1528
1529 rtcp::TargetBitrate bitrate;
1530 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1531 bitrate.AddTargetBitrate(0, 1, expected_allocation.GetBitrate(0, 1) / 1000);
1532 bitrate.AddTargetBitrate(1, 0, expected_allocation.GetBitrate(1, 0) / 1000);
1533 bitrate.AddTargetBitrate(1, 1, expected_allocation.GetBitrate(1, 1) / 1000);
1534
1535 rtcp::ExtendedReports xr;
1536 xr.SetTargetBitrate(bitrate);
1537
sprangb32aaf92017-08-28 05:49:12 -07001538 // Wrong sender ssrc, target bitrate should be discarded.
1539 xr.SetSenderSsrc(kSenderSsrc + 1);
1540 EXPECT_CALL(bitrate_allocation_observer_,
1541 OnBitrateAllocationUpdated(expected_allocation))
1542 .Times(0);
1543 InjectRtcpPacket(xr);
1544
1545 // Set correct ssrc, callback should be called once.
1546 xr.SetSenderSsrc(kSenderSsrc);
spranga790d832016-12-02 07:29:44 -08001547 EXPECT_CALL(bitrate_allocation_observer_,
1548 OnBitrateAllocationUpdated(expected_allocation));
1549 InjectRtcpPacket(xr);
1550}
1551
sprang6d314c72016-12-06 06:08:53 -08001552TEST_F(RtcpReceiverTest, HandlesIncorrectTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001553 VideoBitrateAllocation expected_allocation;
sprang6d314c72016-12-06 06:08:53 -08001554 expected_allocation.SetBitrate(0, 0, 10000);
1555
1556 rtcp::TargetBitrate bitrate;
1557 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1558 bitrate.AddTargetBitrate(0, kMaxTemporalStreams, 20000);
1559 bitrate.AddTargetBitrate(kMaxSpatialLayers, 0, 40000);
1560
1561 rtcp::ExtendedReports xr;
1562 xr.SetTargetBitrate(bitrate);
sprangb32aaf92017-08-28 05:49:12 -07001563 xr.SetSenderSsrc(kSenderSsrc);
sprang6d314c72016-12-06 06:08:53 -08001564
1565 EXPECT_CALL(bitrate_allocation_observer_,
1566 OnBitrateAllocationUpdated(expected_allocation));
1567 InjectRtcpPacket(xr);
1568}
1569
hta@webrtc.org47059b52012-05-02 07:46:22 +00001570} // namespace webrtc