blob: 8a2a89e8928ebba5654911e52d3c5aae54374a7c [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));
87 MOCK_METHOD2(CNameChanged, void(const char*, uint32_t));
88};
89
Henrik Boströmf2047872019-05-16 13:32:20 +020090class MockReportBlockDataObserverImpl : public ReportBlockDataObserver {
91 public:
92 MOCK_METHOD1(OnReportBlockDataUpdated, void(ReportBlockData));
93};
94
danilchap1e714ae2016-09-05 09:57:22 -070095class MockTransportFeedbackObserver : public TransportFeedbackObserver {
96 public:
Erik Språng30a276b2019-04-23 12:00:11 +020097 MOCK_METHOD1(OnAddPacket, void(const RtpPacketSendInfo&));
danilchap1e714ae2016-09-05 09:57:22 -070098 MOCK_METHOD1(OnTransportFeedback, void(const rtcp::TransportFeedback&));
elad.alonf9490002017-03-06 05:32:21 -080099 MOCK_CONST_METHOD0(GetTransportFeedbackVector, std::vector<PacketFeedback>());
danilchap1e714ae2016-09-05 09:57:22 -0700100};
101
danilchap1e714ae2016-09-05 09:57:22 -0700102class MockModuleRtpRtcp : public RTCPReceiver::ModuleRtpRtcp {
103 public:
104 MOCK_METHOD1(SetTmmbn, void(std::vector<rtcp::TmmbItem>));
105 MOCK_METHOD0(OnRequestSendReport, void());
106 MOCK_METHOD1(OnReceivedNack, void(const std::vector<uint16_t>&));
107 MOCK_METHOD1(OnReceivedRtcpReportBlocks, void(const ReportBlockList&));
108};
109
spranga790d832016-12-02 07:29:44 -0800110class MockVideoBitrateAllocationObserver
111 : public VideoBitrateAllocationObserver {
112 public:
113 MOCK_METHOD1(OnBitrateAllocationUpdated,
Erik Språng566124a2018-04-23 12:32:22 +0200114 void(const VideoBitrateAllocation& allocation));
spranga790d832016-12-02 07:29:44 -0800115};
116
danilchap1e714ae2016-09-05 09:57:22 -0700117// SSRC of remote peer, that sends rtcp packet to the rtcp receiver under test.
118constexpr uint32_t kSenderSsrc = 0x10203;
119// SSRCs of local peer, that rtcp packet addressed to.
120constexpr uint32_t kReceiverMainSsrc = 0x123456;
121// RtcpReceiver can accept several ssrc, e.g. regular and rtx streams.
122constexpr uint32_t kReceiverExtraSsrc = 0x1234567;
123// SSRCs to ignore (i.e. not configured in RtcpReceiver).
124constexpr uint32_t kNotToUsSsrc = 0x654321;
125constexpr uint32_t kUnknownSenderSsrc = 0x54321;
126
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800127constexpr int64_t kRtcpIntervalMs = 1000;
128
danilchap1e714ae2016-09-05 09:57:22 -0700129} // namespace
130
hta@webrtc.org47059b52012-05-02 07:46:22 +0000131class RtcpReceiverTest : public ::testing::Test {
132 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000133 RtcpReceiverTest()
danilchap1e714ae2016-09-05 09:57:22 -0700134 : system_clock_(1335900000),
Mirko Bonadei3b676722019-07-12 17:35:05 +0000135 rtcp_receiver_(
136 [&] {
137 RtpRtcp::Configuration config;
138 config.clock = &system_clock_;
139 config.receiver_only = false;
140 config.rtcp_packet_type_counter_observer =
141 &packet_type_counter_observer_;
142 config.bandwidth_callback = &bandwidth_observer_;
143 config.intra_frame_callback = &intra_frame_observer_;
144 config.rtcp_loss_notification_observer =
145 &rtcp_loss_notification_observer_;
146 config.transport_feedback_callback =
147 &transport_feedback_observer_;
148 config.bitrate_allocation_observer =
149 &bitrate_allocation_observer_;
150 config.rtcp_report_interval_ms = kRtcpIntervalMs;
151 config.media_send_ssrc = kReceiverMainSsrc;
152 config.rtx_send_ssrc = kReceiverExtraSsrc;
153 return config;
154 }(),
155 &rtp_rtcp_impl_) {}
danilchap1e714ae2016-09-05 09:57:22 -0700156 void SetUp() {
danilchap1e714ae2016-09-05 09:57:22 -0700157 rtcp_receiver_.SetRemoteSSRC(kSenderSsrc);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000158 }
Erik Språng737336d2016-07-29 12:59:36 +0200159
danilchap1e714ae2016-09-05 09:57:22 -0700160 void InjectRtcpPacket(rtc::ArrayView<const uint8_t> raw) {
161 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
hta@webrtc.org47059b52012-05-02 07:46:22 +0000162 }
163
danilchap1e714ae2016-09-05 09:57:22 -0700164 void InjectRtcpPacket(const rtcp::RtcpPacket& packet) {
165 rtc::Buffer raw = packet.Build();
166 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
167 }
168
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000169 SimulatedClock system_clock_;
danilchap1e714ae2016-09-05 09:57:22 -0700170 // Callbacks to packet_type_counter_observer are frequent but most of the time
171 // are not interesting.
172 NiceMock<MockRtcpPacketTypeCounterObserver> packet_type_counter_observer_;
173 StrictMock<MockRtcpBandwidthObserver> bandwidth_observer_;
174 StrictMock<MockRtcpIntraFrameObserver> intra_frame_observer_;
Elad Alon0a8562e2019-04-09 11:55:13 +0200175 StrictMock<MockRtcpLossNotificationObserver> rtcp_loss_notification_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700176 StrictMock<MockTransportFeedbackObserver> transport_feedback_observer_;
spranga790d832016-12-02 07:29:44 -0800177 StrictMock<MockVideoBitrateAllocationObserver> bitrate_allocation_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700178 StrictMock<MockModuleRtpRtcp> rtp_rtcp_impl_;
hta@webrtc.org47059b52012-05-02 07:46:22 +0000179
danilchap1e714ae2016-09-05 09:57:22 -0700180 RTCPReceiver rtcp_receiver_;
181};
hta@webrtc.org47059b52012-05-02 07:46:22 +0000182
183TEST_F(RtcpReceiverTest, BrokenPacketIsIgnored) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000184 const uint8_t bad_packet[] = {0, 0, 0, 0};
danilchap1e714ae2016-09-05 09:57:22 -0700185 EXPECT_CALL(packet_type_counter_observer_,
186 RtcpPacketTypesCounterUpdated(_, _))
187 .Times(0);
188 InjectRtcpPacket(bad_packet);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000189}
190
danilchap50da1d32016-03-10 13:13:52 -0800191TEST_F(RtcpReceiverTest, InvalidFeedbackPacketIsIgnored) {
192 // Too short feedback packet.
danilchap1e714ae2016-09-05 09:57:22 -0700193 const uint8_t bad_packet[] = {0x81, rtcp::Rtpfb::kPacketType, 0, 0};
194
195 // TODO(danilchap): Add expectation RtcpPacketTypesCounterUpdated
196 // is not called once parser would be adjusted to avoid that callback on
197 // semi-valid packets.
198 InjectRtcpPacket(bad_packet);
danilchap50da1d32016-03-10 13:13:52 -0800199}
200
hta@webrtc.org47059b52012-05-02 07:46:22 +0000201TEST_F(RtcpReceiverTest, InjectSrPacket) {
danilchapa04d9c32017-07-25 04:03:39 -0700202 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
danilchap1e714ae2016-09-05 09:57:22 -0700203
204 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000205 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700206 sr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700207
208 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
209 EXPECT_CALL(bandwidth_observer_,
210 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
211 InjectRtcpPacket(sr);
212
danilchapa04d9c32017-07-25 04:03:39 -0700213 EXPECT_TRUE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
hta@webrtc.org47059b52012-05-02 07:46:22 +0000214}
215
danilchap1e714ae2016-09-05 09:57:22 -0700216TEST_F(RtcpReceiverTest, InjectSrPacketFromUnknownSender) {
217 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000218 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700219 sr.SetSenderSsrc(kUnknownSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700220
221 // The parser will handle report blocks in Sender Report from other than his
222 // expected peer.
223 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
224 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, now));
225 InjectRtcpPacket(sr);
226
227 // But will not flag that he's gotten sender information.
danilchapa04d9c32017-07-25 04:03:39 -0700228 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000229}
230
Danil Chapovalova094fd12016-02-22 18:59:36 +0100231TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesRTT) {
232 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100233 const int64_t kRttMs = r.Rand(1, 9 * 3600 * 1000);
234 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
235 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100236
Danil Chapovalova094fd12016-02-22 18:59:36 +0100237 int64_t rtt_ms = 0;
238 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700239 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100240
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200241 uint32_t sent_ntp =
242 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100243 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
244
245 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700246 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100247 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700248 block.SetMediaSsrc(kReceiverMainSsrc);
249 block.SetLastSr(sent_ntp);
250 block.SetDelayLastSr(kDelayNtp);
251 sr.AddReportBlock(block);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100252
danilchap1e714ae2016-09-05 09:57:22 -0700253 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
254 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
255 InjectRtcpPacket(sr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100256
257 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700258 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100259 EXPECT_NEAR(kRttMs, rtt_ms, 1);
260}
261
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100262TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesNegativeRTTAsOne) {
263 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100264 const int64_t kRttMs = r.Rand(-3600 * 1000, -1);
265 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
266 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
267
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100268 int64_t rtt_ms = 0;
269 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700270 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100271
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200272 uint32_t sent_ntp =
273 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100274 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
275
276 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700277 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100278 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700279 block.SetMediaSsrc(kReceiverMainSsrc);
280 block.SetLastSr(sent_ntp);
281 block.SetDelayLastSr(kDelayNtp);
282 sr.AddReportBlock(block);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100283
danilchap1e714ae2016-09-05 09:57:22 -0700284 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
285 EXPECT_CALL(bandwidth_observer_,
286 OnReceivedRtcpReceiverReport(SizeIs(1), _, _));
287 InjectRtcpPacket(sr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100288
289 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700290 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100291 EXPECT_EQ(1, rtt_ms);
292}
293
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100294TEST_F(
295 RtcpReceiverTest,
296 TwoReportBlocksWithLastOneWithoutLastSrCalculatesRttForBandwidthObserver) {
297 const int64_t kRttMs = 120;
298 const uint32_t kDelayNtp = 123000;
299 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
300
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200301 uint32_t sent_ntp =
302 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100303 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
304
305 rtcp::SenderReport sr;
306 sr.SetSenderSsrc(kSenderSsrc);
307 rtcp::ReportBlock block;
308 block.SetMediaSsrc(kReceiverMainSsrc);
309 block.SetLastSr(sent_ntp);
310 block.SetDelayLastSr(kDelayNtp);
311 sr.AddReportBlock(block);
312 block.SetMediaSsrc(kReceiverExtraSsrc);
313 block.SetLastSr(0);
314 sr.AddReportBlock(block);
315
316 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
317 EXPECT_CALL(bandwidth_observer_,
318 OnReceivedRtcpReceiverReport(SizeIs(2), kRttMs, _));
319 InjectRtcpPacket(sr);
320}
321
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000322TEST_F(RtcpReceiverTest, InjectRrPacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700323 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000324 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700325 rr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700326
327 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
328 EXPECT_CALL(bandwidth_observer_,
329 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
330 InjectRtcpPacket(rr);
331
danilchap1e714ae2016-09-05 09:57:22 -0700332 std::vector<RTCPReportBlock> report_blocks;
333 rtcp_receiver_.StatisticsReceived(&report_blocks);
334 EXPECT_TRUE(report_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000335}
336
337TEST_F(RtcpReceiverTest, InjectRrPacketWithReportBlockNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700338 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000339 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700340 rb.SetMediaSsrc(kNotToUsSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000341 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700342 rr.SetSenderSsrc(kSenderSsrc);
343 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000344
danilchap1e714ae2016-09-05 09:57:22 -0700345 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
346 EXPECT_CALL(bandwidth_observer_,
347 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
348 InjectRtcpPacket(rr);
349
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200350 EXPECT_EQ(0, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000351 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700352 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000353 EXPECT_TRUE(received_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000354}
355
356TEST_F(RtcpReceiverTest, InjectRrPacketWithOneReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700357 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000358
359 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700360 rb.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000361 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700362 rr.SetSenderSsrc(kSenderSsrc);
363 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000364
danilchap1e714ae2016-09-05 09:57:22 -0700365 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
366 EXPECT_CALL(bandwidth_observer_,
367 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
368 InjectRtcpPacket(rr);
369
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200370 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
371 std::vector<RTCPReportBlock> received_blocks;
372 rtcp_receiver_.StatisticsReceived(&received_blocks);
373 EXPECT_EQ(1u, received_blocks.size());
374}
375
376TEST_F(RtcpReceiverTest, InjectSrPacketWithOneReportBlock) {
377 int64_t now = system_clock_.TimeInMilliseconds();
378
379 rtcp::ReportBlock rb;
380 rb.SetMediaSsrc(kReceiverMainSsrc);
381 rtcp::SenderReport sr;
382 sr.SetSenderSsrc(kSenderSsrc);
383 sr.AddReportBlock(rb);
384
385 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
386 EXPECT_CALL(bandwidth_observer_,
387 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
388 InjectRtcpPacket(sr);
389
390 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000391 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700392 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000393 EXPECT_EQ(1u, received_blocks.size());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000394}
395
396TEST_F(RtcpReceiverTest, InjectRrPacketWithTwoReportBlocks) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000397 const uint16_t kSequenceNumbers[] = {10, 12423};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000398 const uint32_t kCumLost[] = {13, 555};
399 const uint8_t kFracLost[] = {20, 11};
danilchap1e714ae2016-09-05 09:57:22 -0700400 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000401
402 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700403 rb1.SetMediaSsrc(kReceiverMainSsrc);
404 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
405 rb1.SetFractionLost(10);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000406
407 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700408 rb2.SetMediaSsrc(kReceiverExtraSsrc);
409 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
410 rb2.SetFractionLost(0);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000411
412 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700413 rr1.SetSenderSsrc(kSenderSsrc);
414 rr1.AddReportBlock(rb1);
415 rr1.AddReportBlock(rb2);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000416
danilchap1e714ae2016-09-05 09:57:22 -0700417 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
418 EXPECT_CALL(bandwidth_observer_,
419 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
420 InjectRtcpPacket(rr1);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000421
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200422 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700423 std::vector<RTCPReportBlock> received_blocks;
424 rtcp_receiver_.StatisticsReceived(&received_blocks);
425 EXPECT_THAT(received_blocks,
srte3e69e5c2017-08-09 06:13:45 -0700426 UnorderedElementsAre(Field(&RTCPReportBlock::fraction_lost, 0),
427 Field(&RTCPReportBlock::fraction_lost, 10)));
danilchap1e714ae2016-09-05 09:57:22 -0700428
429 // Insert next receiver report with same ssrc but new values.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000430 rtcp::ReportBlock rb3;
danilchap822a16f2016-09-27 09:27:47 -0700431 rb3.SetMediaSsrc(kReceiverMainSsrc);
432 rb3.SetExtHighestSeqNum(kSequenceNumbers[0]);
433 rb3.SetFractionLost(kFracLost[0]);
434 rb3.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000435
436 rtcp::ReportBlock rb4;
danilchap822a16f2016-09-27 09:27:47 -0700437 rb4.SetMediaSsrc(kReceiverExtraSsrc);
438 rb4.SetExtHighestSeqNum(kSequenceNumbers[1]);
439 rb4.SetFractionLost(kFracLost[1]);
440 rb4.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000441
442 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700443 rr2.SetSenderSsrc(kSenderSsrc);
444 rr2.AddReportBlock(rb3);
445 rr2.AddReportBlock(rb4);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000446
danilchap1e714ae2016-09-05 09:57:22 -0700447 // Advance time to make 1st sent time and 2nd sent time different.
448 system_clock_.AdvanceTimeMilliseconds(500);
449 now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000450
danilchap1e714ae2016-09-05 09:57:22 -0700451 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
452 EXPECT_CALL(bandwidth_observer_,
453 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
454 InjectRtcpPacket(rr2);
455
456 received_blocks.clear();
457 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000458 EXPECT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700459 EXPECT_THAT(
460 received_blocks,
461 UnorderedElementsAre(
462 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
463 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
464 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
465 Field(&RTCPReportBlock::extended_highest_sequence_number,
466 kSequenceNumbers[0])),
467 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverExtraSsrc),
468 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
469 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
470 Field(&RTCPReportBlock::extended_highest_sequence_number,
471 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000472}
473
474TEST_F(RtcpReceiverTest, InjectRrPacketsFromTwoRemoteSsrcs) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000475 const uint32_t kSenderSsrc2 = 0x20304;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000476 const uint16_t kSequenceNumbers[] = {10, 12423};
Sebastian Jansson9701e0c2018-08-09 11:21:11 +0200477 const int32_t kCumLost[] = {13, 555};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000478 const uint8_t kFracLost[] = {20, 11};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000479
480 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700481 rb1.SetMediaSsrc(kReceiverMainSsrc);
482 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
483 rb1.SetFractionLost(kFracLost[0]);
484 rb1.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000485 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700486 rr1.SetSenderSsrc(kSenderSsrc);
487 rr1.AddReportBlock(rb1);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000488
danilchap1e714ae2016-09-05 09:57:22 -0700489 int64_t now = system_clock_.TimeInMilliseconds();
490
491 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
492 EXPECT_CALL(bandwidth_observer_,
493 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
494 InjectRtcpPacket(rr1);
495
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200496 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000497
498 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700499 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000500 EXPECT_EQ(1u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700501 EXPECT_EQ(kSenderSsrc, received_blocks[0].sender_ssrc);
502 EXPECT_EQ(kReceiverMainSsrc, received_blocks[0].source_ssrc);
503 EXPECT_EQ(kFracLost[0], received_blocks[0].fraction_lost);
504 EXPECT_EQ(kCumLost[0], received_blocks[0].packets_lost);
505 EXPECT_EQ(kSequenceNumbers[0],
506 received_blocks[0].extended_highest_sequence_number);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000507
508 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700509 rb2.SetMediaSsrc(kReceiverMainSsrc);
510 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
511 rb2.SetFractionLost(kFracLost[1]);
512 rb2.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000513 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700514 rr2.SetSenderSsrc(kSenderSsrc2);
515 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -0700516
517 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
518 EXPECT_CALL(bandwidth_observer_,
519 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
520 InjectRtcpPacket(rr2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000521
522 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700523 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000524 ASSERT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700525 EXPECT_THAT(
526 received_blocks,
527 UnorderedElementsAre(
528 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
529 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc),
530 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
531 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
532 Field(&RTCPReportBlock::extended_highest_sequence_number,
533 kSequenceNumbers[0])),
534 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
535 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc2),
536 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
537 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
538 Field(&RTCPReportBlock::extended_highest_sequence_number,
539 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000540}
541
542TEST_F(RtcpReceiverTest, GetRtt) {
danilchap28b03eb2016-10-05 06:59:44 -0700543 const uint32_t kSentCompactNtp = 0x1234;
544 const uint32_t kDelayCompactNtp = 0x222;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000545 // No report block received.
Erik Språng6b8d3552015-09-24 15:06:57 +0200546 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700547 -1, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000548
549 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700550 rb.SetMediaSsrc(kReceiverMainSsrc);
danilchap28b03eb2016-10-05 06:59:44 -0700551 rb.SetLastSr(kSentCompactNtp);
552 rb.SetDelayLastSr(kDelayCompactNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700553
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000554 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700555 rr.SetSenderSsrc(kSenderSsrc);
556 rr.AddReportBlock(rb);
danilchap1e714ae2016-09-05 09:57:22 -0700557 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000558
danilchap1e714ae2016-09-05 09:57:22 -0700559 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
560 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
561 InjectRtcpPacket(rr);
562
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200563 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700564 EXPECT_EQ(
565 0, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000566}
567
danilchap1e714ae2016-09-05 09:57:22 -0700568// Ij packets are ignored.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000569TEST_F(RtcpReceiverTest, InjectIjWithNoItem) {
danilchapf8506cb2015-11-13 07:33:20 -0800570 rtcp::ExtendedJitterReport ij;
danilchap1e714ae2016-09-05 09:57:22 -0700571 InjectRtcpPacket(ij);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000572}
573
danilchap1e714ae2016-09-05 09:57:22 -0700574// App packets are ignored.
575TEST_F(RtcpReceiverTest, InjectApp) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000576 rtcp::App app;
danilchap822a16f2016-09-27 09:27:47 -0700577 app.SetSubType(30);
578 app.SetName(0x17a177e);
danilchap1e714ae2016-09-05 09:57:22 -0700579 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
danilchap822a16f2016-09-27 09:27:47 -0700580 app.SetData(kData, sizeof(kData));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000581
danilchap1e714ae2016-09-05 09:57:22 -0700582 InjectRtcpPacket(app);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000583}
584
585TEST_F(RtcpReceiverTest, InjectSdesWithOneChunk) {
danilchap1e714ae2016-09-05 09:57:22 -0700586 const char kCname[] = "alice@host";
587 MockRtcpCallbackImpl callback;
588 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000589 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700590 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000591
danilchap1e714ae2016-09-05 09:57:22 -0700592 EXPECT_CALL(callback, CNameChanged(StrEq(kCname), kSenderSsrc));
593 InjectRtcpPacket(sdes);
594
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000595 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700596 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
597 EXPECT_EQ(0, strncmp(cName, kCname, RTCP_CNAME_SIZE));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000598}
599
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000600TEST_F(RtcpReceiverTest, InjectByePacket_RemovesCname) {
danilchap1e714ae2016-09-05 09:57:22 -0700601 const char kCname[] = "alice@host";
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000602 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700603 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000604
danilchap1e714ae2016-09-05 09:57:22 -0700605 InjectRtcpPacket(sdes);
606
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000607 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700608 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000609
610 // Verify that BYE removes the CNAME.
611 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700612 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700613
614 InjectRtcpPacket(bye);
615
616 EXPECT_EQ(-1, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000617}
618
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000619TEST_F(RtcpReceiverTest, InjectByePacket_RemovesReportBlocks) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000620 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700621 rb1.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000622 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700623 rb2.SetMediaSsrc(kReceiverExtraSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000624 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700625 rr.SetSenderSsrc(kSenderSsrc);
626 rr.AddReportBlock(rb1);
627 rr.AddReportBlock(rb2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000628
danilchap1e714ae2016-09-05 09:57:22 -0700629 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
630 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
631 InjectRtcpPacket(rr);
632
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000633 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700634 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000635 EXPECT_EQ(2u, received_blocks.size());
636
637 // Verify that BYE removes the report blocks.
638 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700639 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700640
641 InjectRtcpPacket(bye);
642
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000643 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700644 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000645 EXPECT_TRUE(received_blocks.empty());
646
danilchap1e714ae2016-09-05 09:57:22 -0700647 // Inject packet again.
648 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
649 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
650 InjectRtcpPacket(rr);
651
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000652 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700653 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000654 EXPECT_EQ(2u, received_blocks.size());
655}
656
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200657TEST_F(RtcpReceiverTest, InjectByePacketRemovesReferenceTimeInfo) {
658 rtcp::ExtendedReports xr;
659 xr.SetSenderSsrc(kSenderSsrc);
660 rtcp::Rrtr rrtr;
661 rrtr.SetNtp(NtpTime(0x10203, 0x40506));
662 xr.SetRrtr(rrtr);
663 InjectRtcpPacket(xr);
664
665 rtcp::Bye bye;
666 bye.SetSenderSsrc(kSenderSsrc);
667 InjectRtcpPacket(bye);
668
669 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
670}
671
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000672TEST_F(RtcpReceiverTest, InjectPliPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000673 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700674 pli.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700675
676 EXPECT_CALL(
677 packet_type_counter_observer_,
678 RtcpPacketTypesCounterUpdated(
679 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 1)));
680 EXPECT_CALL(intra_frame_observer_,
681 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
682 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000683}
684
685TEST_F(RtcpReceiverTest, PliPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000686 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700687 pli.SetMediaSsrc(kNotToUsSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700688
689 EXPECT_CALL(
690 packet_type_counter_observer_,
691 RtcpPacketTypesCounterUpdated(
692 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 0)));
693 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
694 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000695}
696
697TEST_F(RtcpReceiverTest, InjectFirPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000698 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700699 fir.AddRequestTo(kReceiverMainSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700700
701 EXPECT_CALL(
702 packet_type_counter_observer_,
703 RtcpPacketTypesCounterUpdated(
704 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::fir_packets, 1)));
705 EXPECT_CALL(intra_frame_observer_,
706 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
707 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000708}
709
710TEST_F(RtcpReceiverTest, FirPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000711 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700712 fir.AddRequestTo(kNotToUsSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700713
714 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
715 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000716}
717
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100718TEST_F(RtcpReceiverTest, ExtendedReportsPacketWithZeroReportBlocksIgnored) {
719 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700720 xr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700721
722 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000723}
724
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100725TEST_F(RtcpReceiverTest, InjectExtendedReportsReceiverReferenceTimePacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700726 const NtpTime kNtp(0x10203, 0x40506);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000727 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700728 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100729 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700730 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700731 xr.SetRrtr(rrtr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000732
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200733 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
734 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
735 EXPECT_THAT(last_xr_rtis, IsEmpty());
danilchap1e714ae2016-09-05 09:57:22 -0700736
737 InjectRtcpPacket(xr);
738
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200739 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
740 ASSERT_THAT(last_xr_rtis, SizeIs(1));
741 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
742 EXPECT_EQ(CompactNtp(kNtp), last_xr_rtis[0].last_rr);
743 EXPECT_EQ(0U, last_xr_rtis[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000744}
745
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100746TEST_F(RtcpReceiverTest, ExtendedReportsDlrrPacketNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700747 // Allow calculate rtt using dlrr/rrtr, simulating media receiver side.
748 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000749
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100750 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700751 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700752 xr.AddDlrrItem(ReceiveTimeInfo(kNotToUsSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700753
754 InjectRtcpPacket(xr);
755
756 int64_t rtt_ms = 0;
757 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000758}
759
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100760TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithSubBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700761 const uint32_t kLastRR = 0x12345;
762 const uint32_t kDelay = 0x23456;
763 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
764 int64_t rtt_ms = 0;
765 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000766
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100767 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700768 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700769 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
danilchap1e714ae2016-09-05 09:57:22 -0700770
771 InjectRtcpPacket(xr);
772
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200773 uint32_t compact_ntp_now =
774 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700775 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
776 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
777 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000778}
779
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100780TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithMultipleSubBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700781 const uint32_t kLastRR = 0x12345;
782 const uint32_t kDelay = 0x56789;
783 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000784
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100785 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700786 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700787 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
788 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 1, 0x12345, 0x67890));
789 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 2, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700790
791 InjectRtcpPacket(xr);
792
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200793 uint32_t compact_ntp_now =
794 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700795 int64_t rtt_ms = 0;
796 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
797 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
798 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000799}
800
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100801TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithMultipleReportBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700802 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000803
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000804 rtcp::Rrtr rrtr;
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100805 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700806 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700807 xr.SetRrtr(rrtr);
808 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700809
810 InjectRtcpPacket(xr);
811
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200812 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
813 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
814 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700815 int64_t rtt_ms = 0;
816 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000817}
818
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100819TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithUnknownReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700820 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000821
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000822 rtcp::Rrtr rrtr;
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100823 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700824 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700825 xr.SetRrtr(rrtr);
826 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700827
danilchap69e59e62016-02-17 03:11:42 -0800828 rtc::Buffer packet = xr.Build();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000829 // Modify the DLRR block to have an unsupported block type, from 5 to 6.
danilchap1e714ae2016-09-05 09:57:22 -0700830 ASSERT_EQ(5, packet.data()[20]);
831 packet.data()[20] = 6;
832 InjectRtcpPacket(packet);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000833
danilchap1e714ae2016-09-05 09:57:22 -0700834 // Validate Rrtr was received and processed.
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200835 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
836 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
837 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700838 // Validate Dlrr report wasn't processed.
839 int64_t rtt_ms = 0;
840 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000841}
842
danilchap1e714ae2016-09-05 09:57:22 -0700843TEST_F(RtcpReceiverTest, TestExtendedReportsRrRttInitiallyFalse) {
844 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
845
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000846 int64_t rtt_ms;
danilchap1e714ae2016-09-05 09:57:22 -0700847 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000848}
849
danilchap1e714ae2016-09-05 09:57:22 -0700850TEST_F(RtcpReceiverTest, RttCalculatedAfterExtendedReportsDlrr) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100851 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100852 const int64_t kRttMs = rand.Rand(1, 9 * 3600 * 1000);
853 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
854 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700855 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200856 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalova094fd12016-02-22 18:59:36 +0100857 uint32_t sent_ntp = CompactNtp(now);
858 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
859
Danil Chapovalova094fd12016-02-22 18:59:36 +0100860 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700861 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700862 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700863
864 InjectRtcpPacket(xr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100865
866 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700867 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100868 EXPECT_NEAR(kRttMs, rtt_ms, 1);
869}
870
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100871TEST_F(RtcpReceiverTest, XrDlrrCalculatesNegativeRttAsOne) {
872 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100873 const int64_t kRttMs = rand.Rand(-3600 * 1000, -1);
874 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
875 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200876 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100877 uint32_t sent_ntp = CompactNtp(now);
878 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
danilchap1e714ae2016-09-05 09:57:22 -0700879 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100880
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100881 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700882 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700883 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700884
885 InjectRtcpPacket(xr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100886
887 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700888 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100889 EXPECT_EQ(1, rtt_ms);
890}
891
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200892TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfoInitiallyEmpty) {
893 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000894}
895
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200896TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfo) {
Danil Chapovalovfc47ed62015-12-07 14:46:35 +0100897 const NtpTime kNtp(0x10203, 0x40506);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100898 const uint32_t kNtpMid = CompactNtp(kNtp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000899
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000900 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700901 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100902 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700903 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700904 xr.SetRrtr(rrtr);
danilchap1e714ae2016-09-05 09:57:22 -0700905
906 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000907
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000908 system_clock_.AdvanceTimeMilliseconds(1000);
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200909
910 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
911 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
912 ASSERT_THAT(last_xr_rtis, SizeIs(1));
913 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
914 EXPECT_EQ(kNtpMid, last_xr_rtis[0].last_rr);
915 EXPECT_EQ(65536U, last_xr_rtis[0].delay_since_last_rr);
916}
917
918TEST_F(RtcpReceiverTest,
919 ReceivedRrtrFromSameSsrcUpdatesReceivedReferenceTimeInfo) {
920 const NtpTime kNtp1(0x10203, 0x40506);
921 const NtpTime kNtp2(0x11223, 0x44556);
922 const int64_t kDelayMs = 2000;
923
924 rtcp::ExtendedReports xr;
925 xr.SetSenderSsrc(kSenderSsrc);
926 rtcp::Rrtr rrtr1;
927 rrtr1.SetNtp(kNtp1);
928 xr.SetRrtr(rrtr1);
929 InjectRtcpPacket(xr);
930 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
931 rtcp::Rrtr rrtr2;
932 rrtr2.SetNtp(kNtp2);
933 xr.SetRrtr(rrtr2);
934 InjectRtcpPacket(xr);
935 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
936
937 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
938 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
939 ASSERT_THAT(last_xr_rtis, SizeIs(1));
940 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
941 EXPECT_EQ(CompactNtp(kNtp2), last_xr_rtis[0].last_rr);
942 EXPECT_EQ(kDelayMs * 65536 / 1000, last_xr_rtis[0].delay_since_last_rr);
943}
944
945TEST_F(RtcpReceiverTest, StoresLastReceivedRrtrPerSsrc) {
946 const size_t kNumBufferedReports = 1;
947 const size_t kNumReports =
948 rtcp::ExtendedReports::kMaxNumberOfDlrrItems + kNumBufferedReports;
949 for (size_t i = 0; i < kNumReports; ++i) {
950 rtcp::ExtendedReports xr;
951 xr.SetSenderSsrc(i * 100);
952 rtcp::Rrtr rrtr;
953 rrtr.SetNtp(NtpTime(i * 200, i * 300));
954 xr.SetRrtr(rrtr);
955 InjectRtcpPacket(xr);
956 system_clock_.AdvanceTimeMilliseconds(1000);
957 }
958
959 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
960 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
961 ASSERT_THAT(last_xr_rtis,
962 SizeIs(rtcp::ExtendedReports::kMaxNumberOfDlrrItems));
963 for (size_t i = 0; i < rtcp::ExtendedReports::kMaxNumberOfDlrrItems; ++i) {
964 EXPECT_EQ(i * 100, last_xr_rtis[i].ssrc);
965 EXPECT_EQ(CompactNtp(NtpTime(i * 200, i * 300)), last_xr_rtis[i].last_rr);
966 EXPECT_EQ(65536U * (kNumReports - i), last_xr_rtis[i].delay_since_last_rr);
967 }
968
969 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
970 ASSERT_THAT(last_xr_rtis, SizeIs(kNumBufferedReports));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000971}
972
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000973TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000974 const uint16_t kSequenceNumber = 1234;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000975 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000976
977 // No RR received, shouldn't trigger a timeout.
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800978 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
979 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000980
981 // Add a RR and advance the clock just enough to not trigger a timeout.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000982 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700983 rb1.SetMediaSsrc(kReceiverMainSsrc);
984 rb1.SetExtHighestSeqNum(kSequenceNumber);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000985 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700986 rr1.SetSenderSsrc(kSenderSsrc);
987 rr1.AddReportBlock(rb1);
danilchap1e714ae2016-09-05 09:57:22 -0700988
989 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
990 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
991 InjectRtcpPacket(rr1);
992
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000993 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs - 1);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800994 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
995 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000996
997 // Add a RR with the same extended max as the previous RR to trigger a
998 // sequence number timeout, but not a RR timeout.
danilchap1e714ae2016-09-05 09:57:22 -0700999 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1000 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1001 InjectRtcpPacket(rr1);
1002
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001003 system_clock_.AdvanceTimeMilliseconds(2);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001004 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1005 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001006
1007 // Advance clock enough to trigger an RR timeout too.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001008 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001009 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001010
1011 // We should only get one timeout even though we still haven't received a new
1012 // RR.
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001013 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1014 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001015
1016 // Add a new RR with increase sequence number to reset timers.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001017 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001018 rb2.SetMediaSsrc(kReceiverMainSsrc);
1019 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001020 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001021 rr2.SetSenderSsrc(kSenderSsrc);
1022 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001023
1024 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1025 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1026 InjectRtcpPacket(rr2);
1027
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001028 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1029 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001030
1031 // Verify we can get a timeout again once we've received new RR.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001032 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -07001033 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1034 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1035 InjectRtcpPacket(rr2);
1036
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001037 system_clock_.AdvanceTimeMilliseconds(kRtcpIntervalMs + 1);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001038 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1039 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
danilchap1e714ae2016-09-05 09:57:22 -07001040
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001041 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001042 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001043}
1044
hta@webrtc.org47059b52012-05-02 07:46:22 +00001045TEST_F(RtcpReceiverTest, TmmbrReceivedWithNoIncomingPacket) {
danilchap1e714ae2016-09-05 09:57:22 -07001046 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001047}
1048
1049TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) {
danilchap1e714ae2016-09-05 09:57:22 -07001050 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001051 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001052 tmmbr.SetSenderSsrc(kSenderSsrc);
1053 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001054 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001055 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001056 rtcp::CompoundPacket compound;
1057 compound.Append(&sr);
1058 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001059
danilchap1e714ae2016-09-05 09:57:22 -07001060 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1061 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(SizeIs(1)));
1062 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1063 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1064 InjectRtcpPacket(compound);
1065
1066 std::vector<rtcp::TmmbItem> tmmbr_received = rtcp_receiver_.TmmbrReceived();
1067 ASSERT_EQ(1u, tmmbr_received.size());
1068 EXPECT_EQ(kBitrateBps, tmmbr_received[0].bitrate_bps());
1069 EXPECT_EQ(kSenderSsrc, tmmbr_received[0].ssrc());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001070}
1071
1072TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -07001073 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001074 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001075 tmmbr.SetSenderSsrc(kSenderSsrc);
1076 tmmbr.AddTmmbr(rtcp::TmmbItem(kNotToUsSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001077
1078 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001079 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001080 rtcp::CompoundPacket compound;
1081 compound.Append(&sr);
1082 compound.Append(&tmmbr);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001083
danilchap1e714ae2016-09-05 09:57:22 -07001084 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1085 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1086 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1087 InjectRtcpPacket(compound);
1088
1089 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001090}
1091
1092TEST_F(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001093 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001094 tmmbr.SetSenderSsrc(kSenderSsrc);
1095 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 0, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001096 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001097 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001098 rtcp::CompoundPacket compound;
1099 compound.Append(&sr);
1100 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001101
danilchap1e714ae2016-09-05 09:57:22 -07001102 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1103 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1104 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1105 InjectRtcpPacket(compound);
1106
1107 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001108}
1109
hta@webrtc.org404843e2012-05-02 09:56:45 +00001110TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001111 // Inject 3 packets "from" kSenderSsrc, kSenderSsrc+1, kSenderSsrc+2.
hta@webrtc.org404843e2012-05-02 09:56:45 +00001112 // The times of arrival are starttime + 0, starttime + 5 and starttime + 10.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001113 for (uint32_t ssrc = kSenderSsrc; ssrc < kSenderSsrc + 3; ++ssrc) {
1114 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001115 tmmbr.SetSenderSsrc(ssrc);
1116 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 30000, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001117 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001118 sr.SetSenderSsrc(ssrc);
danilchap7a4116a2016-03-14 08:19:28 -07001119 rtcp::CompoundPacket compound;
1120 compound.Append(&sr);
1121 compound.Append(&tmmbr);
danilchap1e714ae2016-09-05 09:57:22 -07001122
1123 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1124 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(_));
1125 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1126 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_));
1127 InjectRtcpPacket(compound);
1128
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001129 // 5 seconds between each packet.
1130 system_clock_.AdvanceTimeMilliseconds(5000);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001131 }
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001132 // It is now starttime + 15.
danilchap1e714ae2016-09-05 09:57:22 -07001133 std::vector<rtcp::TmmbItem> candidate_set = rtcp_receiver_.TmmbrReceived();
1134 ASSERT_EQ(3u, candidate_set.size());
1135 EXPECT_EQ(30000U, candidate_set[0].bitrate_bps());
1136
hta@webrtc.org404843e2012-05-02 09:56:45 +00001137 // We expect the timeout to be 25 seconds. Advance the clock by 12
1138 // seconds, timing out the first packet.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001139 system_clock_.AdvanceTimeMilliseconds(12000);
danilchap1e714ae2016-09-05 09:57:22 -07001140 candidate_set = rtcp_receiver_.TmmbrReceived();
1141 ASSERT_EQ(2u, candidate_set.size());
danilchap287e5482016-08-16 15:15:39 -07001142 EXPECT_EQ(kSenderSsrc + 1, candidate_set[0].ssrc());
hta@webrtc.org404843e2012-05-02 09:56:45 +00001143}
1144
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001145TEST_F(RtcpReceiverTest, Callbacks) {
danilchap1e714ae2016-09-05 09:57:22 -07001146 MockRtcpCallbackImpl callback;
1147 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001148
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001149 const uint8_t kFractionLoss = 3;
1150 const uint32_t kCumulativeLoss = 7;
1151 const uint32_t kJitter = 9;
1152 const uint16_t kSequenceNumber = 1234;
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001153
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001154 // First packet, all numbers should just propagate.
1155 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -07001156 rb1.SetMediaSsrc(kReceiverMainSsrc);
1157 rb1.SetExtHighestSeqNum(kSequenceNumber);
1158 rb1.SetFractionLost(kFractionLoss);
1159 rb1.SetCumulativeLost(kCumulativeLoss);
1160 rb1.SetJitter(kJitter);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001161
1162 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -07001163 rr1.SetSenderSsrc(kSenderSsrc);
1164 rr1.AddReportBlock(rb1);
srte186d9c32017-08-04 05:03:53 -07001165 EXPECT_CALL(callback,
1166 StatisticsUpdated(
1167 AllOf(Field(&RtcpStatistics::fraction_lost, kFractionLoss),
1168 Field(&RtcpStatistics::packets_lost, kCumulativeLoss),
1169 Field(&RtcpStatistics::extended_highest_sequence_number,
1170 kSequenceNumber),
1171 Field(&RtcpStatistics::jitter, kJitter)),
1172 kReceiverMainSsrc));
danilchap1e714ae2016-09-05 09:57:22 -07001173 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1174 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1175 InjectRtcpPacket(rr1);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001176
danilchap1e714ae2016-09-05 09:57:22 -07001177 rtcp_receiver_.RegisterRtcpStatisticsCallback(nullptr);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001178
danilchap1e714ae2016-09-05 09:57:22 -07001179 // Add arbitrary numbers, callback should not be called.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001180 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001181 rb2.SetMediaSsrc(kReceiverMainSsrc);
1182 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
1183 rb2.SetFractionLost(42);
1184 rb2.SetCumulativeLost(137);
1185 rb2.SetJitter(4711);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001186
1187 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001188 rr2.SetSenderSsrc(kSenderSsrc);
1189 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001190
1191 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1192 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1193 EXPECT_CALL(callback, StatisticsUpdated(_, _)).Times(0);
1194 InjectRtcpPacket(rr2);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001195}
hta@webrtc.org404843e2012-05-02 09:56:45 +00001196
Henrik Boströmf2047872019-05-16 13:32:20 +02001197TEST_F(RtcpReceiverTest,
1198 VerifyBlockAndTimestampObtainedFromReportBlockDataObserver) {
1199 MockReportBlockDataObserverImpl observer;
1200 rtcp_receiver_.SetReportBlockDataObserver(&observer);
1201
1202 const uint8_t kFractionLoss = 3;
1203 const uint32_t kCumulativeLoss = 7;
1204 const uint32_t kJitter = 9;
1205 const uint16_t kSequenceNumber = 1234;
1206 const int64_t kUtcNowUs = 42;
1207
1208 // The "report_block_timestamp_utc_us" is obtained from the global UTC clock
1209 // (not the simulcated |system_clock_|) and requires a scoped fake clock.
1210 rtc::ScopedFakeClock fake_clock;
1211 fake_clock.SetTime(Timestamp::us(kUtcNowUs));
1212
1213 rtcp::ReportBlock rtcp_block;
1214 rtcp_block.SetMediaSsrc(kReceiverMainSsrc);
1215 rtcp_block.SetExtHighestSeqNum(kSequenceNumber);
1216 rtcp_block.SetFractionLost(kFractionLoss);
1217 rtcp_block.SetCumulativeLost(kCumulativeLoss);
1218 rtcp_block.SetJitter(kJitter);
1219
1220 rtcp::ReceiverReport rtcp_report;
1221 rtcp_report.SetSenderSsrc(kSenderSsrc);
1222 rtcp_report.AddReportBlock(rtcp_block);
1223 EXPECT_CALL(observer, OnReportBlockDataUpdated)
1224 .WillOnce([&](ReportBlockData report_block_data) {
1225 const auto& report_block = report_block_data.report_block();
1226 EXPECT_EQ(rtcp_block.source_ssrc(), report_block.source_ssrc);
1227 EXPECT_EQ(kSenderSsrc, report_block.sender_ssrc);
1228 EXPECT_EQ(rtcp_block.fraction_lost(), report_block.fraction_lost);
1229 EXPECT_EQ(rtcp_block.cumulative_lost_signed(),
1230 report_block.packets_lost);
1231 EXPECT_EQ(rtcp_block.extended_high_seq_num(),
1232 report_block.extended_highest_sequence_number);
1233 EXPECT_EQ(rtcp_block.jitter(), report_block.jitter);
1234 EXPECT_EQ(kUtcNowUs, report_block_data.report_block_timestamp_utc_us());
1235 // No RTT is calculated in this test.
1236 EXPECT_EQ(0u, report_block_data.num_rtts());
1237 });
1238 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1239 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1240 InjectRtcpPacket(rtcp_report);
1241}
1242
1243TEST_F(RtcpReceiverTest, VerifyRttObtainedFromReportBlockDataObserver) {
1244 MockReportBlockDataObserverImpl observer;
1245 rtcp_receiver_.SetReportBlockDataObserver(&observer);
1246
1247 const int64_t kRttMs = 120;
1248 const uint32_t kDelayNtp = 123000;
1249 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
1250
1251 uint32_t sent_ntp =
1252 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
1253 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
1254
1255 rtcp::SenderReport sr;
1256 sr.SetSenderSsrc(kSenderSsrc);
1257 rtcp::ReportBlock block;
1258 block.SetMediaSsrc(kReceiverMainSsrc);
1259 block.SetLastSr(sent_ntp);
1260 block.SetDelayLastSr(kDelayNtp);
1261 sr.AddReportBlock(block);
1262 block.SetMediaSsrc(kReceiverExtraSsrc);
1263 block.SetLastSr(0);
1264 sr.AddReportBlock(block);
1265
1266 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1267 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1268 InSequence sequence;
1269 EXPECT_CALL(observer, OnReportBlockDataUpdated)
1270 .WillOnce([&](ReportBlockData report_block_data) {
1271 EXPECT_EQ(kReceiverMainSsrc,
1272 report_block_data.report_block().source_ssrc);
1273 EXPECT_EQ(1u, report_block_data.num_rtts());
1274 EXPECT_EQ(kRttMs, report_block_data.min_rtt_ms());
1275 EXPECT_EQ(kRttMs, report_block_data.max_rtt_ms());
1276 EXPECT_EQ(kRttMs, report_block_data.sum_rtt_ms());
1277 EXPECT_EQ(kRttMs, report_block_data.last_rtt_ms());
1278 });
1279 EXPECT_CALL(observer, OnReportBlockDataUpdated)
1280 .WillOnce([](ReportBlockData report_block_data) {
1281 EXPECT_EQ(kReceiverExtraSsrc,
1282 report_block_data.report_block().source_ssrc);
1283 EXPECT_EQ(0u, report_block_data.num_rtts());
1284 });
1285 InjectRtcpPacket(sr);
1286}
1287
1288TEST_F(RtcpReceiverTest, GetReportBlockDataAfterOneReportBlock) {
1289 const uint16_t kSequenceNumber = 1234;
1290
1291 rtcp::ReportBlock rtcp_block;
1292 rtcp_block.SetMediaSsrc(kReceiverMainSsrc);
1293 rtcp_block.SetExtHighestSeqNum(kSequenceNumber);
1294
1295 rtcp::ReceiverReport rtcp_report;
1296 rtcp_report.SetSenderSsrc(kSenderSsrc);
1297 rtcp_report.AddReportBlock(rtcp_block);
1298 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1299 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1300 InjectRtcpPacket(rtcp_report);
1301
1302 auto report_block_datas = rtcp_receiver_.GetLatestReportBlockData();
1303 ASSERT_THAT(report_block_datas, SizeIs(1));
1304 EXPECT_EQ(kReceiverMainSsrc,
1305 report_block_datas[0].report_block().source_ssrc);
1306 EXPECT_EQ(
1307 kSequenceNumber,
1308 report_block_datas[0].report_block().extended_highest_sequence_number);
1309}
1310
1311TEST_F(RtcpReceiverTest, GetReportBlockDataAfterTwoReportBlocksOfSameSsrc) {
1312 const uint16_t kSequenceNumber1 = 1234;
1313 const uint16_t kSequenceNumber2 = 1235;
1314
1315 rtcp::ReportBlock rtcp_block1;
1316 rtcp_block1.SetMediaSsrc(kReceiverMainSsrc);
1317 rtcp_block1.SetExtHighestSeqNum(kSequenceNumber1);
1318
1319 rtcp::ReceiverReport rtcp_report1;
1320 rtcp_report1.SetSenderSsrc(kSenderSsrc);
1321 rtcp_report1.AddReportBlock(rtcp_block1);
1322 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1323 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1324 InjectRtcpPacket(rtcp_report1);
1325
1326 // Inject a report block with an increased the sequence number for the same
1327 // source SSRC.
1328 rtcp::ReportBlock rtcp_block2;
1329 rtcp_block2.SetMediaSsrc(kReceiverMainSsrc);
1330 rtcp_block2.SetExtHighestSeqNum(kSequenceNumber2);
1331
1332 rtcp::ReceiverReport rtcp_report2;
1333 rtcp_report2.SetSenderSsrc(kSenderSsrc);
1334 rtcp_report2.AddReportBlock(rtcp_block2);
1335 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1336 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1337 InjectRtcpPacket(rtcp_report2);
1338
1339 // Only the latest block should be returned.
1340 auto report_block_datas = rtcp_receiver_.GetLatestReportBlockData();
1341 ASSERT_THAT(report_block_datas, SizeIs(1));
1342 EXPECT_EQ(kReceiverMainSsrc,
1343 report_block_datas[0].report_block().source_ssrc);
1344 EXPECT_EQ(
1345 kSequenceNumber2,
1346 report_block_datas[0].report_block().extended_highest_sequence_number);
1347}
1348
1349TEST_F(RtcpReceiverTest,
1350 GetReportBlockDataAfterTwoReportBlocksOfDifferentSsrcs) {
1351 const uint16_t kSequenceNumber1 = 1234;
1352 const uint16_t kSequenceNumber2 = 42;
1353
1354 rtcp::ReportBlock rtcp_block1;
1355 rtcp_block1.SetMediaSsrc(kReceiverMainSsrc);
1356 rtcp_block1.SetExtHighestSeqNum(kSequenceNumber1);
1357
1358 rtcp::ReceiverReport rtcp_report1;
1359 rtcp_report1.SetSenderSsrc(kSenderSsrc);
1360 rtcp_report1.AddReportBlock(rtcp_block1);
1361 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1362 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1363 InjectRtcpPacket(rtcp_report1);
1364
1365 // Inject a report block for a different source SSRC.
1366 rtcp::ReportBlock rtcp_block2;
1367 rtcp_block2.SetMediaSsrc(kReceiverExtraSsrc);
1368 rtcp_block2.SetExtHighestSeqNum(kSequenceNumber2);
1369
1370 rtcp::ReceiverReport rtcp_report2;
1371 rtcp_report2.SetSenderSsrc(kSenderSsrc);
1372 rtcp_report2.AddReportBlock(rtcp_block2);
1373 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1374 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1375 InjectRtcpPacket(rtcp_report2);
1376
1377 // Both report blocks should be returned.
1378 auto report_block_datas = rtcp_receiver_.GetLatestReportBlockData();
1379 ASSERT_THAT(report_block_datas, SizeIs(2));
1380 EXPECT_EQ(kReceiverMainSsrc,
1381 report_block_datas[0].report_block().source_ssrc);
1382 EXPECT_EQ(
1383 kSequenceNumber1,
1384 report_block_datas[0].report_block().extended_highest_sequence_number);
1385 EXPECT_EQ(kReceiverExtraSsrc,
1386 report_block_datas[1].report_block().source_ssrc);
1387 EXPECT_EQ(
1388 kSequenceNumber2,
1389 report_block_datas[1].report_block().extended_highest_sequence_number);
1390}
1391
sprang49f9cdb2015-10-01 03:06:57 -07001392TEST_F(RtcpReceiverTest, ReceivesTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001393 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001394 packet.SetMediaSsrc(kReceiverMainSsrc);
1395 packet.SetSenderSsrc(kSenderSsrc);
1396 packet.SetBase(1, 1000);
1397 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001398
danilchap1e714ae2016-09-05 09:57:22 -07001399 EXPECT_CALL(
1400 transport_feedback_observer_,
1401 OnTransportFeedback(AllOf(
1402 Property(&rtcp::TransportFeedback::media_ssrc, kReceiverMainSsrc),
1403 Property(&rtcp::TransportFeedback::sender_ssrc, kSenderSsrc))));
1404 InjectRtcpPacket(packet);
sprang49f9cdb2015-10-01 03:06:57 -07001405}
1406
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001407TEST_F(RtcpReceiverTest, ReceivesRemb) {
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001408 const uint32_t kBitrateBps = 500000;
1409 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001410 remb.SetSenderSsrc(kSenderSsrc);
1411 remb.SetBitrateBps(kBitrateBps);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001412
danilchap1e714ae2016-09-05 09:57:22 -07001413 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1414 InjectRtcpPacket(remb);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001415}
1416
sprang49f9cdb2015-10-01 03:06:57 -07001417TEST_F(RtcpReceiverTest, HandlesInvalidTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001418 // Send a compound packet with a TransportFeedback followed by something else.
1419 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001420 packet.SetMediaSsrc(kReceiverMainSsrc);
1421 packet.SetSenderSsrc(kSenderSsrc);
1422 packet.SetBase(1, 1000);
1423 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001424
1425 static uint32_t kBitrateBps = 50000;
1426 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001427 remb.SetSenderSsrc(kSenderSsrc);
1428 remb.SetBitrateBps(kBitrateBps);
danilchap7a4116a2016-03-14 08:19:28 -07001429 rtcp::CompoundPacket compound;
1430 compound.Append(&packet);
1431 compound.Append(&remb);
1432 rtc::Buffer built_packet = compound.Build();
sprang49f9cdb2015-10-01 03:06:57 -07001433
1434 // Modify the TransportFeedback packet so that it is invalid.
1435 const size_t kStatusCountOffset = 14;
Yves Gerey665174f2018-06-19 15:03:05 +02001436 ByteWriter<uint16_t>::WriteBigEndian(&built_packet.data()[kStatusCountOffset],
1437 42);
sprang49f9cdb2015-10-01 03:06:57 -07001438
danilchap1e714ae2016-09-05 09:57:22 -07001439 // Stress no transport feedback is expected.
1440 EXPECT_CALL(transport_feedback_observer_, OnTransportFeedback(_)).Times(0);
1441 // But remb should be processed and cause a callback
1442 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1443 InjectRtcpPacket(built_packet);
sprang49f9cdb2015-10-01 03:06:57 -07001444}
1445
danilchap1e714ae2016-09-05 09:57:22 -07001446TEST_F(RtcpReceiverTest, Nack) {
1447 const uint16_t kNackList1[] = {1, 2, 3, 5};
danilchap142f0192016-10-20 08:22:42 -07001448 const uint16_t kNackList23[] = {5, 7, 30, 40, 41, 58, 59, 61, 63};
1449 const size_t kNackListLength2 = 4;
1450 const size_t kNackListLength3 = arraysize(kNackList23) - kNackListLength2;
danilchap1e714ae2016-09-05 09:57:22 -07001451 std::set<uint16_t> nack_set;
1452 nack_set.insert(std::begin(kNackList1), std::end(kNackList1));
danilchap142f0192016-10-20 08:22:42 -07001453 nack_set.insert(std::begin(kNackList23), std::end(kNackList23));
danilchap1e714ae2016-09-05 09:57:22 -07001454
danilchap142f0192016-10-20 08:22:42 -07001455 rtcp::Nack nack1;
1456 nack1.SetSenderSsrc(kSenderSsrc);
1457 nack1.SetMediaSsrc(kReceiverMainSsrc);
1458 nack1.SetPacketIds(kNackList1, arraysize(kNackList1));
danilchap1e714ae2016-09-05 09:57:22 -07001459
1460 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList1)));
danilchap1e714ae2016-09-05 09:57:22 -07001461 EXPECT_CALL(packet_type_counter_observer_,
1462 RtcpPacketTypesCounterUpdated(
1463 kReceiverMainSsrc,
1464 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
danilchap142f0192016-10-20 08:22:42 -07001465 arraysize(kNackList1)),
1466 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1467 arraysize(kNackList1)))));
1468 InjectRtcpPacket(nack1);
1469
1470 rtcp::Nack nack2;
1471 nack2.SetSenderSsrc(kSenderSsrc);
1472 nack2.SetMediaSsrc(kReceiverMainSsrc);
1473 nack2.SetPacketIds(kNackList23, kNackListLength2);
1474
1475 rtcp::Nack nack3;
1476 nack3.SetSenderSsrc(kSenderSsrc);
1477 nack3.SetMediaSsrc(kReceiverMainSsrc);
1478 nack3.SetPacketIds(kNackList23 + kNackListLength2, kNackListLength3);
1479
1480 rtcp::CompoundPacket two_nacks;
1481 two_nacks.Append(&nack2);
1482 two_nacks.Append(&nack3);
1483
1484 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList23)));
1485 EXPECT_CALL(packet_type_counter_observer_,
1486 RtcpPacketTypesCounterUpdated(
1487 kReceiverMainSsrc,
1488 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
1489 arraysize(kNackList1) + arraysize(kNackList23)),
danilchap1e714ae2016-09-05 09:57:22 -07001490 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1491 nack_set.size()))));
danilchap142f0192016-10-20 08:22:42 -07001492 InjectRtcpPacket(two_nacks);
danilchap1e714ae2016-09-05 09:57:22 -07001493}
1494
1495TEST_F(RtcpReceiverTest, NackNotForUsIgnored) {
1496 const uint16_t kNackList1[] = {1, 2, 3, 5};
1497 const size_t kNackListLength1 = std::end(kNackList1) - std::begin(kNackList1);
1498
1499 rtcp::Nack nack;
danilchap822a16f2016-09-27 09:27:47 -07001500 nack.SetSenderSsrc(kSenderSsrc);
1501 nack.SetMediaSsrc(kNotToUsSsrc);
1502 nack.SetPacketIds(kNackList1, kNackListLength1);
danilchap1e714ae2016-09-05 09:57:22 -07001503
1504 EXPECT_CALL(packet_type_counter_observer_,
1505 RtcpPacketTypesCounterUpdated(
1506 _, Field(&RtcpPacketTypeCounter::nack_requests, 0)));
1507 InjectRtcpPacket(nack);
1508}
1509
1510TEST_F(RtcpReceiverTest, ForceSenderReport) {
1511 rtcp::RapidResyncRequest rr;
danilchap822a16f2016-09-27 09:27:47 -07001512 rr.SetSenderSsrc(kSenderSsrc);
1513 rr.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -07001514
1515 EXPECT_CALL(rtp_rtcp_impl_, OnRequestSendReport());
1516 InjectRtcpPacket(rr);
1517}
hta@webrtc.org47059b52012-05-02 07:46:22 +00001518
spranga790d832016-12-02 07:29:44 -08001519TEST_F(RtcpReceiverTest, ReceivesTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001520 VideoBitrateAllocation expected_allocation;
spranga790d832016-12-02 07:29:44 -08001521 expected_allocation.SetBitrate(0, 0, 10000);
1522 expected_allocation.SetBitrate(0, 1, 20000);
1523 expected_allocation.SetBitrate(1, 0, 40000);
1524 expected_allocation.SetBitrate(1, 1, 80000);
1525
1526 rtcp::TargetBitrate bitrate;
1527 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1528 bitrate.AddTargetBitrate(0, 1, expected_allocation.GetBitrate(0, 1) / 1000);
1529 bitrate.AddTargetBitrate(1, 0, expected_allocation.GetBitrate(1, 0) / 1000);
1530 bitrate.AddTargetBitrate(1, 1, expected_allocation.GetBitrate(1, 1) / 1000);
1531
1532 rtcp::ExtendedReports xr;
1533 xr.SetTargetBitrate(bitrate);
1534
sprangb32aaf92017-08-28 05:49:12 -07001535 // Wrong sender ssrc, target bitrate should be discarded.
1536 xr.SetSenderSsrc(kSenderSsrc + 1);
1537 EXPECT_CALL(bitrate_allocation_observer_,
1538 OnBitrateAllocationUpdated(expected_allocation))
1539 .Times(0);
1540 InjectRtcpPacket(xr);
1541
1542 // Set correct ssrc, callback should be called once.
1543 xr.SetSenderSsrc(kSenderSsrc);
spranga790d832016-12-02 07:29:44 -08001544 EXPECT_CALL(bitrate_allocation_observer_,
1545 OnBitrateAllocationUpdated(expected_allocation));
1546 InjectRtcpPacket(xr);
1547}
1548
sprang6d314c72016-12-06 06:08:53 -08001549TEST_F(RtcpReceiverTest, HandlesIncorrectTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001550 VideoBitrateAllocation expected_allocation;
sprang6d314c72016-12-06 06:08:53 -08001551 expected_allocation.SetBitrate(0, 0, 10000);
1552
1553 rtcp::TargetBitrate bitrate;
1554 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1555 bitrate.AddTargetBitrate(0, kMaxTemporalStreams, 20000);
1556 bitrate.AddTargetBitrate(kMaxSpatialLayers, 0, 40000);
1557
1558 rtcp::ExtendedReports xr;
1559 xr.SetTargetBitrate(bitrate);
sprangb32aaf92017-08-28 05:49:12 -07001560 xr.SetSenderSsrc(kSenderSsrc);
sprang6d314c72016-12-06 06:08:53 -08001561
1562 EXPECT_CALL(bitrate_allocation_observer_,
1563 OnBitrateAllocationUpdated(expected_allocation));
1564 InjectRtcpPacket(xr);
1565}
1566
hta@webrtc.org47059b52012-05-02 07:46:22 +00001567} // namespace webrtc