blob: e9c6e2cfecc48b5923e5b515d0f1109e60ec3dff [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&));
elad.alonf9490002017-03-06 05:32:21 -0800103 MOCK_CONST_METHOD0(GetTransportFeedbackVector, std::vector<PacketFeedback>());
danilchap1e714ae2016-09-05 09:57:22 -0700104};
105
danilchap1e714ae2016-09-05 09:57:22 -0700106class MockModuleRtpRtcp : public RTCPReceiver::ModuleRtpRtcp {
107 public:
108 MOCK_METHOD1(SetTmmbn, void(std::vector<rtcp::TmmbItem>));
109 MOCK_METHOD0(OnRequestSendReport, void());
110 MOCK_METHOD1(OnReceivedNack, void(const std::vector<uint16_t>&));
111 MOCK_METHOD1(OnReceivedRtcpReportBlocks, void(const ReportBlockList&));
112};
113
spranga790d832016-12-02 07:29:44 -0800114class MockVideoBitrateAllocationObserver
115 : public VideoBitrateAllocationObserver {
116 public:
117 MOCK_METHOD1(OnBitrateAllocationUpdated,
Erik Språng566124a2018-04-23 12:32:22 +0200118 void(const VideoBitrateAllocation& allocation));
spranga790d832016-12-02 07:29:44 -0800119};
120
danilchap1e714ae2016-09-05 09:57:22 -0700121// SSRC of remote peer, that sends rtcp packet to the rtcp receiver under test.
122constexpr uint32_t kSenderSsrc = 0x10203;
123// SSRCs of local peer, that rtcp packet addressed to.
124constexpr uint32_t kReceiverMainSsrc = 0x123456;
125// RtcpReceiver can accept several ssrc, e.g. regular and rtx streams.
126constexpr uint32_t kReceiverExtraSsrc = 0x1234567;
127// SSRCs to ignore (i.e. not configured in RtcpReceiver).
128constexpr uint32_t kNotToUsSsrc = 0x654321;
129constexpr uint32_t kUnknownSenderSsrc = 0x54321;
130
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800131constexpr int64_t kRtcpIntervalMs = 1000;
132
danilchap1e714ae2016-09-05 09:57:22 -0700133} // namespace
134
hta@webrtc.org47059b52012-05-02 07:46:22 +0000135class RtcpReceiverTest : public ::testing::Test {
136 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000137 RtcpReceiverTest()
danilchap1e714ae2016-09-05 09:57:22 -0700138 : system_clock_(1335900000),
Mirko Bonadei3b676722019-07-12 17:35:05 +0000139 rtcp_receiver_(
140 [&] {
141 RtpRtcp::Configuration config;
142 config.clock = &system_clock_;
143 config.receiver_only = false;
144 config.rtcp_packet_type_counter_observer =
145 &packet_type_counter_observer_;
146 config.bandwidth_callback = &bandwidth_observer_;
147 config.intra_frame_callback = &intra_frame_observer_;
148 config.rtcp_loss_notification_observer =
149 &rtcp_loss_notification_observer_;
150 config.transport_feedback_callback =
151 &transport_feedback_observer_;
152 config.bitrate_allocation_observer =
153 &bitrate_allocation_observer_;
154 config.rtcp_report_interval_ms = kRtcpIntervalMs;
155 config.media_send_ssrc = kReceiverMainSsrc;
156 config.rtx_send_ssrc = kReceiverExtraSsrc;
157 return config;
158 }(),
159 &rtp_rtcp_impl_) {}
danilchap1e714ae2016-09-05 09:57:22 -0700160 void SetUp() {
danilchap1e714ae2016-09-05 09:57:22 -0700161 rtcp_receiver_.SetRemoteSSRC(kSenderSsrc);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000162 }
Erik Språng737336d2016-07-29 12:59:36 +0200163
danilchap1e714ae2016-09-05 09:57:22 -0700164 void InjectRtcpPacket(rtc::ArrayView<const uint8_t> raw) {
165 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
hta@webrtc.org47059b52012-05-02 07:46:22 +0000166 }
167
danilchap1e714ae2016-09-05 09:57:22 -0700168 void InjectRtcpPacket(const rtcp::RtcpPacket& packet) {
169 rtc::Buffer raw = packet.Build();
170 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
171 }
172
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000173 SimulatedClock system_clock_;
danilchap1e714ae2016-09-05 09:57:22 -0700174 // Callbacks to packet_type_counter_observer are frequent but most of the time
175 // are not interesting.
176 NiceMock<MockRtcpPacketTypeCounterObserver> packet_type_counter_observer_;
177 StrictMock<MockRtcpBandwidthObserver> bandwidth_observer_;
178 StrictMock<MockRtcpIntraFrameObserver> intra_frame_observer_;
Elad Alon0a8562e2019-04-09 11:55:13 +0200179 StrictMock<MockRtcpLossNotificationObserver> rtcp_loss_notification_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700180 StrictMock<MockTransportFeedbackObserver> transport_feedback_observer_;
spranga790d832016-12-02 07:29:44 -0800181 StrictMock<MockVideoBitrateAllocationObserver> bitrate_allocation_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700182 StrictMock<MockModuleRtpRtcp> rtp_rtcp_impl_;
hta@webrtc.org47059b52012-05-02 07:46:22 +0000183
danilchap1e714ae2016-09-05 09:57:22 -0700184 RTCPReceiver rtcp_receiver_;
185};
hta@webrtc.org47059b52012-05-02 07:46:22 +0000186
187TEST_F(RtcpReceiverTest, BrokenPacketIsIgnored) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000188 const uint8_t bad_packet[] = {0, 0, 0, 0};
danilchap1e714ae2016-09-05 09:57:22 -0700189 EXPECT_CALL(packet_type_counter_observer_,
190 RtcpPacketTypesCounterUpdated(_, _))
191 .Times(0);
192 InjectRtcpPacket(bad_packet);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000193}
194
danilchap50da1d32016-03-10 13:13:52 -0800195TEST_F(RtcpReceiverTest, InvalidFeedbackPacketIsIgnored) {
196 // Too short feedback packet.
danilchap1e714ae2016-09-05 09:57:22 -0700197 const uint8_t bad_packet[] = {0x81, rtcp::Rtpfb::kPacketType, 0, 0};
198
199 // TODO(danilchap): Add expectation RtcpPacketTypesCounterUpdated
200 // is not called once parser would be adjusted to avoid that callback on
201 // semi-valid packets.
202 InjectRtcpPacket(bad_packet);
danilchap50da1d32016-03-10 13:13:52 -0800203}
204
hta@webrtc.org47059b52012-05-02 07:46:22 +0000205TEST_F(RtcpReceiverTest, InjectSrPacket) {
danilchapa04d9c32017-07-25 04:03:39 -0700206 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
danilchap1e714ae2016-09-05 09:57:22 -0700207
208 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000209 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700210 sr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700211
212 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
213 EXPECT_CALL(bandwidth_observer_,
214 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
215 InjectRtcpPacket(sr);
216
danilchapa04d9c32017-07-25 04:03:39 -0700217 EXPECT_TRUE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
hta@webrtc.org47059b52012-05-02 07:46:22 +0000218}
219
danilchap1e714ae2016-09-05 09:57:22 -0700220TEST_F(RtcpReceiverTest, InjectSrPacketFromUnknownSender) {
221 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000222 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700223 sr.SetSenderSsrc(kUnknownSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700224
225 // The parser will handle report blocks in Sender Report from other than his
226 // expected peer.
227 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
228 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, now));
229 InjectRtcpPacket(sr);
230
231 // But will not flag that he's gotten sender information.
danilchapa04d9c32017-07-25 04:03:39 -0700232 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000233}
234
Danil Chapovalova094fd12016-02-22 18:59:36 +0100235TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesRTT) {
236 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100237 const int64_t kRttMs = r.Rand(1, 9 * 3600 * 1000);
238 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
239 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100240
Danil Chapovalova094fd12016-02-22 18:59:36 +0100241 int64_t rtt_ms = 0;
242 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700243 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100244
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200245 uint32_t sent_ntp =
246 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100247 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
248
249 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700250 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100251 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700252 block.SetMediaSsrc(kReceiverMainSsrc);
253 block.SetLastSr(sent_ntp);
254 block.SetDelayLastSr(kDelayNtp);
255 sr.AddReportBlock(block);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100256
danilchap1e714ae2016-09-05 09:57:22 -0700257 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
258 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
259 InjectRtcpPacket(sr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100260
261 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700262 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100263 EXPECT_NEAR(kRttMs, rtt_ms, 1);
264}
265
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100266TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesNegativeRTTAsOne) {
267 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100268 const int64_t kRttMs = r.Rand(-3600 * 1000, -1);
269 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
270 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
271
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100272 int64_t rtt_ms = 0;
273 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700274 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100275
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200276 uint32_t sent_ntp =
277 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100278 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
279
280 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700281 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100282 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700283 block.SetMediaSsrc(kReceiverMainSsrc);
284 block.SetLastSr(sent_ntp);
285 block.SetDelayLastSr(kDelayNtp);
286 sr.AddReportBlock(block);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100287
danilchap1e714ae2016-09-05 09:57:22 -0700288 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
289 EXPECT_CALL(bandwidth_observer_,
290 OnReceivedRtcpReceiverReport(SizeIs(1), _, _));
291 InjectRtcpPacket(sr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100292
293 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700294 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100295 EXPECT_EQ(1, rtt_ms);
296}
297
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100298TEST_F(
299 RtcpReceiverTest,
300 TwoReportBlocksWithLastOneWithoutLastSrCalculatesRttForBandwidthObserver) {
301 const int64_t kRttMs = 120;
302 const uint32_t kDelayNtp = 123000;
303 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
304
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200305 uint32_t sent_ntp =
306 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100307 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
308
309 rtcp::SenderReport sr;
310 sr.SetSenderSsrc(kSenderSsrc);
311 rtcp::ReportBlock block;
312 block.SetMediaSsrc(kReceiverMainSsrc);
313 block.SetLastSr(sent_ntp);
314 block.SetDelayLastSr(kDelayNtp);
315 sr.AddReportBlock(block);
316 block.SetMediaSsrc(kReceiverExtraSsrc);
317 block.SetLastSr(0);
318 sr.AddReportBlock(block);
319
320 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
321 EXPECT_CALL(bandwidth_observer_,
322 OnReceivedRtcpReceiverReport(SizeIs(2), kRttMs, _));
323 InjectRtcpPacket(sr);
324}
325
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000326TEST_F(RtcpReceiverTest, InjectRrPacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700327 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000328 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700329 rr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700330
331 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
332 EXPECT_CALL(bandwidth_observer_,
333 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
334 InjectRtcpPacket(rr);
335
danilchap1e714ae2016-09-05 09:57:22 -0700336 std::vector<RTCPReportBlock> report_blocks;
337 rtcp_receiver_.StatisticsReceived(&report_blocks);
338 EXPECT_TRUE(report_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000339}
340
341TEST_F(RtcpReceiverTest, InjectRrPacketWithReportBlockNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700342 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000343 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700344 rb.SetMediaSsrc(kNotToUsSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000345 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700346 rr.SetSenderSsrc(kSenderSsrc);
347 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000348
danilchap1e714ae2016-09-05 09:57:22 -0700349 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
350 EXPECT_CALL(bandwidth_observer_,
351 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
352 InjectRtcpPacket(rr);
353
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200354 EXPECT_EQ(0, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000355 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700356 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000357 EXPECT_TRUE(received_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000358}
359
360TEST_F(RtcpReceiverTest, InjectRrPacketWithOneReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700361 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000362
363 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700364 rb.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000365 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700366 rr.SetSenderSsrc(kSenderSsrc);
367 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000368
danilchap1e714ae2016-09-05 09:57:22 -0700369 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
370 EXPECT_CALL(bandwidth_observer_,
371 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
372 InjectRtcpPacket(rr);
373
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200374 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
375 std::vector<RTCPReportBlock> received_blocks;
376 rtcp_receiver_.StatisticsReceived(&received_blocks);
377 EXPECT_EQ(1u, received_blocks.size());
378}
379
380TEST_F(RtcpReceiverTest, InjectSrPacketWithOneReportBlock) {
381 int64_t now = system_clock_.TimeInMilliseconds();
382
383 rtcp::ReportBlock rb;
384 rb.SetMediaSsrc(kReceiverMainSsrc);
385 rtcp::SenderReport sr;
386 sr.SetSenderSsrc(kSenderSsrc);
387 sr.AddReportBlock(rb);
388
389 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
390 EXPECT_CALL(bandwidth_observer_,
391 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
392 InjectRtcpPacket(sr);
393
394 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000395 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700396 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000397 EXPECT_EQ(1u, received_blocks.size());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000398}
399
400TEST_F(RtcpReceiverTest, InjectRrPacketWithTwoReportBlocks) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000401 const uint16_t kSequenceNumbers[] = {10, 12423};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000402 const uint32_t kCumLost[] = {13, 555};
403 const uint8_t kFracLost[] = {20, 11};
danilchap1e714ae2016-09-05 09:57:22 -0700404 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000405
406 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700407 rb1.SetMediaSsrc(kReceiverMainSsrc);
408 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
409 rb1.SetFractionLost(10);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000410
411 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700412 rb2.SetMediaSsrc(kReceiverExtraSsrc);
413 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
414 rb2.SetFractionLost(0);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000415
416 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700417 rr1.SetSenderSsrc(kSenderSsrc);
418 rr1.AddReportBlock(rb1);
419 rr1.AddReportBlock(rb2);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000420
danilchap1e714ae2016-09-05 09:57:22 -0700421 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
422 EXPECT_CALL(bandwidth_observer_,
423 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
424 InjectRtcpPacket(rr1);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000425
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200426 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700427 std::vector<RTCPReportBlock> received_blocks;
428 rtcp_receiver_.StatisticsReceived(&received_blocks);
429 EXPECT_THAT(received_blocks,
srte3e69e5c2017-08-09 06:13:45 -0700430 UnorderedElementsAre(Field(&RTCPReportBlock::fraction_lost, 0),
431 Field(&RTCPReportBlock::fraction_lost, 10)));
danilchap1e714ae2016-09-05 09:57:22 -0700432
433 // Insert next receiver report with same ssrc but new values.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000434 rtcp::ReportBlock rb3;
danilchap822a16f2016-09-27 09:27:47 -0700435 rb3.SetMediaSsrc(kReceiverMainSsrc);
436 rb3.SetExtHighestSeqNum(kSequenceNumbers[0]);
437 rb3.SetFractionLost(kFracLost[0]);
438 rb3.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000439
440 rtcp::ReportBlock rb4;
danilchap822a16f2016-09-27 09:27:47 -0700441 rb4.SetMediaSsrc(kReceiverExtraSsrc);
442 rb4.SetExtHighestSeqNum(kSequenceNumbers[1]);
443 rb4.SetFractionLost(kFracLost[1]);
444 rb4.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000445
446 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700447 rr2.SetSenderSsrc(kSenderSsrc);
448 rr2.AddReportBlock(rb3);
449 rr2.AddReportBlock(rb4);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000450
danilchap1e714ae2016-09-05 09:57:22 -0700451 // Advance time to make 1st sent time and 2nd sent time different.
452 system_clock_.AdvanceTimeMilliseconds(500);
453 now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000454
danilchap1e714ae2016-09-05 09:57:22 -0700455 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
456 EXPECT_CALL(bandwidth_observer_,
457 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
458 InjectRtcpPacket(rr2);
459
460 received_blocks.clear();
461 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000462 EXPECT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700463 EXPECT_THAT(
464 received_blocks,
465 UnorderedElementsAre(
466 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
467 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
468 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
469 Field(&RTCPReportBlock::extended_highest_sequence_number,
470 kSequenceNumbers[0])),
471 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverExtraSsrc),
472 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
473 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
474 Field(&RTCPReportBlock::extended_highest_sequence_number,
475 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000476}
477
478TEST_F(RtcpReceiverTest, InjectRrPacketsFromTwoRemoteSsrcs) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000479 const uint32_t kSenderSsrc2 = 0x20304;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000480 const uint16_t kSequenceNumbers[] = {10, 12423};
Sebastian Jansson9701e0c2018-08-09 11:21:11 +0200481 const int32_t kCumLost[] = {13, 555};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000482 const uint8_t kFracLost[] = {20, 11};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000483
484 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700485 rb1.SetMediaSsrc(kReceiverMainSsrc);
486 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
487 rb1.SetFractionLost(kFracLost[0]);
488 rb1.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000489 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700490 rr1.SetSenderSsrc(kSenderSsrc);
491 rr1.AddReportBlock(rb1);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000492
danilchap1e714ae2016-09-05 09:57:22 -0700493 int64_t now = system_clock_.TimeInMilliseconds();
494
495 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
496 EXPECT_CALL(bandwidth_observer_,
497 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
498 InjectRtcpPacket(rr1);
499
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200500 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000501
502 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700503 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000504 EXPECT_EQ(1u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700505 EXPECT_EQ(kSenderSsrc, received_blocks[0].sender_ssrc);
506 EXPECT_EQ(kReceiverMainSsrc, received_blocks[0].source_ssrc);
507 EXPECT_EQ(kFracLost[0], received_blocks[0].fraction_lost);
508 EXPECT_EQ(kCumLost[0], received_blocks[0].packets_lost);
509 EXPECT_EQ(kSequenceNumbers[0],
510 received_blocks[0].extended_highest_sequence_number);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000511
512 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700513 rb2.SetMediaSsrc(kReceiverMainSsrc);
514 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
515 rb2.SetFractionLost(kFracLost[1]);
516 rb2.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000517 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700518 rr2.SetSenderSsrc(kSenderSsrc2);
519 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -0700520
521 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
522 EXPECT_CALL(bandwidth_observer_,
523 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
524 InjectRtcpPacket(rr2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000525
526 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700527 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000528 ASSERT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700529 EXPECT_THAT(
530 received_blocks,
531 UnorderedElementsAre(
532 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
533 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc),
534 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
535 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
536 Field(&RTCPReportBlock::extended_highest_sequence_number,
537 kSequenceNumbers[0])),
538 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
539 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc2),
540 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
541 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
542 Field(&RTCPReportBlock::extended_highest_sequence_number,
543 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000544}
545
546TEST_F(RtcpReceiverTest, GetRtt) {
danilchap28b03eb2016-10-05 06:59:44 -0700547 const uint32_t kSentCompactNtp = 0x1234;
548 const uint32_t kDelayCompactNtp = 0x222;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000549 // No report block received.
Erik Språng6b8d3552015-09-24 15:06:57 +0200550 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700551 -1, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000552
553 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700554 rb.SetMediaSsrc(kReceiverMainSsrc);
danilchap28b03eb2016-10-05 06:59:44 -0700555 rb.SetLastSr(kSentCompactNtp);
556 rb.SetDelayLastSr(kDelayCompactNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700557
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000558 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700559 rr.SetSenderSsrc(kSenderSsrc);
560 rr.AddReportBlock(rb);
danilchap1e714ae2016-09-05 09:57:22 -0700561 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000562
danilchap1e714ae2016-09-05 09:57:22 -0700563 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
564 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
565 InjectRtcpPacket(rr);
566
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200567 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700568 EXPECT_EQ(
569 0, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000570}
571
danilchap1e714ae2016-09-05 09:57:22 -0700572// Ij packets are ignored.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000573TEST_F(RtcpReceiverTest, InjectIjWithNoItem) {
danilchapf8506cb2015-11-13 07:33:20 -0800574 rtcp::ExtendedJitterReport ij;
danilchap1e714ae2016-09-05 09:57:22 -0700575 InjectRtcpPacket(ij);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000576}
577
danilchap1e714ae2016-09-05 09:57:22 -0700578// App packets are ignored.
579TEST_F(RtcpReceiverTest, InjectApp) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000580 rtcp::App app;
danilchap822a16f2016-09-27 09:27:47 -0700581 app.SetSubType(30);
582 app.SetName(0x17a177e);
danilchap1e714ae2016-09-05 09:57:22 -0700583 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
danilchap822a16f2016-09-27 09:27:47 -0700584 app.SetData(kData, sizeof(kData));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000585
danilchap1e714ae2016-09-05 09:57:22 -0700586 InjectRtcpPacket(app);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000587}
588
589TEST_F(RtcpReceiverTest, InjectSdesWithOneChunk) {
danilchap1e714ae2016-09-05 09:57:22 -0700590 const char kCname[] = "alice@host";
Niels Möller4d7c4052019-08-05 12:45:19 +0200591 MockCnameCallbackImpl callback;
592 rtcp_receiver_.RegisterRtcpCnameCallback(&callback);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000593 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700594 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000595
Niels Möller4d7c4052019-08-05 12:45:19 +0200596 EXPECT_CALL(callback, OnCname(kSenderSsrc, StrEq(kCname)));
danilchap1e714ae2016-09-05 09:57:22 -0700597 InjectRtcpPacket(sdes);
598
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000599 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700600 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
601 EXPECT_EQ(0, strncmp(cName, kCname, RTCP_CNAME_SIZE));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000602}
603
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000604TEST_F(RtcpReceiverTest, InjectByePacket_RemovesCname) {
danilchap1e714ae2016-09-05 09:57:22 -0700605 const char kCname[] = "alice@host";
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000606 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700607 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000608
danilchap1e714ae2016-09-05 09:57:22 -0700609 InjectRtcpPacket(sdes);
610
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000611 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700612 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000613
614 // Verify that BYE removes the CNAME.
615 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700616 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700617
618 InjectRtcpPacket(bye);
619
620 EXPECT_EQ(-1, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000621}
622
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000623TEST_F(RtcpReceiverTest, InjectByePacket_RemovesReportBlocks) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000624 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700625 rb1.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000626 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700627 rb2.SetMediaSsrc(kReceiverExtraSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000628 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700629 rr.SetSenderSsrc(kSenderSsrc);
630 rr.AddReportBlock(rb1);
631 rr.AddReportBlock(rb2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000632
danilchap1e714ae2016-09-05 09:57:22 -0700633 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
634 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
635 InjectRtcpPacket(rr);
636
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000637 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700638 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000639 EXPECT_EQ(2u, received_blocks.size());
640
641 // Verify that BYE removes the report blocks.
642 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700643 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700644
645 InjectRtcpPacket(bye);
646
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000647 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700648 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000649 EXPECT_TRUE(received_blocks.empty());
650
danilchap1e714ae2016-09-05 09:57:22 -0700651 // Inject packet again.
652 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
653 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
654 InjectRtcpPacket(rr);
655
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000656 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700657 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000658 EXPECT_EQ(2u, received_blocks.size());
659}
660
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200661TEST_F(RtcpReceiverTest, InjectByePacketRemovesReferenceTimeInfo) {
662 rtcp::ExtendedReports xr;
663 xr.SetSenderSsrc(kSenderSsrc);
664 rtcp::Rrtr rrtr;
665 rrtr.SetNtp(NtpTime(0x10203, 0x40506));
666 xr.SetRrtr(rrtr);
667 InjectRtcpPacket(xr);
668
669 rtcp::Bye bye;
670 bye.SetSenderSsrc(kSenderSsrc);
671 InjectRtcpPacket(bye);
672
673 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
674}
675
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000676TEST_F(RtcpReceiverTest, InjectPliPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000677 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700678 pli.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700679
680 EXPECT_CALL(
681 packet_type_counter_observer_,
682 RtcpPacketTypesCounterUpdated(
683 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 1)));
684 EXPECT_CALL(intra_frame_observer_,
685 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
686 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000687}
688
689TEST_F(RtcpReceiverTest, PliPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000690 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700691 pli.SetMediaSsrc(kNotToUsSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700692
693 EXPECT_CALL(
694 packet_type_counter_observer_,
695 RtcpPacketTypesCounterUpdated(
696 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 0)));
697 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
698 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000699}
700
701TEST_F(RtcpReceiverTest, InjectFirPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000702 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700703 fir.AddRequestTo(kReceiverMainSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700704
705 EXPECT_CALL(
706 packet_type_counter_observer_,
707 RtcpPacketTypesCounterUpdated(
708 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::fir_packets, 1)));
709 EXPECT_CALL(intra_frame_observer_,
710 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
711 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000712}
713
714TEST_F(RtcpReceiverTest, FirPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000715 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700716 fir.AddRequestTo(kNotToUsSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700717
718 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
719 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000720}
721
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100722TEST_F(RtcpReceiverTest, ExtendedReportsPacketWithZeroReportBlocksIgnored) {
723 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700724 xr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700725
726 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000727}
728
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100729TEST_F(RtcpReceiverTest, InjectExtendedReportsReceiverReferenceTimePacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700730 const NtpTime kNtp(0x10203, 0x40506);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000731 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700732 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100733 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700734 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700735 xr.SetRrtr(rrtr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000736
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200737 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
738 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
739 EXPECT_THAT(last_xr_rtis, IsEmpty());
danilchap1e714ae2016-09-05 09:57:22 -0700740
741 InjectRtcpPacket(xr);
742
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200743 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
744 ASSERT_THAT(last_xr_rtis, SizeIs(1));
745 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
746 EXPECT_EQ(CompactNtp(kNtp), last_xr_rtis[0].last_rr);
747 EXPECT_EQ(0U, last_xr_rtis[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000748}
749
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100750TEST_F(RtcpReceiverTest, ExtendedReportsDlrrPacketNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700751 // Allow calculate rtt using dlrr/rrtr, simulating media receiver side.
752 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000753
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100754 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700755 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700756 xr.AddDlrrItem(ReceiveTimeInfo(kNotToUsSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700757
758 InjectRtcpPacket(xr);
759
760 int64_t rtt_ms = 0;
761 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000762}
763
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100764TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithSubBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700765 const uint32_t kLastRR = 0x12345;
766 const uint32_t kDelay = 0x23456;
767 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
768 int64_t rtt_ms = 0;
769 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000770
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100771 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700772 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700773 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
danilchap1e714ae2016-09-05 09:57:22 -0700774
775 InjectRtcpPacket(xr);
776
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200777 uint32_t compact_ntp_now =
778 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700779 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
780 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
781 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000782}
783
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100784TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithMultipleSubBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700785 const uint32_t kLastRR = 0x12345;
786 const uint32_t kDelay = 0x56789;
787 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000788
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100789 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700790 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700791 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
792 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 1, 0x12345, 0x67890));
793 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 2, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700794
795 InjectRtcpPacket(xr);
796
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200797 uint32_t compact_ntp_now =
798 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700799 int64_t rtt_ms = 0;
800 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
801 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
802 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000803}
804
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100805TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithMultipleReportBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700806 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000807
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000808 rtcp::Rrtr rrtr;
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100809 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700810 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700811 xr.SetRrtr(rrtr);
812 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700813
814 InjectRtcpPacket(xr);
815
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200816 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
817 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
818 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700819 int64_t rtt_ms = 0;
820 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000821}
822
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100823TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithUnknownReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700824 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000825
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000826 rtcp::Rrtr rrtr;
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100827 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700828 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700829 xr.SetRrtr(rrtr);
830 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700831
danilchap69e59e62016-02-17 03:11:42 -0800832 rtc::Buffer packet = xr.Build();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000833 // Modify the DLRR block to have an unsupported block type, from 5 to 6.
danilchap1e714ae2016-09-05 09:57:22 -0700834 ASSERT_EQ(5, packet.data()[20]);
835 packet.data()[20] = 6;
836 InjectRtcpPacket(packet);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000837
danilchap1e714ae2016-09-05 09:57:22 -0700838 // Validate Rrtr was received and processed.
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200839 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
840 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
841 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700842 // Validate Dlrr report wasn't processed.
843 int64_t rtt_ms = 0;
844 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000845}
846
danilchap1e714ae2016-09-05 09:57:22 -0700847TEST_F(RtcpReceiverTest, TestExtendedReportsRrRttInitiallyFalse) {
848 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
849
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000850 int64_t rtt_ms;
danilchap1e714ae2016-09-05 09:57:22 -0700851 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000852}
853
danilchap1e714ae2016-09-05 09:57:22 -0700854TEST_F(RtcpReceiverTest, RttCalculatedAfterExtendedReportsDlrr) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100855 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100856 const int64_t kRttMs = rand.Rand(1, 9 * 3600 * 1000);
857 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
858 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700859 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200860 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalova094fd12016-02-22 18:59:36 +0100861 uint32_t sent_ntp = CompactNtp(now);
862 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
863
Danil Chapovalova094fd12016-02-22 18:59:36 +0100864 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700865 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700866 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700867
868 InjectRtcpPacket(xr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100869
870 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700871 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100872 EXPECT_NEAR(kRttMs, rtt_ms, 1);
873}
874
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100875TEST_F(RtcpReceiverTest, XrDlrrCalculatesNegativeRttAsOne) {
876 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100877 const int64_t kRttMs = rand.Rand(-3600 * 1000, -1);
878 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
879 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200880 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100881 uint32_t sent_ntp = CompactNtp(now);
882 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
danilchap1e714ae2016-09-05 09:57:22 -0700883 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100884
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100885 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700886 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700887 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700888
889 InjectRtcpPacket(xr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100890
891 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700892 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100893 EXPECT_EQ(1, rtt_ms);
894}
895
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200896TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfoInitiallyEmpty) {
897 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000898}
899
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200900TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfo) {
Danil Chapovalovfc47ed62015-12-07 14:46:35 +0100901 const NtpTime kNtp(0x10203, 0x40506);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100902 const uint32_t kNtpMid = CompactNtp(kNtp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000903
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000904 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700905 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100906 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700907 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700908 xr.SetRrtr(rrtr);
danilchap1e714ae2016-09-05 09:57:22 -0700909
910 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000911
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000912 system_clock_.AdvanceTimeMilliseconds(1000);
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200913
914 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
915 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
916 ASSERT_THAT(last_xr_rtis, SizeIs(1));
917 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
918 EXPECT_EQ(kNtpMid, last_xr_rtis[0].last_rr);
919 EXPECT_EQ(65536U, last_xr_rtis[0].delay_since_last_rr);
920}
921
922TEST_F(RtcpReceiverTest,
923 ReceivedRrtrFromSameSsrcUpdatesReceivedReferenceTimeInfo) {
924 const NtpTime kNtp1(0x10203, 0x40506);
925 const NtpTime kNtp2(0x11223, 0x44556);
926 const int64_t kDelayMs = 2000;
927
928 rtcp::ExtendedReports xr;
929 xr.SetSenderSsrc(kSenderSsrc);
930 rtcp::Rrtr rrtr1;
931 rrtr1.SetNtp(kNtp1);
932 xr.SetRrtr(rrtr1);
933 InjectRtcpPacket(xr);
934 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
935 rtcp::Rrtr rrtr2;
936 rrtr2.SetNtp(kNtp2);
937 xr.SetRrtr(rrtr2);
938 InjectRtcpPacket(xr);
939 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
940
941 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
942 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
943 ASSERT_THAT(last_xr_rtis, SizeIs(1));
944 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
945 EXPECT_EQ(CompactNtp(kNtp2), last_xr_rtis[0].last_rr);
946 EXPECT_EQ(kDelayMs * 65536 / 1000, last_xr_rtis[0].delay_since_last_rr);
947}
948
949TEST_F(RtcpReceiverTest, StoresLastReceivedRrtrPerSsrc) {
950 const size_t kNumBufferedReports = 1;
951 const size_t kNumReports =
952 rtcp::ExtendedReports::kMaxNumberOfDlrrItems + kNumBufferedReports;
953 for (size_t i = 0; i < kNumReports; ++i) {
954 rtcp::ExtendedReports xr;
955 xr.SetSenderSsrc(i * 100);
956 rtcp::Rrtr rrtr;
957 rrtr.SetNtp(NtpTime(i * 200, i * 300));
958 xr.SetRrtr(rrtr);
959 InjectRtcpPacket(xr);
960 system_clock_.AdvanceTimeMilliseconds(1000);
961 }
962
963 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
964 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
965 ASSERT_THAT(last_xr_rtis,
966 SizeIs(rtcp::ExtendedReports::kMaxNumberOfDlrrItems));
967 for (size_t i = 0; i < rtcp::ExtendedReports::kMaxNumberOfDlrrItems; ++i) {
968 EXPECT_EQ(i * 100, last_xr_rtis[i].ssrc);
969 EXPECT_EQ(CompactNtp(NtpTime(i * 200, i * 300)), last_xr_rtis[i].last_rr);
970 EXPECT_EQ(65536U * (kNumReports - i), last_xr_rtis[i].delay_since_last_rr);
971 }
972
973 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
974 ASSERT_THAT(last_xr_rtis, SizeIs(kNumBufferedReports));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000975}
976
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000977TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000978 const uint16_t kSequenceNumber = 1234;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000979 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000980
981 // No RR received, shouldn't trigger a timeout.
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800982 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
983 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000984
985 // Add a RR and advance the clock just enough to not trigger a timeout.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000986 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700987 rb1.SetMediaSsrc(kReceiverMainSsrc);
988 rb1.SetExtHighestSeqNum(kSequenceNumber);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000989 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700990 rr1.SetSenderSsrc(kSenderSsrc);
991 rr1.AddReportBlock(rb1);
danilchap1e714ae2016-09-05 09:57:22 -0700992
993 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
994 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
995 InjectRtcpPacket(rr1);
996
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000997 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs - 1);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800998 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
999 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001000
1001 // Add a RR with the same extended max as the previous RR to trigger a
1002 // sequence number timeout, but not a RR timeout.
danilchap1e714ae2016-09-05 09:57:22 -07001003 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1004 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1005 InjectRtcpPacket(rr1);
1006
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001007 system_clock_.AdvanceTimeMilliseconds(2);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001008 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1009 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001010
1011 // Advance clock enough to trigger an RR timeout too.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001012 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001013 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001014
1015 // We should only get one timeout even though we still haven't received a new
1016 // RR.
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001017 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1018 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001019
1020 // Add a new RR with increase sequence number to reset timers.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001021 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001022 rb2.SetMediaSsrc(kReceiverMainSsrc);
1023 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001024 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001025 rr2.SetSenderSsrc(kSenderSsrc);
1026 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001027
1028 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1029 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1030 InjectRtcpPacket(rr2);
1031
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001032 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1033 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001034
1035 // Verify we can get a timeout again once we've received new RR.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001036 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -07001037 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1038 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1039 InjectRtcpPacket(rr2);
1040
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001041 system_clock_.AdvanceTimeMilliseconds(kRtcpIntervalMs + 1);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001042 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1043 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
danilchap1e714ae2016-09-05 09:57:22 -07001044
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001045 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001046 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001047}
1048
hta@webrtc.org47059b52012-05-02 07:46:22 +00001049TEST_F(RtcpReceiverTest, TmmbrReceivedWithNoIncomingPacket) {
danilchap1e714ae2016-09-05 09:57:22 -07001050 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001051}
1052
1053TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) {
danilchap1e714ae2016-09-05 09:57:22 -07001054 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001055 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001056 tmmbr.SetSenderSsrc(kSenderSsrc);
1057 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001058 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001059 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001060 rtcp::CompoundPacket compound;
1061 compound.Append(&sr);
1062 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001063
danilchap1e714ae2016-09-05 09:57:22 -07001064 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1065 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(SizeIs(1)));
1066 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1067 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1068 InjectRtcpPacket(compound);
1069
1070 std::vector<rtcp::TmmbItem> tmmbr_received = rtcp_receiver_.TmmbrReceived();
1071 ASSERT_EQ(1u, tmmbr_received.size());
1072 EXPECT_EQ(kBitrateBps, tmmbr_received[0].bitrate_bps());
1073 EXPECT_EQ(kSenderSsrc, tmmbr_received[0].ssrc());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001074}
1075
1076TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -07001077 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001078 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001079 tmmbr.SetSenderSsrc(kSenderSsrc);
1080 tmmbr.AddTmmbr(rtcp::TmmbItem(kNotToUsSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001081
1082 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001083 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001084 rtcp::CompoundPacket compound;
1085 compound.Append(&sr);
1086 compound.Append(&tmmbr);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001087
danilchap1e714ae2016-09-05 09:57:22 -07001088 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1089 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1090 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1091 InjectRtcpPacket(compound);
1092
1093 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001094}
1095
1096TEST_F(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001097 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001098 tmmbr.SetSenderSsrc(kSenderSsrc);
1099 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 0, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001100 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001101 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001102 rtcp::CompoundPacket compound;
1103 compound.Append(&sr);
1104 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001105
danilchap1e714ae2016-09-05 09:57:22 -07001106 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1107 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1108 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1109 InjectRtcpPacket(compound);
1110
1111 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001112}
1113
hta@webrtc.org404843e2012-05-02 09:56:45 +00001114TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001115 // Inject 3 packets "from" kSenderSsrc, kSenderSsrc+1, kSenderSsrc+2.
hta@webrtc.org404843e2012-05-02 09:56:45 +00001116 // The times of arrival are starttime + 0, starttime + 5 and starttime + 10.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001117 for (uint32_t ssrc = kSenderSsrc; ssrc < kSenderSsrc + 3; ++ssrc) {
1118 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001119 tmmbr.SetSenderSsrc(ssrc);
1120 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 30000, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001121 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001122 sr.SetSenderSsrc(ssrc);
danilchap7a4116a2016-03-14 08:19:28 -07001123 rtcp::CompoundPacket compound;
1124 compound.Append(&sr);
1125 compound.Append(&tmmbr);
danilchap1e714ae2016-09-05 09:57:22 -07001126
1127 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1128 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(_));
1129 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1130 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_));
1131 InjectRtcpPacket(compound);
1132
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001133 // 5 seconds between each packet.
1134 system_clock_.AdvanceTimeMilliseconds(5000);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001135 }
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001136 // It is now starttime + 15.
danilchap1e714ae2016-09-05 09:57:22 -07001137 std::vector<rtcp::TmmbItem> candidate_set = rtcp_receiver_.TmmbrReceived();
1138 ASSERT_EQ(3u, candidate_set.size());
1139 EXPECT_EQ(30000U, candidate_set[0].bitrate_bps());
1140
hta@webrtc.org404843e2012-05-02 09:56:45 +00001141 // We expect the timeout to be 25 seconds. Advance the clock by 12
1142 // seconds, timing out the first packet.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001143 system_clock_.AdvanceTimeMilliseconds(12000);
danilchap1e714ae2016-09-05 09:57:22 -07001144 candidate_set = rtcp_receiver_.TmmbrReceived();
1145 ASSERT_EQ(2u, candidate_set.size());
danilchap287e5482016-08-16 15:15:39 -07001146 EXPECT_EQ(kSenderSsrc + 1, candidate_set[0].ssrc());
hta@webrtc.org404843e2012-05-02 09:56:45 +00001147}
1148
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001149TEST_F(RtcpReceiverTest, Callbacks) {
danilchap1e714ae2016-09-05 09:57:22 -07001150 MockRtcpCallbackImpl callback;
1151 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001152
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001153 const uint8_t kFractionLoss = 3;
1154 const uint32_t kCumulativeLoss = 7;
1155 const uint32_t kJitter = 9;
1156 const uint16_t kSequenceNumber = 1234;
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001157
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001158 // First packet, all numbers should just propagate.
1159 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -07001160 rb1.SetMediaSsrc(kReceiverMainSsrc);
1161 rb1.SetExtHighestSeqNum(kSequenceNumber);
1162 rb1.SetFractionLost(kFractionLoss);
1163 rb1.SetCumulativeLost(kCumulativeLoss);
1164 rb1.SetJitter(kJitter);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001165
1166 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -07001167 rr1.SetSenderSsrc(kSenderSsrc);
1168 rr1.AddReportBlock(rb1);
srte186d9c32017-08-04 05:03:53 -07001169 EXPECT_CALL(callback,
1170 StatisticsUpdated(
1171 AllOf(Field(&RtcpStatistics::fraction_lost, kFractionLoss),
1172 Field(&RtcpStatistics::packets_lost, kCumulativeLoss),
1173 Field(&RtcpStatistics::extended_highest_sequence_number,
1174 kSequenceNumber),
1175 Field(&RtcpStatistics::jitter, kJitter)),
1176 kReceiverMainSsrc));
danilchap1e714ae2016-09-05 09:57:22 -07001177 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1178 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1179 InjectRtcpPacket(rr1);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001180
danilchap1e714ae2016-09-05 09:57:22 -07001181 rtcp_receiver_.RegisterRtcpStatisticsCallback(nullptr);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001182
danilchap1e714ae2016-09-05 09:57:22 -07001183 // Add arbitrary numbers, callback should not be called.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001184 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001185 rb2.SetMediaSsrc(kReceiverMainSsrc);
1186 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
1187 rb2.SetFractionLost(42);
1188 rb2.SetCumulativeLost(137);
1189 rb2.SetJitter(4711);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001190
1191 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001192 rr2.SetSenderSsrc(kSenderSsrc);
1193 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001194
1195 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1196 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1197 EXPECT_CALL(callback, StatisticsUpdated(_, _)).Times(0);
1198 InjectRtcpPacket(rr2);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001199}
hta@webrtc.org404843e2012-05-02 09:56:45 +00001200
Henrik Boströmf2047872019-05-16 13:32:20 +02001201TEST_F(RtcpReceiverTest,
1202 VerifyBlockAndTimestampObtainedFromReportBlockDataObserver) {
1203 MockReportBlockDataObserverImpl observer;
1204 rtcp_receiver_.SetReportBlockDataObserver(&observer);
1205
1206 const uint8_t kFractionLoss = 3;
1207 const uint32_t kCumulativeLoss = 7;
1208 const uint32_t kJitter = 9;
1209 const uint16_t kSequenceNumber = 1234;
1210 const int64_t kUtcNowUs = 42;
1211
1212 // The "report_block_timestamp_utc_us" is obtained from the global UTC clock
1213 // (not the simulcated |system_clock_|) and requires a scoped fake clock.
1214 rtc::ScopedFakeClock fake_clock;
1215 fake_clock.SetTime(Timestamp::us(kUtcNowUs));
1216
1217 rtcp::ReportBlock rtcp_block;
1218 rtcp_block.SetMediaSsrc(kReceiverMainSsrc);
1219 rtcp_block.SetExtHighestSeqNum(kSequenceNumber);
1220 rtcp_block.SetFractionLost(kFractionLoss);
1221 rtcp_block.SetCumulativeLost(kCumulativeLoss);
1222 rtcp_block.SetJitter(kJitter);
1223
1224 rtcp::ReceiverReport rtcp_report;
1225 rtcp_report.SetSenderSsrc(kSenderSsrc);
1226 rtcp_report.AddReportBlock(rtcp_block);
1227 EXPECT_CALL(observer, OnReportBlockDataUpdated)
1228 .WillOnce([&](ReportBlockData report_block_data) {
1229 const auto& report_block = report_block_data.report_block();
1230 EXPECT_EQ(rtcp_block.source_ssrc(), report_block.source_ssrc);
1231 EXPECT_EQ(kSenderSsrc, report_block.sender_ssrc);
1232 EXPECT_EQ(rtcp_block.fraction_lost(), report_block.fraction_lost);
1233 EXPECT_EQ(rtcp_block.cumulative_lost_signed(),
1234 report_block.packets_lost);
1235 EXPECT_EQ(rtcp_block.extended_high_seq_num(),
1236 report_block.extended_highest_sequence_number);
1237 EXPECT_EQ(rtcp_block.jitter(), report_block.jitter);
1238 EXPECT_EQ(kUtcNowUs, report_block_data.report_block_timestamp_utc_us());
1239 // No RTT is calculated in this test.
1240 EXPECT_EQ(0u, report_block_data.num_rtts());
1241 });
1242 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1243 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1244 InjectRtcpPacket(rtcp_report);
1245}
1246
1247TEST_F(RtcpReceiverTest, VerifyRttObtainedFromReportBlockDataObserver) {
1248 MockReportBlockDataObserverImpl observer;
1249 rtcp_receiver_.SetReportBlockDataObserver(&observer);
1250
1251 const int64_t kRttMs = 120;
1252 const uint32_t kDelayNtp = 123000;
1253 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
1254
1255 uint32_t sent_ntp =
1256 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
1257 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
1258
1259 rtcp::SenderReport sr;
1260 sr.SetSenderSsrc(kSenderSsrc);
1261 rtcp::ReportBlock block;
1262 block.SetMediaSsrc(kReceiverMainSsrc);
1263 block.SetLastSr(sent_ntp);
1264 block.SetDelayLastSr(kDelayNtp);
1265 sr.AddReportBlock(block);
1266 block.SetMediaSsrc(kReceiverExtraSsrc);
1267 block.SetLastSr(0);
1268 sr.AddReportBlock(block);
1269
1270 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1271 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1272 InSequence sequence;
1273 EXPECT_CALL(observer, OnReportBlockDataUpdated)
1274 .WillOnce([&](ReportBlockData report_block_data) {
1275 EXPECT_EQ(kReceiverMainSsrc,
1276 report_block_data.report_block().source_ssrc);
1277 EXPECT_EQ(1u, report_block_data.num_rtts());
1278 EXPECT_EQ(kRttMs, report_block_data.min_rtt_ms());
1279 EXPECT_EQ(kRttMs, report_block_data.max_rtt_ms());
1280 EXPECT_EQ(kRttMs, report_block_data.sum_rtt_ms());
1281 EXPECT_EQ(kRttMs, report_block_data.last_rtt_ms());
1282 });
1283 EXPECT_CALL(observer, OnReportBlockDataUpdated)
1284 .WillOnce([](ReportBlockData report_block_data) {
1285 EXPECT_EQ(kReceiverExtraSsrc,
1286 report_block_data.report_block().source_ssrc);
1287 EXPECT_EQ(0u, report_block_data.num_rtts());
1288 });
1289 InjectRtcpPacket(sr);
1290}
1291
1292TEST_F(RtcpReceiverTest, GetReportBlockDataAfterOneReportBlock) {
1293 const uint16_t kSequenceNumber = 1234;
1294
1295 rtcp::ReportBlock rtcp_block;
1296 rtcp_block.SetMediaSsrc(kReceiverMainSsrc);
1297 rtcp_block.SetExtHighestSeqNum(kSequenceNumber);
1298
1299 rtcp::ReceiverReport rtcp_report;
1300 rtcp_report.SetSenderSsrc(kSenderSsrc);
1301 rtcp_report.AddReportBlock(rtcp_block);
1302 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1303 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1304 InjectRtcpPacket(rtcp_report);
1305
1306 auto report_block_datas = rtcp_receiver_.GetLatestReportBlockData();
1307 ASSERT_THAT(report_block_datas, SizeIs(1));
1308 EXPECT_EQ(kReceiverMainSsrc,
1309 report_block_datas[0].report_block().source_ssrc);
1310 EXPECT_EQ(
1311 kSequenceNumber,
1312 report_block_datas[0].report_block().extended_highest_sequence_number);
1313}
1314
1315TEST_F(RtcpReceiverTest, GetReportBlockDataAfterTwoReportBlocksOfSameSsrc) {
1316 const uint16_t kSequenceNumber1 = 1234;
1317 const uint16_t kSequenceNumber2 = 1235;
1318
1319 rtcp::ReportBlock rtcp_block1;
1320 rtcp_block1.SetMediaSsrc(kReceiverMainSsrc);
1321 rtcp_block1.SetExtHighestSeqNum(kSequenceNumber1);
1322
1323 rtcp::ReceiverReport rtcp_report1;
1324 rtcp_report1.SetSenderSsrc(kSenderSsrc);
1325 rtcp_report1.AddReportBlock(rtcp_block1);
1326 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1327 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1328 InjectRtcpPacket(rtcp_report1);
1329
1330 // Inject a report block with an increased the sequence number for the same
1331 // source SSRC.
1332 rtcp::ReportBlock rtcp_block2;
1333 rtcp_block2.SetMediaSsrc(kReceiverMainSsrc);
1334 rtcp_block2.SetExtHighestSeqNum(kSequenceNumber2);
1335
1336 rtcp::ReceiverReport rtcp_report2;
1337 rtcp_report2.SetSenderSsrc(kSenderSsrc);
1338 rtcp_report2.AddReportBlock(rtcp_block2);
1339 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1340 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1341 InjectRtcpPacket(rtcp_report2);
1342
1343 // Only the latest block should be returned.
1344 auto report_block_datas = rtcp_receiver_.GetLatestReportBlockData();
1345 ASSERT_THAT(report_block_datas, SizeIs(1));
1346 EXPECT_EQ(kReceiverMainSsrc,
1347 report_block_datas[0].report_block().source_ssrc);
1348 EXPECT_EQ(
1349 kSequenceNumber2,
1350 report_block_datas[0].report_block().extended_highest_sequence_number);
1351}
1352
1353TEST_F(RtcpReceiverTest,
1354 GetReportBlockDataAfterTwoReportBlocksOfDifferentSsrcs) {
1355 const uint16_t kSequenceNumber1 = 1234;
1356 const uint16_t kSequenceNumber2 = 42;
1357
1358 rtcp::ReportBlock rtcp_block1;
1359 rtcp_block1.SetMediaSsrc(kReceiverMainSsrc);
1360 rtcp_block1.SetExtHighestSeqNum(kSequenceNumber1);
1361
1362 rtcp::ReceiverReport rtcp_report1;
1363 rtcp_report1.SetSenderSsrc(kSenderSsrc);
1364 rtcp_report1.AddReportBlock(rtcp_block1);
1365 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1366 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1367 InjectRtcpPacket(rtcp_report1);
1368
1369 // Inject a report block for a different source SSRC.
1370 rtcp::ReportBlock rtcp_block2;
1371 rtcp_block2.SetMediaSsrc(kReceiverExtraSsrc);
1372 rtcp_block2.SetExtHighestSeqNum(kSequenceNumber2);
1373
1374 rtcp::ReceiverReport rtcp_report2;
1375 rtcp_report2.SetSenderSsrc(kSenderSsrc);
1376 rtcp_report2.AddReportBlock(rtcp_block2);
1377 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1378 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1379 InjectRtcpPacket(rtcp_report2);
1380
1381 // Both report blocks should be returned.
1382 auto report_block_datas = rtcp_receiver_.GetLatestReportBlockData();
1383 ASSERT_THAT(report_block_datas, SizeIs(2));
1384 EXPECT_EQ(kReceiverMainSsrc,
1385 report_block_datas[0].report_block().source_ssrc);
1386 EXPECT_EQ(
1387 kSequenceNumber1,
1388 report_block_datas[0].report_block().extended_highest_sequence_number);
1389 EXPECT_EQ(kReceiverExtraSsrc,
1390 report_block_datas[1].report_block().source_ssrc);
1391 EXPECT_EQ(
1392 kSequenceNumber2,
1393 report_block_datas[1].report_block().extended_highest_sequence_number);
1394}
1395
sprang49f9cdb2015-10-01 03:06:57 -07001396TEST_F(RtcpReceiverTest, ReceivesTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001397 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001398 packet.SetMediaSsrc(kReceiverMainSsrc);
1399 packet.SetSenderSsrc(kSenderSsrc);
1400 packet.SetBase(1, 1000);
1401 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001402
danilchap1e714ae2016-09-05 09:57:22 -07001403 EXPECT_CALL(
1404 transport_feedback_observer_,
1405 OnTransportFeedback(AllOf(
1406 Property(&rtcp::TransportFeedback::media_ssrc, kReceiverMainSsrc),
1407 Property(&rtcp::TransportFeedback::sender_ssrc, kSenderSsrc))));
1408 InjectRtcpPacket(packet);
sprang49f9cdb2015-10-01 03:06:57 -07001409}
1410
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001411TEST_F(RtcpReceiverTest, ReceivesRemb) {
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001412 const uint32_t kBitrateBps = 500000;
1413 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001414 remb.SetSenderSsrc(kSenderSsrc);
1415 remb.SetBitrateBps(kBitrateBps);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001416
danilchap1e714ae2016-09-05 09:57:22 -07001417 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1418 InjectRtcpPacket(remb);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001419}
1420
sprang49f9cdb2015-10-01 03:06:57 -07001421TEST_F(RtcpReceiverTest, HandlesInvalidTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001422 // Send a compound packet with a TransportFeedback followed by something else.
1423 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001424 packet.SetMediaSsrc(kReceiverMainSsrc);
1425 packet.SetSenderSsrc(kSenderSsrc);
1426 packet.SetBase(1, 1000);
1427 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001428
1429 static uint32_t kBitrateBps = 50000;
1430 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001431 remb.SetSenderSsrc(kSenderSsrc);
1432 remb.SetBitrateBps(kBitrateBps);
danilchap7a4116a2016-03-14 08:19:28 -07001433 rtcp::CompoundPacket compound;
1434 compound.Append(&packet);
1435 compound.Append(&remb);
1436 rtc::Buffer built_packet = compound.Build();
sprang49f9cdb2015-10-01 03:06:57 -07001437
1438 // Modify the TransportFeedback packet so that it is invalid.
1439 const size_t kStatusCountOffset = 14;
Yves Gerey665174f2018-06-19 15:03:05 +02001440 ByteWriter<uint16_t>::WriteBigEndian(&built_packet.data()[kStatusCountOffset],
1441 42);
sprang49f9cdb2015-10-01 03:06:57 -07001442
danilchap1e714ae2016-09-05 09:57:22 -07001443 // Stress no transport feedback is expected.
1444 EXPECT_CALL(transport_feedback_observer_, OnTransportFeedback(_)).Times(0);
1445 // But remb should be processed and cause a callback
1446 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1447 InjectRtcpPacket(built_packet);
sprang49f9cdb2015-10-01 03:06:57 -07001448}
1449
danilchap1e714ae2016-09-05 09:57:22 -07001450TEST_F(RtcpReceiverTest, Nack) {
1451 const uint16_t kNackList1[] = {1, 2, 3, 5};
danilchap142f0192016-10-20 08:22:42 -07001452 const uint16_t kNackList23[] = {5, 7, 30, 40, 41, 58, 59, 61, 63};
1453 const size_t kNackListLength2 = 4;
1454 const size_t kNackListLength3 = arraysize(kNackList23) - kNackListLength2;
danilchap1e714ae2016-09-05 09:57:22 -07001455 std::set<uint16_t> nack_set;
1456 nack_set.insert(std::begin(kNackList1), std::end(kNackList1));
danilchap142f0192016-10-20 08:22:42 -07001457 nack_set.insert(std::begin(kNackList23), std::end(kNackList23));
danilchap1e714ae2016-09-05 09:57:22 -07001458
danilchap142f0192016-10-20 08:22:42 -07001459 rtcp::Nack nack1;
1460 nack1.SetSenderSsrc(kSenderSsrc);
1461 nack1.SetMediaSsrc(kReceiverMainSsrc);
1462 nack1.SetPacketIds(kNackList1, arraysize(kNackList1));
danilchap1e714ae2016-09-05 09:57:22 -07001463
1464 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList1)));
danilchap1e714ae2016-09-05 09:57:22 -07001465 EXPECT_CALL(packet_type_counter_observer_,
1466 RtcpPacketTypesCounterUpdated(
1467 kReceiverMainSsrc,
1468 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
danilchap142f0192016-10-20 08:22:42 -07001469 arraysize(kNackList1)),
1470 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1471 arraysize(kNackList1)))));
1472 InjectRtcpPacket(nack1);
1473
1474 rtcp::Nack nack2;
1475 nack2.SetSenderSsrc(kSenderSsrc);
1476 nack2.SetMediaSsrc(kReceiverMainSsrc);
1477 nack2.SetPacketIds(kNackList23, kNackListLength2);
1478
1479 rtcp::Nack nack3;
1480 nack3.SetSenderSsrc(kSenderSsrc);
1481 nack3.SetMediaSsrc(kReceiverMainSsrc);
1482 nack3.SetPacketIds(kNackList23 + kNackListLength2, kNackListLength3);
1483
1484 rtcp::CompoundPacket two_nacks;
1485 two_nacks.Append(&nack2);
1486 two_nacks.Append(&nack3);
1487
1488 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList23)));
1489 EXPECT_CALL(packet_type_counter_observer_,
1490 RtcpPacketTypesCounterUpdated(
1491 kReceiverMainSsrc,
1492 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
1493 arraysize(kNackList1) + arraysize(kNackList23)),
danilchap1e714ae2016-09-05 09:57:22 -07001494 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1495 nack_set.size()))));
danilchap142f0192016-10-20 08:22:42 -07001496 InjectRtcpPacket(two_nacks);
danilchap1e714ae2016-09-05 09:57:22 -07001497}
1498
1499TEST_F(RtcpReceiverTest, NackNotForUsIgnored) {
1500 const uint16_t kNackList1[] = {1, 2, 3, 5};
1501 const size_t kNackListLength1 = std::end(kNackList1) - std::begin(kNackList1);
1502
1503 rtcp::Nack nack;
danilchap822a16f2016-09-27 09:27:47 -07001504 nack.SetSenderSsrc(kSenderSsrc);
1505 nack.SetMediaSsrc(kNotToUsSsrc);
1506 nack.SetPacketIds(kNackList1, kNackListLength1);
danilchap1e714ae2016-09-05 09:57:22 -07001507
1508 EXPECT_CALL(packet_type_counter_observer_,
1509 RtcpPacketTypesCounterUpdated(
1510 _, Field(&RtcpPacketTypeCounter::nack_requests, 0)));
1511 InjectRtcpPacket(nack);
1512}
1513
1514TEST_F(RtcpReceiverTest, ForceSenderReport) {
1515 rtcp::RapidResyncRequest rr;
danilchap822a16f2016-09-27 09:27:47 -07001516 rr.SetSenderSsrc(kSenderSsrc);
1517 rr.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -07001518
1519 EXPECT_CALL(rtp_rtcp_impl_, OnRequestSendReport());
1520 InjectRtcpPacket(rr);
1521}
hta@webrtc.org47059b52012-05-02 07:46:22 +00001522
spranga790d832016-12-02 07:29:44 -08001523TEST_F(RtcpReceiverTest, ReceivesTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001524 VideoBitrateAllocation expected_allocation;
spranga790d832016-12-02 07:29:44 -08001525 expected_allocation.SetBitrate(0, 0, 10000);
1526 expected_allocation.SetBitrate(0, 1, 20000);
1527 expected_allocation.SetBitrate(1, 0, 40000);
1528 expected_allocation.SetBitrate(1, 1, 80000);
1529
1530 rtcp::TargetBitrate bitrate;
1531 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1532 bitrate.AddTargetBitrate(0, 1, expected_allocation.GetBitrate(0, 1) / 1000);
1533 bitrate.AddTargetBitrate(1, 0, expected_allocation.GetBitrate(1, 0) / 1000);
1534 bitrate.AddTargetBitrate(1, 1, expected_allocation.GetBitrate(1, 1) / 1000);
1535
1536 rtcp::ExtendedReports xr;
1537 xr.SetTargetBitrate(bitrate);
1538
sprangb32aaf92017-08-28 05:49:12 -07001539 // Wrong sender ssrc, target bitrate should be discarded.
1540 xr.SetSenderSsrc(kSenderSsrc + 1);
1541 EXPECT_CALL(bitrate_allocation_observer_,
1542 OnBitrateAllocationUpdated(expected_allocation))
1543 .Times(0);
1544 InjectRtcpPacket(xr);
1545
1546 // Set correct ssrc, callback should be called once.
1547 xr.SetSenderSsrc(kSenderSsrc);
spranga790d832016-12-02 07:29:44 -08001548 EXPECT_CALL(bitrate_allocation_observer_,
1549 OnBitrateAllocationUpdated(expected_allocation));
1550 InjectRtcpPacket(xr);
1551}
1552
sprang6d314c72016-12-06 06:08:53 -08001553TEST_F(RtcpReceiverTest, HandlesIncorrectTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001554 VideoBitrateAllocation expected_allocation;
sprang6d314c72016-12-06 06:08:53 -08001555 expected_allocation.SetBitrate(0, 0, 10000);
1556
1557 rtcp::TargetBitrate bitrate;
1558 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1559 bitrate.AddTargetBitrate(0, kMaxTemporalStreams, 20000);
1560 bitrate.AddTargetBitrate(kMaxSpatialLayers, 0, 40000);
1561
1562 rtcp::ExtendedReports xr;
1563 xr.SetTargetBitrate(bitrate);
sprangb32aaf92017-08-28 05:49:12 -07001564 xr.SetSenderSsrc(kSenderSsrc);
sprang6d314c72016-12-06 06:08:53 -08001565
1566 EXPECT_CALL(bitrate_allocation_observer_,
1567 OnBitrateAllocationUpdated(expected_allocation));
1568 InjectRtcpPacket(xr);
1569}
1570
hta@webrtc.org47059b52012-05-02 07:46:22 +00001571} // namespace webrtc