blob: 6fa2cdf9009bf6176c024d38ed06390722e8c895 [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 Bonadei4d683142019-07-12 08:36:29 +0000135 rtcp_receiver_(&system_clock_,
136 false,
137 &packet_type_counter_observer_,
138 &bandwidth_observer_,
139 &intra_frame_observer_,
140 &rtcp_loss_notification_observer_,
141 &transport_feedback_observer_,
142 &bitrate_allocation_observer_,
143 kRtcpIntervalMs,
144 &rtp_rtcp_impl_) {}
danilchap1e714ae2016-09-05 09:57:22 -0700145 void SetUp() {
Mirko Bonadei4d683142019-07-12 08:36:29 +0000146 std::set<uint32_t> ssrcs = {kReceiverMainSsrc, kReceiverExtraSsrc};
147 rtcp_receiver_.SetSsrcs(kReceiverMainSsrc, ssrcs);
148
danilchap1e714ae2016-09-05 09:57:22 -0700149 rtcp_receiver_.SetRemoteSSRC(kSenderSsrc);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000150 }
Erik Språng737336d2016-07-29 12:59:36 +0200151
danilchap1e714ae2016-09-05 09:57:22 -0700152 void InjectRtcpPacket(rtc::ArrayView<const uint8_t> raw) {
153 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
hta@webrtc.org47059b52012-05-02 07:46:22 +0000154 }
155
danilchap1e714ae2016-09-05 09:57:22 -0700156 void InjectRtcpPacket(const rtcp::RtcpPacket& packet) {
157 rtc::Buffer raw = packet.Build();
158 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
159 }
160
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000161 SimulatedClock system_clock_;
danilchap1e714ae2016-09-05 09:57:22 -0700162 // Callbacks to packet_type_counter_observer are frequent but most of the time
163 // are not interesting.
164 NiceMock<MockRtcpPacketTypeCounterObserver> packet_type_counter_observer_;
165 StrictMock<MockRtcpBandwidthObserver> bandwidth_observer_;
166 StrictMock<MockRtcpIntraFrameObserver> intra_frame_observer_;
Elad Alon0a8562e2019-04-09 11:55:13 +0200167 StrictMock<MockRtcpLossNotificationObserver> rtcp_loss_notification_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700168 StrictMock<MockTransportFeedbackObserver> transport_feedback_observer_;
spranga790d832016-12-02 07:29:44 -0800169 StrictMock<MockVideoBitrateAllocationObserver> bitrate_allocation_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700170 StrictMock<MockModuleRtpRtcp> rtp_rtcp_impl_;
hta@webrtc.org47059b52012-05-02 07:46:22 +0000171
danilchap1e714ae2016-09-05 09:57:22 -0700172 RTCPReceiver rtcp_receiver_;
173};
hta@webrtc.org47059b52012-05-02 07:46:22 +0000174
175TEST_F(RtcpReceiverTest, BrokenPacketIsIgnored) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000176 const uint8_t bad_packet[] = {0, 0, 0, 0};
danilchap1e714ae2016-09-05 09:57:22 -0700177 EXPECT_CALL(packet_type_counter_observer_,
178 RtcpPacketTypesCounterUpdated(_, _))
179 .Times(0);
180 InjectRtcpPacket(bad_packet);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000181}
182
danilchap50da1d32016-03-10 13:13:52 -0800183TEST_F(RtcpReceiverTest, InvalidFeedbackPacketIsIgnored) {
184 // Too short feedback packet.
danilchap1e714ae2016-09-05 09:57:22 -0700185 const uint8_t bad_packet[] = {0x81, rtcp::Rtpfb::kPacketType, 0, 0};
186
187 // TODO(danilchap): Add expectation RtcpPacketTypesCounterUpdated
188 // is not called once parser would be adjusted to avoid that callback on
189 // semi-valid packets.
190 InjectRtcpPacket(bad_packet);
danilchap50da1d32016-03-10 13:13:52 -0800191}
192
hta@webrtc.org47059b52012-05-02 07:46:22 +0000193TEST_F(RtcpReceiverTest, InjectSrPacket) {
danilchapa04d9c32017-07-25 04:03:39 -0700194 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
danilchap1e714ae2016-09-05 09:57:22 -0700195
196 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000197 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700198 sr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700199
200 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
201 EXPECT_CALL(bandwidth_observer_,
202 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
203 InjectRtcpPacket(sr);
204
danilchapa04d9c32017-07-25 04:03:39 -0700205 EXPECT_TRUE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
hta@webrtc.org47059b52012-05-02 07:46:22 +0000206}
207
danilchap1e714ae2016-09-05 09:57:22 -0700208TEST_F(RtcpReceiverTest, InjectSrPacketFromUnknownSender) {
209 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000210 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700211 sr.SetSenderSsrc(kUnknownSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700212
213 // The parser will handle report blocks in Sender Report from other than his
214 // expected peer.
215 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
216 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, now));
217 InjectRtcpPacket(sr);
218
219 // But will not flag that he's gotten sender information.
danilchapa04d9c32017-07-25 04:03:39 -0700220 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000221}
222
Danil Chapovalova094fd12016-02-22 18:59:36 +0100223TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesRTT) {
224 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100225 const int64_t kRttMs = r.Rand(1, 9 * 3600 * 1000);
226 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
227 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100228
Danil Chapovalova094fd12016-02-22 18:59:36 +0100229 int64_t rtt_ms = 0;
230 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700231 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100232
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200233 uint32_t sent_ntp =
234 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100235 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
236
237 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700238 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100239 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700240 block.SetMediaSsrc(kReceiverMainSsrc);
241 block.SetLastSr(sent_ntp);
242 block.SetDelayLastSr(kDelayNtp);
243 sr.AddReportBlock(block);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100244
danilchap1e714ae2016-09-05 09:57:22 -0700245 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
246 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
247 InjectRtcpPacket(sr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100248
249 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700250 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100251 EXPECT_NEAR(kRttMs, rtt_ms, 1);
252}
253
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100254TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesNegativeRTTAsOne) {
255 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100256 const int64_t kRttMs = r.Rand(-3600 * 1000, -1);
257 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
258 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
259
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100260 int64_t rtt_ms = 0;
261 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700262 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100263
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200264 uint32_t sent_ntp =
265 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100266 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
267
268 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700269 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100270 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700271 block.SetMediaSsrc(kReceiverMainSsrc);
272 block.SetLastSr(sent_ntp);
273 block.SetDelayLastSr(kDelayNtp);
274 sr.AddReportBlock(block);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100275
danilchap1e714ae2016-09-05 09:57:22 -0700276 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
277 EXPECT_CALL(bandwidth_observer_,
278 OnReceivedRtcpReceiverReport(SizeIs(1), _, _));
279 InjectRtcpPacket(sr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100280
281 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700282 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100283 EXPECT_EQ(1, rtt_ms);
284}
285
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100286TEST_F(
287 RtcpReceiverTest,
288 TwoReportBlocksWithLastOneWithoutLastSrCalculatesRttForBandwidthObserver) {
289 const int64_t kRttMs = 120;
290 const uint32_t kDelayNtp = 123000;
291 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
292
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200293 uint32_t sent_ntp =
294 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100295 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
296
297 rtcp::SenderReport sr;
298 sr.SetSenderSsrc(kSenderSsrc);
299 rtcp::ReportBlock block;
300 block.SetMediaSsrc(kReceiverMainSsrc);
301 block.SetLastSr(sent_ntp);
302 block.SetDelayLastSr(kDelayNtp);
303 sr.AddReportBlock(block);
304 block.SetMediaSsrc(kReceiverExtraSsrc);
305 block.SetLastSr(0);
306 sr.AddReportBlock(block);
307
308 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
309 EXPECT_CALL(bandwidth_observer_,
310 OnReceivedRtcpReceiverReport(SizeIs(2), kRttMs, _));
311 InjectRtcpPacket(sr);
312}
313
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000314TEST_F(RtcpReceiverTest, InjectRrPacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700315 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000316 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700317 rr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700318
319 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
320 EXPECT_CALL(bandwidth_observer_,
321 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
322 InjectRtcpPacket(rr);
323
danilchap1e714ae2016-09-05 09:57:22 -0700324 std::vector<RTCPReportBlock> report_blocks;
325 rtcp_receiver_.StatisticsReceived(&report_blocks);
326 EXPECT_TRUE(report_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000327}
328
329TEST_F(RtcpReceiverTest, InjectRrPacketWithReportBlockNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700330 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000331 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700332 rb.SetMediaSsrc(kNotToUsSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000333 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700334 rr.SetSenderSsrc(kSenderSsrc);
335 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000336
danilchap1e714ae2016-09-05 09:57:22 -0700337 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
338 EXPECT_CALL(bandwidth_observer_,
339 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
340 InjectRtcpPacket(rr);
341
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200342 EXPECT_EQ(0, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000343 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700344 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000345 EXPECT_TRUE(received_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000346}
347
348TEST_F(RtcpReceiverTest, InjectRrPacketWithOneReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700349 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000350
351 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700352 rb.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000353 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700354 rr.SetSenderSsrc(kSenderSsrc);
355 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000356
danilchap1e714ae2016-09-05 09:57:22 -0700357 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
358 EXPECT_CALL(bandwidth_observer_,
359 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
360 InjectRtcpPacket(rr);
361
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200362 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
363 std::vector<RTCPReportBlock> received_blocks;
364 rtcp_receiver_.StatisticsReceived(&received_blocks);
365 EXPECT_EQ(1u, received_blocks.size());
366}
367
368TEST_F(RtcpReceiverTest, InjectSrPacketWithOneReportBlock) {
369 int64_t now = system_clock_.TimeInMilliseconds();
370
371 rtcp::ReportBlock rb;
372 rb.SetMediaSsrc(kReceiverMainSsrc);
373 rtcp::SenderReport sr;
374 sr.SetSenderSsrc(kSenderSsrc);
375 sr.AddReportBlock(rb);
376
377 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
378 EXPECT_CALL(bandwidth_observer_,
379 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
380 InjectRtcpPacket(sr);
381
382 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000383 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700384 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000385 EXPECT_EQ(1u, received_blocks.size());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000386}
387
388TEST_F(RtcpReceiverTest, InjectRrPacketWithTwoReportBlocks) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000389 const uint16_t kSequenceNumbers[] = {10, 12423};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000390 const uint32_t kCumLost[] = {13, 555};
391 const uint8_t kFracLost[] = {20, 11};
danilchap1e714ae2016-09-05 09:57:22 -0700392 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000393
394 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700395 rb1.SetMediaSsrc(kReceiverMainSsrc);
396 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
397 rb1.SetFractionLost(10);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000398
399 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700400 rb2.SetMediaSsrc(kReceiverExtraSsrc);
401 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
402 rb2.SetFractionLost(0);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000403
404 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700405 rr1.SetSenderSsrc(kSenderSsrc);
406 rr1.AddReportBlock(rb1);
407 rr1.AddReportBlock(rb2);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000408
danilchap1e714ae2016-09-05 09:57:22 -0700409 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
410 EXPECT_CALL(bandwidth_observer_,
411 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
412 InjectRtcpPacket(rr1);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000413
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200414 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700415 std::vector<RTCPReportBlock> received_blocks;
416 rtcp_receiver_.StatisticsReceived(&received_blocks);
417 EXPECT_THAT(received_blocks,
srte3e69e5c2017-08-09 06:13:45 -0700418 UnorderedElementsAre(Field(&RTCPReportBlock::fraction_lost, 0),
419 Field(&RTCPReportBlock::fraction_lost, 10)));
danilchap1e714ae2016-09-05 09:57:22 -0700420
421 // Insert next receiver report with same ssrc but new values.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000422 rtcp::ReportBlock rb3;
danilchap822a16f2016-09-27 09:27:47 -0700423 rb3.SetMediaSsrc(kReceiverMainSsrc);
424 rb3.SetExtHighestSeqNum(kSequenceNumbers[0]);
425 rb3.SetFractionLost(kFracLost[0]);
426 rb3.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000427
428 rtcp::ReportBlock rb4;
danilchap822a16f2016-09-27 09:27:47 -0700429 rb4.SetMediaSsrc(kReceiverExtraSsrc);
430 rb4.SetExtHighestSeqNum(kSequenceNumbers[1]);
431 rb4.SetFractionLost(kFracLost[1]);
432 rb4.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000433
434 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700435 rr2.SetSenderSsrc(kSenderSsrc);
436 rr2.AddReportBlock(rb3);
437 rr2.AddReportBlock(rb4);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000438
danilchap1e714ae2016-09-05 09:57:22 -0700439 // Advance time to make 1st sent time and 2nd sent time different.
440 system_clock_.AdvanceTimeMilliseconds(500);
441 now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000442
danilchap1e714ae2016-09-05 09:57:22 -0700443 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
444 EXPECT_CALL(bandwidth_observer_,
445 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
446 InjectRtcpPacket(rr2);
447
448 received_blocks.clear();
449 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000450 EXPECT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700451 EXPECT_THAT(
452 received_blocks,
453 UnorderedElementsAre(
454 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
455 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
456 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
457 Field(&RTCPReportBlock::extended_highest_sequence_number,
458 kSequenceNumbers[0])),
459 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverExtraSsrc),
460 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
461 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
462 Field(&RTCPReportBlock::extended_highest_sequence_number,
463 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000464}
465
466TEST_F(RtcpReceiverTest, InjectRrPacketsFromTwoRemoteSsrcs) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000467 const uint32_t kSenderSsrc2 = 0x20304;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000468 const uint16_t kSequenceNumbers[] = {10, 12423};
Sebastian Jansson9701e0c2018-08-09 11:21:11 +0200469 const int32_t kCumLost[] = {13, 555};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000470 const uint8_t kFracLost[] = {20, 11};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000471
472 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700473 rb1.SetMediaSsrc(kReceiverMainSsrc);
474 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
475 rb1.SetFractionLost(kFracLost[0]);
476 rb1.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000477 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700478 rr1.SetSenderSsrc(kSenderSsrc);
479 rr1.AddReportBlock(rb1);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000480
danilchap1e714ae2016-09-05 09:57:22 -0700481 int64_t now = system_clock_.TimeInMilliseconds();
482
483 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
484 EXPECT_CALL(bandwidth_observer_,
485 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
486 InjectRtcpPacket(rr1);
487
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200488 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000489
490 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700491 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000492 EXPECT_EQ(1u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700493 EXPECT_EQ(kSenderSsrc, received_blocks[0].sender_ssrc);
494 EXPECT_EQ(kReceiverMainSsrc, received_blocks[0].source_ssrc);
495 EXPECT_EQ(kFracLost[0], received_blocks[0].fraction_lost);
496 EXPECT_EQ(kCumLost[0], received_blocks[0].packets_lost);
497 EXPECT_EQ(kSequenceNumbers[0],
498 received_blocks[0].extended_highest_sequence_number);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000499
500 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700501 rb2.SetMediaSsrc(kReceiverMainSsrc);
502 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
503 rb2.SetFractionLost(kFracLost[1]);
504 rb2.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000505 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700506 rr2.SetSenderSsrc(kSenderSsrc2);
507 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -0700508
509 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
510 EXPECT_CALL(bandwidth_observer_,
511 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
512 InjectRtcpPacket(rr2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000513
514 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700515 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000516 ASSERT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700517 EXPECT_THAT(
518 received_blocks,
519 UnorderedElementsAre(
520 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
521 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc),
522 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
523 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
524 Field(&RTCPReportBlock::extended_highest_sequence_number,
525 kSequenceNumbers[0])),
526 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
527 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc2),
528 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
529 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
530 Field(&RTCPReportBlock::extended_highest_sequence_number,
531 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000532}
533
534TEST_F(RtcpReceiverTest, GetRtt) {
danilchap28b03eb2016-10-05 06:59:44 -0700535 const uint32_t kSentCompactNtp = 0x1234;
536 const uint32_t kDelayCompactNtp = 0x222;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000537 // No report block received.
Erik Språng6b8d3552015-09-24 15:06:57 +0200538 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700539 -1, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000540
541 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700542 rb.SetMediaSsrc(kReceiverMainSsrc);
danilchap28b03eb2016-10-05 06:59:44 -0700543 rb.SetLastSr(kSentCompactNtp);
544 rb.SetDelayLastSr(kDelayCompactNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700545
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000546 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700547 rr.SetSenderSsrc(kSenderSsrc);
548 rr.AddReportBlock(rb);
danilchap1e714ae2016-09-05 09:57:22 -0700549 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000550
danilchap1e714ae2016-09-05 09:57:22 -0700551 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
552 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
553 InjectRtcpPacket(rr);
554
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200555 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700556 EXPECT_EQ(
557 0, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000558}
559
danilchap1e714ae2016-09-05 09:57:22 -0700560// Ij packets are ignored.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000561TEST_F(RtcpReceiverTest, InjectIjWithNoItem) {
danilchapf8506cb2015-11-13 07:33:20 -0800562 rtcp::ExtendedJitterReport ij;
danilchap1e714ae2016-09-05 09:57:22 -0700563 InjectRtcpPacket(ij);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000564}
565
danilchap1e714ae2016-09-05 09:57:22 -0700566// App packets are ignored.
567TEST_F(RtcpReceiverTest, InjectApp) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000568 rtcp::App app;
danilchap822a16f2016-09-27 09:27:47 -0700569 app.SetSubType(30);
570 app.SetName(0x17a177e);
danilchap1e714ae2016-09-05 09:57:22 -0700571 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
danilchap822a16f2016-09-27 09:27:47 -0700572 app.SetData(kData, sizeof(kData));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000573
danilchap1e714ae2016-09-05 09:57:22 -0700574 InjectRtcpPacket(app);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000575}
576
577TEST_F(RtcpReceiverTest, InjectSdesWithOneChunk) {
danilchap1e714ae2016-09-05 09:57:22 -0700578 const char kCname[] = "alice@host";
579 MockRtcpCallbackImpl callback;
580 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000581 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700582 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000583
danilchap1e714ae2016-09-05 09:57:22 -0700584 EXPECT_CALL(callback, CNameChanged(StrEq(kCname), kSenderSsrc));
585 InjectRtcpPacket(sdes);
586
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000587 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700588 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
589 EXPECT_EQ(0, strncmp(cName, kCname, RTCP_CNAME_SIZE));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000590}
591
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000592TEST_F(RtcpReceiverTest, InjectByePacket_RemovesCname) {
danilchap1e714ae2016-09-05 09:57:22 -0700593 const char kCname[] = "alice@host";
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000594 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700595 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000596
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));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000601
602 // Verify that BYE removes the CNAME.
603 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700604 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700605
606 InjectRtcpPacket(bye);
607
608 EXPECT_EQ(-1, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000609}
610
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000611TEST_F(RtcpReceiverTest, InjectByePacket_RemovesReportBlocks) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000612 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700613 rb1.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000614 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700615 rb2.SetMediaSsrc(kReceiverExtraSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000616 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700617 rr.SetSenderSsrc(kSenderSsrc);
618 rr.AddReportBlock(rb1);
619 rr.AddReportBlock(rb2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000620
danilchap1e714ae2016-09-05 09:57:22 -0700621 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
622 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
623 InjectRtcpPacket(rr);
624
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000625 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700626 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000627 EXPECT_EQ(2u, received_blocks.size());
628
629 // Verify that BYE removes the report blocks.
630 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700631 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700632
633 InjectRtcpPacket(bye);
634
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000635 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700636 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000637 EXPECT_TRUE(received_blocks.empty());
638
danilchap1e714ae2016-09-05 09:57:22 -0700639 // Inject packet again.
640 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
641 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
642 InjectRtcpPacket(rr);
643
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000644 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700645 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000646 EXPECT_EQ(2u, received_blocks.size());
647}
648
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200649TEST_F(RtcpReceiverTest, InjectByePacketRemovesReferenceTimeInfo) {
650 rtcp::ExtendedReports xr;
651 xr.SetSenderSsrc(kSenderSsrc);
652 rtcp::Rrtr rrtr;
653 rrtr.SetNtp(NtpTime(0x10203, 0x40506));
654 xr.SetRrtr(rrtr);
655 InjectRtcpPacket(xr);
656
657 rtcp::Bye bye;
658 bye.SetSenderSsrc(kSenderSsrc);
659 InjectRtcpPacket(bye);
660
661 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
662}
663
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000664TEST_F(RtcpReceiverTest, InjectPliPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000665 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700666 pli.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700667
668 EXPECT_CALL(
669 packet_type_counter_observer_,
670 RtcpPacketTypesCounterUpdated(
671 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 1)));
672 EXPECT_CALL(intra_frame_observer_,
673 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
674 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000675}
676
677TEST_F(RtcpReceiverTest, PliPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000678 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700679 pli.SetMediaSsrc(kNotToUsSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700680
681 EXPECT_CALL(
682 packet_type_counter_observer_,
683 RtcpPacketTypesCounterUpdated(
684 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 0)));
685 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
686 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000687}
688
689TEST_F(RtcpReceiverTest, InjectFirPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000690 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700691 fir.AddRequestTo(kReceiverMainSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700692
693 EXPECT_CALL(
694 packet_type_counter_observer_,
695 RtcpPacketTypesCounterUpdated(
696 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::fir_packets, 1)));
697 EXPECT_CALL(intra_frame_observer_,
698 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
699 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000700}
701
702TEST_F(RtcpReceiverTest, FirPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000703 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700704 fir.AddRequestTo(kNotToUsSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700705
706 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
707 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000708}
709
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100710TEST_F(RtcpReceiverTest, ExtendedReportsPacketWithZeroReportBlocksIgnored) {
711 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700712 xr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700713
714 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000715}
716
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100717TEST_F(RtcpReceiverTest, InjectExtendedReportsReceiverReferenceTimePacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700718 const NtpTime kNtp(0x10203, 0x40506);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000719 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700720 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100721 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700722 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700723 xr.SetRrtr(rrtr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000724
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200725 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
726 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
727 EXPECT_THAT(last_xr_rtis, IsEmpty());
danilchap1e714ae2016-09-05 09:57:22 -0700728
729 InjectRtcpPacket(xr);
730
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200731 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
732 ASSERT_THAT(last_xr_rtis, SizeIs(1));
733 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
734 EXPECT_EQ(CompactNtp(kNtp), last_xr_rtis[0].last_rr);
735 EXPECT_EQ(0U, last_xr_rtis[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000736}
737
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100738TEST_F(RtcpReceiverTest, ExtendedReportsDlrrPacketNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700739 // Allow calculate rtt using dlrr/rrtr, simulating media receiver side.
740 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000741
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100742 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700743 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700744 xr.AddDlrrItem(ReceiveTimeInfo(kNotToUsSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700745
746 InjectRtcpPacket(xr);
747
748 int64_t rtt_ms = 0;
749 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000750}
751
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100752TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithSubBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700753 const uint32_t kLastRR = 0x12345;
754 const uint32_t kDelay = 0x23456;
755 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
756 int64_t rtt_ms = 0;
757 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000758
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100759 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700760 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700761 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
danilchap1e714ae2016-09-05 09:57:22 -0700762
763 InjectRtcpPacket(xr);
764
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200765 uint32_t compact_ntp_now =
766 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700767 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
768 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
769 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000770}
771
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100772TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithMultipleSubBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700773 const uint32_t kLastRR = 0x12345;
774 const uint32_t kDelay = 0x56789;
775 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000776
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100777 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700778 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700779 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
780 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 1, 0x12345, 0x67890));
781 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 2, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700782
783 InjectRtcpPacket(xr);
784
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200785 uint32_t compact_ntp_now =
786 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700787 int64_t rtt_ms = 0;
788 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
789 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
790 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000791}
792
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100793TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithMultipleReportBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700794 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000795
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000796 rtcp::Rrtr rrtr;
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100797 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700798 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700799 xr.SetRrtr(rrtr);
800 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700801
802 InjectRtcpPacket(xr);
803
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200804 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
805 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
806 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700807 int64_t rtt_ms = 0;
808 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000809}
810
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100811TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithUnknownReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700812 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000813
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000814 rtcp::Rrtr rrtr;
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100815 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700816 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700817 xr.SetRrtr(rrtr);
818 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700819
danilchap69e59e62016-02-17 03:11:42 -0800820 rtc::Buffer packet = xr.Build();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000821 // Modify the DLRR block to have an unsupported block type, from 5 to 6.
danilchap1e714ae2016-09-05 09:57:22 -0700822 ASSERT_EQ(5, packet.data()[20]);
823 packet.data()[20] = 6;
824 InjectRtcpPacket(packet);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000825
danilchap1e714ae2016-09-05 09:57:22 -0700826 // Validate Rrtr was received and processed.
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200827 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
828 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
829 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700830 // Validate Dlrr report wasn't processed.
831 int64_t rtt_ms = 0;
832 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000833}
834
danilchap1e714ae2016-09-05 09:57:22 -0700835TEST_F(RtcpReceiverTest, TestExtendedReportsRrRttInitiallyFalse) {
836 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
837
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000838 int64_t rtt_ms;
danilchap1e714ae2016-09-05 09:57:22 -0700839 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000840}
841
danilchap1e714ae2016-09-05 09:57:22 -0700842TEST_F(RtcpReceiverTest, RttCalculatedAfterExtendedReportsDlrr) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100843 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100844 const int64_t kRttMs = rand.Rand(1, 9 * 3600 * 1000);
845 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
846 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700847 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200848 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalova094fd12016-02-22 18:59:36 +0100849 uint32_t sent_ntp = CompactNtp(now);
850 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
851
Danil Chapovalova094fd12016-02-22 18:59:36 +0100852 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700853 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700854 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700855
856 InjectRtcpPacket(xr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100857
858 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700859 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100860 EXPECT_NEAR(kRttMs, rtt_ms, 1);
861}
862
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100863TEST_F(RtcpReceiverTest, XrDlrrCalculatesNegativeRttAsOne) {
864 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100865 const int64_t kRttMs = rand.Rand(-3600 * 1000, -1);
866 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
867 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200868 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100869 uint32_t sent_ntp = CompactNtp(now);
870 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
danilchap1e714ae2016-09-05 09:57:22 -0700871 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100872
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100873 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700874 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700875 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700876
877 InjectRtcpPacket(xr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100878
879 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700880 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100881 EXPECT_EQ(1, rtt_ms);
882}
883
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200884TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfoInitiallyEmpty) {
885 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000886}
887
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200888TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfo) {
Danil Chapovalovfc47ed62015-12-07 14:46:35 +0100889 const NtpTime kNtp(0x10203, 0x40506);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100890 const uint32_t kNtpMid = CompactNtp(kNtp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000891
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000892 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700893 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100894 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700895 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700896 xr.SetRrtr(rrtr);
danilchap1e714ae2016-09-05 09:57:22 -0700897
898 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000899
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000900 system_clock_.AdvanceTimeMilliseconds(1000);
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200901
902 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
903 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
904 ASSERT_THAT(last_xr_rtis, SizeIs(1));
905 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
906 EXPECT_EQ(kNtpMid, last_xr_rtis[0].last_rr);
907 EXPECT_EQ(65536U, last_xr_rtis[0].delay_since_last_rr);
908}
909
910TEST_F(RtcpReceiverTest,
911 ReceivedRrtrFromSameSsrcUpdatesReceivedReferenceTimeInfo) {
912 const NtpTime kNtp1(0x10203, 0x40506);
913 const NtpTime kNtp2(0x11223, 0x44556);
914 const int64_t kDelayMs = 2000;
915
916 rtcp::ExtendedReports xr;
917 xr.SetSenderSsrc(kSenderSsrc);
918 rtcp::Rrtr rrtr1;
919 rrtr1.SetNtp(kNtp1);
920 xr.SetRrtr(rrtr1);
921 InjectRtcpPacket(xr);
922 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
923 rtcp::Rrtr rrtr2;
924 rrtr2.SetNtp(kNtp2);
925 xr.SetRrtr(rrtr2);
926 InjectRtcpPacket(xr);
927 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
928
929 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
930 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
931 ASSERT_THAT(last_xr_rtis, SizeIs(1));
932 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
933 EXPECT_EQ(CompactNtp(kNtp2), last_xr_rtis[0].last_rr);
934 EXPECT_EQ(kDelayMs * 65536 / 1000, last_xr_rtis[0].delay_since_last_rr);
935}
936
937TEST_F(RtcpReceiverTest, StoresLastReceivedRrtrPerSsrc) {
938 const size_t kNumBufferedReports = 1;
939 const size_t kNumReports =
940 rtcp::ExtendedReports::kMaxNumberOfDlrrItems + kNumBufferedReports;
941 for (size_t i = 0; i < kNumReports; ++i) {
942 rtcp::ExtendedReports xr;
943 xr.SetSenderSsrc(i * 100);
944 rtcp::Rrtr rrtr;
945 rrtr.SetNtp(NtpTime(i * 200, i * 300));
946 xr.SetRrtr(rrtr);
947 InjectRtcpPacket(xr);
948 system_clock_.AdvanceTimeMilliseconds(1000);
949 }
950
951 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
952 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
953 ASSERT_THAT(last_xr_rtis,
954 SizeIs(rtcp::ExtendedReports::kMaxNumberOfDlrrItems));
955 for (size_t i = 0; i < rtcp::ExtendedReports::kMaxNumberOfDlrrItems; ++i) {
956 EXPECT_EQ(i * 100, last_xr_rtis[i].ssrc);
957 EXPECT_EQ(CompactNtp(NtpTime(i * 200, i * 300)), last_xr_rtis[i].last_rr);
958 EXPECT_EQ(65536U * (kNumReports - i), last_xr_rtis[i].delay_since_last_rr);
959 }
960
961 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
962 ASSERT_THAT(last_xr_rtis, SizeIs(kNumBufferedReports));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000963}
964
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000965TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000966 const uint16_t kSequenceNumber = 1234;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000967 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000968
969 // No RR received, shouldn't trigger a timeout.
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800970 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
971 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000972
973 // Add a RR and advance the clock just enough to not trigger a timeout.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000974 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700975 rb1.SetMediaSsrc(kReceiverMainSsrc);
976 rb1.SetExtHighestSeqNum(kSequenceNumber);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000977 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700978 rr1.SetSenderSsrc(kSenderSsrc);
979 rr1.AddReportBlock(rb1);
danilchap1e714ae2016-09-05 09:57:22 -0700980
981 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
982 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
983 InjectRtcpPacket(rr1);
984
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000985 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs - 1);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800986 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
987 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000988
989 // Add a RR with the same extended max as the previous RR to trigger a
990 // sequence number timeout, but not a RR timeout.
danilchap1e714ae2016-09-05 09:57:22 -0700991 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
992 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
993 InjectRtcpPacket(rr1);
994
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000995 system_clock_.AdvanceTimeMilliseconds(2);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800996 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
997 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000998
999 // Advance clock enough to trigger an RR timeout too.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001000 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001001 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001002
1003 // We should only get one timeout even though we still haven't received a new
1004 // RR.
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001005 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1006 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001007
1008 // Add a new RR with increase sequence number to reset timers.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001009 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001010 rb2.SetMediaSsrc(kReceiverMainSsrc);
1011 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001012 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001013 rr2.SetSenderSsrc(kSenderSsrc);
1014 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001015
1016 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1017 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1018 InjectRtcpPacket(rr2);
1019
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001020 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1021 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001022
1023 // Verify we can get a timeout again once we've received new RR.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001024 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -07001025 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1026 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1027 InjectRtcpPacket(rr2);
1028
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001029 system_clock_.AdvanceTimeMilliseconds(kRtcpIntervalMs + 1);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001030 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1031 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
danilchap1e714ae2016-09-05 09:57:22 -07001032
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001033 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001034 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001035}
1036
hta@webrtc.org47059b52012-05-02 07:46:22 +00001037TEST_F(RtcpReceiverTest, TmmbrReceivedWithNoIncomingPacket) {
danilchap1e714ae2016-09-05 09:57:22 -07001038 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001039}
1040
1041TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) {
danilchap1e714ae2016-09-05 09:57:22 -07001042 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001043 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001044 tmmbr.SetSenderSsrc(kSenderSsrc);
1045 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001046 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001047 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001048 rtcp::CompoundPacket compound;
1049 compound.Append(&sr);
1050 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001051
danilchap1e714ae2016-09-05 09:57:22 -07001052 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1053 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(SizeIs(1)));
1054 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1055 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1056 InjectRtcpPacket(compound);
1057
1058 std::vector<rtcp::TmmbItem> tmmbr_received = rtcp_receiver_.TmmbrReceived();
1059 ASSERT_EQ(1u, tmmbr_received.size());
1060 EXPECT_EQ(kBitrateBps, tmmbr_received[0].bitrate_bps());
1061 EXPECT_EQ(kSenderSsrc, tmmbr_received[0].ssrc());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001062}
1063
1064TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -07001065 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001066 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001067 tmmbr.SetSenderSsrc(kSenderSsrc);
1068 tmmbr.AddTmmbr(rtcp::TmmbItem(kNotToUsSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001069
1070 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001071 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001072 rtcp::CompoundPacket compound;
1073 compound.Append(&sr);
1074 compound.Append(&tmmbr);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001075
danilchap1e714ae2016-09-05 09:57:22 -07001076 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1077 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1078 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1079 InjectRtcpPacket(compound);
1080
1081 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001082}
1083
1084TEST_F(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001085 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001086 tmmbr.SetSenderSsrc(kSenderSsrc);
1087 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 0, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001088 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001089 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001090 rtcp::CompoundPacket compound;
1091 compound.Append(&sr);
1092 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001093
danilchap1e714ae2016-09-05 09:57:22 -07001094 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1095 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1096 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1097 InjectRtcpPacket(compound);
1098
1099 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001100}
1101
hta@webrtc.org404843e2012-05-02 09:56:45 +00001102TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001103 // Inject 3 packets "from" kSenderSsrc, kSenderSsrc+1, kSenderSsrc+2.
hta@webrtc.org404843e2012-05-02 09:56:45 +00001104 // The times of arrival are starttime + 0, starttime + 5 and starttime + 10.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001105 for (uint32_t ssrc = kSenderSsrc; ssrc < kSenderSsrc + 3; ++ssrc) {
1106 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001107 tmmbr.SetSenderSsrc(ssrc);
1108 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 30000, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001109 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001110 sr.SetSenderSsrc(ssrc);
danilchap7a4116a2016-03-14 08:19:28 -07001111 rtcp::CompoundPacket compound;
1112 compound.Append(&sr);
1113 compound.Append(&tmmbr);
danilchap1e714ae2016-09-05 09:57:22 -07001114
1115 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1116 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(_));
1117 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1118 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_));
1119 InjectRtcpPacket(compound);
1120
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001121 // 5 seconds between each packet.
1122 system_clock_.AdvanceTimeMilliseconds(5000);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001123 }
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001124 // It is now starttime + 15.
danilchap1e714ae2016-09-05 09:57:22 -07001125 std::vector<rtcp::TmmbItem> candidate_set = rtcp_receiver_.TmmbrReceived();
1126 ASSERT_EQ(3u, candidate_set.size());
1127 EXPECT_EQ(30000U, candidate_set[0].bitrate_bps());
1128
hta@webrtc.org404843e2012-05-02 09:56:45 +00001129 // We expect the timeout to be 25 seconds. Advance the clock by 12
1130 // seconds, timing out the first packet.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001131 system_clock_.AdvanceTimeMilliseconds(12000);
danilchap1e714ae2016-09-05 09:57:22 -07001132 candidate_set = rtcp_receiver_.TmmbrReceived();
1133 ASSERT_EQ(2u, candidate_set.size());
danilchap287e5482016-08-16 15:15:39 -07001134 EXPECT_EQ(kSenderSsrc + 1, candidate_set[0].ssrc());
hta@webrtc.org404843e2012-05-02 09:56:45 +00001135}
1136
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001137TEST_F(RtcpReceiverTest, Callbacks) {
danilchap1e714ae2016-09-05 09:57:22 -07001138 MockRtcpCallbackImpl callback;
1139 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001140
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001141 const uint8_t kFractionLoss = 3;
1142 const uint32_t kCumulativeLoss = 7;
1143 const uint32_t kJitter = 9;
1144 const uint16_t kSequenceNumber = 1234;
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001145
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001146 // First packet, all numbers should just propagate.
1147 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -07001148 rb1.SetMediaSsrc(kReceiverMainSsrc);
1149 rb1.SetExtHighestSeqNum(kSequenceNumber);
1150 rb1.SetFractionLost(kFractionLoss);
1151 rb1.SetCumulativeLost(kCumulativeLoss);
1152 rb1.SetJitter(kJitter);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001153
1154 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -07001155 rr1.SetSenderSsrc(kSenderSsrc);
1156 rr1.AddReportBlock(rb1);
srte186d9c32017-08-04 05:03:53 -07001157 EXPECT_CALL(callback,
1158 StatisticsUpdated(
1159 AllOf(Field(&RtcpStatistics::fraction_lost, kFractionLoss),
1160 Field(&RtcpStatistics::packets_lost, kCumulativeLoss),
1161 Field(&RtcpStatistics::extended_highest_sequence_number,
1162 kSequenceNumber),
1163 Field(&RtcpStatistics::jitter, kJitter)),
1164 kReceiverMainSsrc));
danilchap1e714ae2016-09-05 09:57:22 -07001165 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1166 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1167 InjectRtcpPacket(rr1);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001168
danilchap1e714ae2016-09-05 09:57:22 -07001169 rtcp_receiver_.RegisterRtcpStatisticsCallback(nullptr);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001170
danilchap1e714ae2016-09-05 09:57:22 -07001171 // Add arbitrary numbers, callback should not be called.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001172 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001173 rb2.SetMediaSsrc(kReceiverMainSsrc);
1174 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
1175 rb2.SetFractionLost(42);
1176 rb2.SetCumulativeLost(137);
1177 rb2.SetJitter(4711);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001178
1179 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001180 rr2.SetSenderSsrc(kSenderSsrc);
1181 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001182
1183 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1184 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1185 EXPECT_CALL(callback, StatisticsUpdated(_, _)).Times(0);
1186 InjectRtcpPacket(rr2);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001187}
hta@webrtc.org404843e2012-05-02 09:56:45 +00001188
Henrik Boströmf2047872019-05-16 13:32:20 +02001189TEST_F(RtcpReceiverTest,
1190 VerifyBlockAndTimestampObtainedFromReportBlockDataObserver) {
1191 MockReportBlockDataObserverImpl observer;
1192 rtcp_receiver_.SetReportBlockDataObserver(&observer);
1193
1194 const uint8_t kFractionLoss = 3;
1195 const uint32_t kCumulativeLoss = 7;
1196 const uint32_t kJitter = 9;
1197 const uint16_t kSequenceNumber = 1234;
1198 const int64_t kUtcNowUs = 42;
1199
1200 // The "report_block_timestamp_utc_us" is obtained from the global UTC clock
1201 // (not the simulcated |system_clock_|) and requires a scoped fake clock.
1202 rtc::ScopedFakeClock fake_clock;
1203 fake_clock.SetTime(Timestamp::us(kUtcNowUs));
1204
1205 rtcp::ReportBlock rtcp_block;
1206 rtcp_block.SetMediaSsrc(kReceiverMainSsrc);
1207 rtcp_block.SetExtHighestSeqNum(kSequenceNumber);
1208 rtcp_block.SetFractionLost(kFractionLoss);
1209 rtcp_block.SetCumulativeLost(kCumulativeLoss);
1210 rtcp_block.SetJitter(kJitter);
1211
1212 rtcp::ReceiverReport rtcp_report;
1213 rtcp_report.SetSenderSsrc(kSenderSsrc);
1214 rtcp_report.AddReportBlock(rtcp_block);
1215 EXPECT_CALL(observer, OnReportBlockDataUpdated)
1216 .WillOnce([&](ReportBlockData report_block_data) {
1217 const auto& report_block = report_block_data.report_block();
1218 EXPECT_EQ(rtcp_block.source_ssrc(), report_block.source_ssrc);
1219 EXPECT_EQ(kSenderSsrc, report_block.sender_ssrc);
1220 EXPECT_EQ(rtcp_block.fraction_lost(), report_block.fraction_lost);
1221 EXPECT_EQ(rtcp_block.cumulative_lost_signed(),
1222 report_block.packets_lost);
1223 EXPECT_EQ(rtcp_block.extended_high_seq_num(),
1224 report_block.extended_highest_sequence_number);
1225 EXPECT_EQ(rtcp_block.jitter(), report_block.jitter);
1226 EXPECT_EQ(kUtcNowUs, report_block_data.report_block_timestamp_utc_us());
1227 // No RTT is calculated in this test.
1228 EXPECT_EQ(0u, report_block_data.num_rtts());
1229 });
1230 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1231 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1232 InjectRtcpPacket(rtcp_report);
1233}
1234
1235TEST_F(RtcpReceiverTest, VerifyRttObtainedFromReportBlockDataObserver) {
1236 MockReportBlockDataObserverImpl observer;
1237 rtcp_receiver_.SetReportBlockDataObserver(&observer);
1238
1239 const int64_t kRttMs = 120;
1240 const uint32_t kDelayNtp = 123000;
1241 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
1242
1243 uint32_t sent_ntp =
1244 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
1245 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
1246
1247 rtcp::SenderReport sr;
1248 sr.SetSenderSsrc(kSenderSsrc);
1249 rtcp::ReportBlock block;
1250 block.SetMediaSsrc(kReceiverMainSsrc);
1251 block.SetLastSr(sent_ntp);
1252 block.SetDelayLastSr(kDelayNtp);
1253 sr.AddReportBlock(block);
1254 block.SetMediaSsrc(kReceiverExtraSsrc);
1255 block.SetLastSr(0);
1256 sr.AddReportBlock(block);
1257
1258 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1259 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1260 InSequence sequence;
1261 EXPECT_CALL(observer, OnReportBlockDataUpdated)
1262 .WillOnce([&](ReportBlockData report_block_data) {
1263 EXPECT_EQ(kReceiverMainSsrc,
1264 report_block_data.report_block().source_ssrc);
1265 EXPECT_EQ(1u, report_block_data.num_rtts());
1266 EXPECT_EQ(kRttMs, report_block_data.min_rtt_ms());
1267 EXPECT_EQ(kRttMs, report_block_data.max_rtt_ms());
1268 EXPECT_EQ(kRttMs, report_block_data.sum_rtt_ms());
1269 EXPECT_EQ(kRttMs, report_block_data.last_rtt_ms());
1270 });
1271 EXPECT_CALL(observer, OnReportBlockDataUpdated)
1272 .WillOnce([](ReportBlockData report_block_data) {
1273 EXPECT_EQ(kReceiverExtraSsrc,
1274 report_block_data.report_block().source_ssrc);
1275 EXPECT_EQ(0u, report_block_data.num_rtts());
1276 });
1277 InjectRtcpPacket(sr);
1278}
1279
1280TEST_F(RtcpReceiverTest, GetReportBlockDataAfterOneReportBlock) {
1281 const uint16_t kSequenceNumber = 1234;
1282
1283 rtcp::ReportBlock rtcp_block;
1284 rtcp_block.SetMediaSsrc(kReceiverMainSsrc);
1285 rtcp_block.SetExtHighestSeqNum(kSequenceNumber);
1286
1287 rtcp::ReceiverReport rtcp_report;
1288 rtcp_report.SetSenderSsrc(kSenderSsrc);
1289 rtcp_report.AddReportBlock(rtcp_block);
1290 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1291 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1292 InjectRtcpPacket(rtcp_report);
1293
1294 auto report_block_datas = rtcp_receiver_.GetLatestReportBlockData();
1295 ASSERT_THAT(report_block_datas, SizeIs(1));
1296 EXPECT_EQ(kReceiverMainSsrc,
1297 report_block_datas[0].report_block().source_ssrc);
1298 EXPECT_EQ(
1299 kSequenceNumber,
1300 report_block_datas[0].report_block().extended_highest_sequence_number);
1301}
1302
1303TEST_F(RtcpReceiverTest, GetReportBlockDataAfterTwoReportBlocksOfSameSsrc) {
1304 const uint16_t kSequenceNumber1 = 1234;
1305 const uint16_t kSequenceNumber2 = 1235;
1306
1307 rtcp::ReportBlock rtcp_block1;
1308 rtcp_block1.SetMediaSsrc(kReceiverMainSsrc);
1309 rtcp_block1.SetExtHighestSeqNum(kSequenceNumber1);
1310
1311 rtcp::ReceiverReport rtcp_report1;
1312 rtcp_report1.SetSenderSsrc(kSenderSsrc);
1313 rtcp_report1.AddReportBlock(rtcp_block1);
1314 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1315 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1316 InjectRtcpPacket(rtcp_report1);
1317
1318 // Inject a report block with an increased the sequence number for the same
1319 // source SSRC.
1320 rtcp::ReportBlock rtcp_block2;
1321 rtcp_block2.SetMediaSsrc(kReceiverMainSsrc);
1322 rtcp_block2.SetExtHighestSeqNum(kSequenceNumber2);
1323
1324 rtcp::ReceiverReport rtcp_report2;
1325 rtcp_report2.SetSenderSsrc(kSenderSsrc);
1326 rtcp_report2.AddReportBlock(rtcp_block2);
1327 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1328 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1329 InjectRtcpPacket(rtcp_report2);
1330
1331 // Only the latest block should be returned.
1332 auto report_block_datas = rtcp_receiver_.GetLatestReportBlockData();
1333 ASSERT_THAT(report_block_datas, SizeIs(1));
1334 EXPECT_EQ(kReceiverMainSsrc,
1335 report_block_datas[0].report_block().source_ssrc);
1336 EXPECT_EQ(
1337 kSequenceNumber2,
1338 report_block_datas[0].report_block().extended_highest_sequence_number);
1339}
1340
1341TEST_F(RtcpReceiverTest,
1342 GetReportBlockDataAfterTwoReportBlocksOfDifferentSsrcs) {
1343 const uint16_t kSequenceNumber1 = 1234;
1344 const uint16_t kSequenceNumber2 = 42;
1345
1346 rtcp::ReportBlock rtcp_block1;
1347 rtcp_block1.SetMediaSsrc(kReceiverMainSsrc);
1348 rtcp_block1.SetExtHighestSeqNum(kSequenceNumber1);
1349
1350 rtcp::ReceiverReport rtcp_report1;
1351 rtcp_report1.SetSenderSsrc(kSenderSsrc);
1352 rtcp_report1.AddReportBlock(rtcp_block1);
1353 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1354 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1355 InjectRtcpPacket(rtcp_report1);
1356
1357 // Inject a report block for a different source SSRC.
1358 rtcp::ReportBlock rtcp_block2;
1359 rtcp_block2.SetMediaSsrc(kReceiverExtraSsrc);
1360 rtcp_block2.SetExtHighestSeqNum(kSequenceNumber2);
1361
1362 rtcp::ReceiverReport rtcp_report2;
1363 rtcp_report2.SetSenderSsrc(kSenderSsrc);
1364 rtcp_report2.AddReportBlock(rtcp_block2);
1365 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1366 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1367 InjectRtcpPacket(rtcp_report2);
1368
1369 // Both report blocks should be returned.
1370 auto report_block_datas = rtcp_receiver_.GetLatestReportBlockData();
1371 ASSERT_THAT(report_block_datas, SizeIs(2));
1372 EXPECT_EQ(kReceiverMainSsrc,
1373 report_block_datas[0].report_block().source_ssrc);
1374 EXPECT_EQ(
1375 kSequenceNumber1,
1376 report_block_datas[0].report_block().extended_highest_sequence_number);
1377 EXPECT_EQ(kReceiverExtraSsrc,
1378 report_block_datas[1].report_block().source_ssrc);
1379 EXPECT_EQ(
1380 kSequenceNumber2,
1381 report_block_datas[1].report_block().extended_highest_sequence_number);
1382}
1383
sprang49f9cdb2015-10-01 03:06:57 -07001384TEST_F(RtcpReceiverTest, ReceivesTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001385 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001386 packet.SetMediaSsrc(kReceiverMainSsrc);
1387 packet.SetSenderSsrc(kSenderSsrc);
1388 packet.SetBase(1, 1000);
1389 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001390
danilchap1e714ae2016-09-05 09:57:22 -07001391 EXPECT_CALL(
1392 transport_feedback_observer_,
1393 OnTransportFeedback(AllOf(
1394 Property(&rtcp::TransportFeedback::media_ssrc, kReceiverMainSsrc),
1395 Property(&rtcp::TransportFeedback::sender_ssrc, kSenderSsrc))));
1396 InjectRtcpPacket(packet);
sprang49f9cdb2015-10-01 03:06:57 -07001397}
1398
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001399TEST_F(RtcpReceiverTest, ReceivesRemb) {
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001400 const uint32_t kBitrateBps = 500000;
1401 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001402 remb.SetSenderSsrc(kSenderSsrc);
1403 remb.SetBitrateBps(kBitrateBps);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001404
danilchap1e714ae2016-09-05 09:57:22 -07001405 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1406 InjectRtcpPacket(remb);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001407}
1408
sprang49f9cdb2015-10-01 03:06:57 -07001409TEST_F(RtcpReceiverTest, HandlesInvalidTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001410 // Send a compound packet with a TransportFeedback followed by something else.
1411 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001412 packet.SetMediaSsrc(kReceiverMainSsrc);
1413 packet.SetSenderSsrc(kSenderSsrc);
1414 packet.SetBase(1, 1000);
1415 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001416
1417 static uint32_t kBitrateBps = 50000;
1418 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001419 remb.SetSenderSsrc(kSenderSsrc);
1420 remb.SetBitrateBps(kBitrateBps);
danilchap7a4116a2016-03-14 08:19:28 -07001421 rtcp::CompoundPacket compound;
1422 compound.Append(&packet);
1423 compound.Append(&remb);
1424 rtc::Buffer built_packet = compound.Build();
sprang49f9cdb2015-10-01 03:06:57 -07001425
1426 // Modify the TransportFeedback packet so that it is invalid.
1427 const size_t kStatusCountOffset = 14;
Yves Gerey665174f2018-06-19 15:03:05 +02001428 ByteWriter<uint16_t>::WriteBigEndian(&built_packet.data()[kStatusCountOffset],
1429 42);
sprang49f9cdb2015-10-01 03:06:57 -07001430
danilchap1e714ae2016-09-05 09:57:22 -07001431 // Stress no transport feedback is expected.
1432 EXPECT_CALL(transport_feedback_observer_, OnTransportFeedback(_)).Times(0);
1433 // But remb should be processed and cause a callback
1434 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1435 InjectRtcpPacket(built_packet);
sprang49f9cdb2015-10-01 03:06:57 -07001436}
1437
danilchap1e714ae2016-09-05 09:57:22 -07001438TEST_F(RtcpReceiverTest, Nack) {
1439 const uint16_t kNackList1[] = {1, 2, 3, 5};
danilchap142f0192016-10-20 08:22:42 -07001440 const uint16_t kNackList23[] = {5, 7, 30, 40, 41, 58, 59, 61, 63};
1441 const size_t kNackListLength2 = 4;
1442 const size_t kNackListLength3 = arraysize(kNackList23) - kNackListLength2;
danilchap1e714ae2016-09-05 09:57:22 -07001443 std::set<uint16_t> nack_set;
1444 nack_set.insert(std::begin(kNackList1), std::end(kNackList1));
danilchap142f0192016-10-20 08:22:42 -07001445 nack_set.insert(std::begin(kNackList23), std::end(kNackList23));
danilchap1e714ae2016-09-05 09:57:22 -07001446
danilchap142f0192016-10-20 08:22:42 -07001447 rtcp::Nack nack1;
1448 nack1.SetSenderSsrc(kSenderSsrc);
1449 nack1.SetMediaSsrc(kReceiverMainSsrc);
1450 nack1.SetPacketIds(kNackList1, arraysize(kNackList1));
danilchap1e714ae2016-09-05 09:57:22 -07001451
1452 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList1)));
danilchap1e714ae2016-09-05 09:57:22 -07001453 EXPECT_CALL(packet_type_counter_observer_,
1454 RtcpPacketTypesCounterUpdated(
1455 kReceiverMainSsrc,
1456 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
danilchap142f0192016-10-20 08:22:42 -07001457 arraysize(kNackList1)),
1458 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1459 arraysize(kNackList1)))));
1460 InjectRtcpPacket(nack1);
1461
1462 rtcp::Nack nack2;
1463 nack2.SetSenderSsrc(kSenderSsrc);
1464 nack2.SetMediaSsrc(kReceiverMainSsrc);
1465 nack2.SetPacketIds(kNackList23, kNackListLength2);
1466
1467 rtcp::Nack nack3;
1468 nack3.SetSenderSsrc(kSenderSsrc);
1469 nack3.SetMediaSsrc(kReceiverMainSsrc);
1470 nack3.SetPacketIds(kNackList23 + kNackListLength2, kNackListLength3);
1471
1472 rtcp::CompoundPacket two_nacks;
1473 two_nacks.Append(&nack2);
1474 two_nacks.Append(&nack3);
1475
1476 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList23)));
1477 EXPECT_CALL(packet_type_counter_observer_,
1478 RtcpPacketTypesCounterUpdated(
1479 kReceiverMainSsrc,
1480 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
1481 arraysize(kNackList1) + arraysize(kNackList23)),
danilchap1e714ae2016-09-05 09:57:22 -07001482 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1483 nack_set.size()))));
danilchap142f0192016-10-20 08:22:42 -07001484 InjectRtcpPacket(two_nacks);
danilchap1e714ae2016-09-05 09:57:22 -07001485}
1486
1487TEST_F(RtcpReceiverTest, NackNotForUsIgnored) {
1488 const uint16_t kNackList1[] = {1, 2, 3, 5};
1489 const size_t kNackListLength1 = std::end(kNackList1) - std::begin(kNackList1);
1490
1491 rtcp::Nack nack;
danilchap822a16f2016-09-27 09:27:47 -07001492 nack.SetSenderSsrc(kSenderSsrc);
1493 nack.SetMediaSsrc(kNotToUsSsrc);
1494 nack.SetPacketIds(kNackList1, kNackListLength1);
danilchap1e714ae2016-09-05 09:57:22 -07001495
1496 EXPECT_CALL(packet_type_counter_observer_,
1497 RtcpPacketTypesCounterUpdated(
1498 _, Field(&RtcpPacketTypeCounter::nack_requests, 0)));
1499 InjectRtcpPacket(nack);
1500}
1501
1502TEST_F(RtcpReceiverTest, ForceSenderReport) {
1503 rtcp::RapidResyncRequest rr;
danilchap822a16f2016-09-27 09:27:47 -07001504 rr.SetSenderSsrc(kSenderSsrc);
1505 rr.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -07001506
1507 EXPECT_CALL(rtp_rtcp_impl_, OnRequestSendReport());
1508 InjectRtcpPacket(rr);
1509}
hta@webrtc.org47059b52012-05-02 07:46:22 +00001510
spranga790d832016-12-02 07:29:44 -08001511TEST_F(RtcpReceiverTest, ReceivesTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001512 VideoBitrateAllocation expected_allocation;
spranga790d832016-12-02 07:29:44 -08001513 expected_allocation.SetBitrate(0, 0, 10000);
1514 expected_allocation.SetBitrate(0, 1, 20000);
1515 expected_allocation.SetBitrate(1, 0, 40000);
1516 expected_allocation.SetBitrate(1, 1, 80000);
1517
1518 rtcp::TargetBitrate bitrate;
1519 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1520 bitrate.AddTargetBitrate(0, 1, expected_allocation.GetBitrate(0, 1) / 1000);
1521 bitrate.AddTargetBitrate(1, 0, expected_allocation.GetBitrate(1, 0) / 1000);
1522 bitrate.AddTargetBitrate(1, 1, expected_allocation.GetBitrate(1, 1) / 1000);
1523
1524 rtcp::ExtendedReports xr;
1525 xr.SetTargetBitrate(bitrate);
1526
sprangb32aaf92017-08-28 05:49:12 -07001527 // Wrong sender ssrc, target bitrate should be discarded.
1528 xr.SetSenderSsrc(kSenderSsrc + 1);
1529 EXPECT_CALL(bitrate_allocation_observer_,
1530 OnBitrateAllocationUpdated(expected_allocation))
1531 .Times(0);
1532 InjectRtcpPacket(xr);
1533
1534 // Set correct ssrc, callback should be called once.
1535 xr.SetSenderSsrc(kSenderSsrc);
spranga790d832016-12-02 07:29:44 -08001536 EXPECT_CALL(bitrate_allocation_observer_,
1537 OnBitrateAllocationUpdated(expected_allocation));
1538 InjectRtcpPacket(xr);
1539}
1540
sprang6d314c72016-12-06 06:08:53 -08001541TEST_F(RtcpReceiverTest, HandlesIncorrectTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001542 VideoBitrateAllocation expected_allocation;
sprang6d314c72016-12-06 06:08:53 -08001543 expected_allocation.SetBitrate(0, 0, 10000);
1544
1545 rtcp::TargetBitrate bitrate;
1546 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1547 bitrate.AddTargetBitrate(0, kMaxTemporalStreams, 20000);
1548 bitrate.AddTargetBitrate(kMaxSpatialLayers, 0, 40000);
1549
1550 rtcp::ExtendedReports xr;
1551 xr.SetTargetBitrate(bitrate);
sprangb32aaf92017-08-28 05:49:12 -07001552 xr.SetSenderSsrc(kSenderSsrc);
sprang6d314c72016-12-06 06:08:53 -08001553
1554 EXPECT_CALL(bitrate_allocation_observer_,
1555 OnBitrateAllocationUpdated(expected_allocation));
1556 InjectRtcpPacket(xr);
1557}
1558
hta@webrtc.org47059b52012-05-02 07:46:22 +00001559} // namespace webrtc