blob: c9664703b050ec3dc9f259c1770c8bfd3b393641 [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
kwiberg84be5112016-04-27 01:19:58 -070011#include <memory>
12
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "api/array_view.h"
Henrik Boströmf2047872019-05-16 13:32:20 +020014#include "api/units/timestamp.h"
Erik Språngeeaa8f92018-05-17 12:35:56 +020015#include "api/video/video_bitrate_allocation.h"
Jiawei Ou4206a0a2018-07-20 15:49:43 -070016#include "api/video/video_bitrate_allocator.h"
Henrik Boströmf2047872019-05-16 13:32:20 +020017#include "modules/rtp_rtcp/include/report_block_data.h"
Sebastian Janssonef9daee2018-02-22 14:49:02 +010018#include "modules/rtp_rtcp/mocks/mock_rtcp_bandwidth_observer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "modules/rtp_rtcp/source/byte_io.h"
20#include "modules/rtp_rtcp/source/rtcp_packet.h"
21#include "modules/rtp_rtcp/source/rtcp_packet/app.h"
22#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
23#include "modules/rtp_rtcp/source/rtcp_packet/compound_packet.h"
24#include "modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.h"
25#include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
26#include "modules/rtp_rtcp/source/rtcp_packet/fir.h"
27#include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
28#include "modules/rtp_rtcp/source/rtcp_packet/pli.h"
29#include "modules/rtp_rtcp/source/rtcp_packet/rapid_resync_request.h"
30#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
31#include "modules/rtp_rtcp/source/rtcp_packet/remb.h"
32#include "modules/rtp_rtcp/source/rtcp_packet/sdes.h"
33#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
34#include "modules/rtp_rtcp/source/rtcp_packet/tmmbr.h"
35#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
36#include "modules/rtp_rtcp/source/rtcp_receiver.h"
37#include "modules/rtp_rtcp/source/time_util.h"
38#include "rtc_base/arraysize.h"
Henrik Boströmf2047872019-05-16 13:32:20 +020039#include "rtc_base/fake_clock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020040#include "rtc_base/random.h"
41#include "system_wrappers/include/ntp_time.h"
42#include "test/gmock.h"
43#include "test/gtest.h"
hta@webrtc.org47059b52012-05-02 07:46:22 +000044
45namespace webrtc {
danilchap1e714ae2016-09-05 09:57:22 -070046namespace {
hta@webrtc.org47059b52012-05-02 07:46:22 +000047
Henrik Boströmf2047872019-05-16 13:32:20 +020048using rtcp::ReceiveTimeInfo;
danilchap1e714ae2016-09-05 09:57:22 -070049using ::testing::_;
50using ::testing::AllOf;
51using ::testing::ElementsAreArray;
52using ::testing::Field;
Henrik Boströmf2047872019-05-16 13:32:20 +020053using ::testing::InSequence;
danilchap1e714ae2016-09-05 09:57:22 -070054using ::testing::IsEmpty;
55using ::testing::NiceMock;
56using ::testing::Property;
57using ::testing::SizeIs;
58using ::testing::StrEq;
59using ::testing::StrictMock;
60using ::testing::UnorderedElementsAre;
hta@webrtc.org47059b52012-05-02 07:46:22 +000061
danilchap1e714ae2016-09-05 09:57:22 -070062class MockRtcpPacketTypeCounterObserver : public RtcpPacketTypeCounterObserver {
hta@webrtc.org47059b52012-05-02 07:46:22 +000063 public:
danilchap1e714ae2016-09-05 09:57:22 -070064 MOCK_METHOD2(RtcpPacketTypesCounterUpdated,
65 void(uint32_t, const RtcpPacketTypeCounter&));
hta@webrtc.org47059b52012-05-02 07:46:22 +000066};
67
danilchap1e714ae2016-09-05 09:57:22 -070068class MockRtcpIntraFrameObserver : public RtcpIntraFrameObserver {
69 public:
70 MOCK_METHOD1(OnReceivedIntraFrameRequest, void(uint32_t));
danilchap1e714ae2016-09-05 09:57:22 -070071};
72
Elad Alon0a8562e2019-04-09 11:55:13 +020073class MockRtcpLossNotificationObserver : public RtcpLossNotificationObserver {
74 public:
75 ~MockRtcpLossNotificationObserver() override = default;
76 MOCK_METHOD4(OnReceivedLossNotification,
77 void(uint32_t ssrc,
78 uint16_t seq_num_of_last_decodable,
79 uint16_t seq_num_of_last_received,
80 bool decodability_flag));
81};
82
danilchap1e714ae2016-09-05 09:57:22 -070083class MockRtcpCallbackImpl : public RtcpStatisticsCallback {
84 public:
85 MOCK_METHOD2(StatisticsUpdated, void(const RtcpStatistics&, uint32_t));
86 MOCK_METHOD2(CNameChanged, void(const char*, uint32_t));
87};
88
Henrik Boströmf2047872019-05-16 13:32:20 +020089class MockReportBlockDataObserverImpl : public ReportBlockDataObserver {
90 public:
91 MOCK_METHOD1(OnReportBlockDataUpdated, void(ReportBlockData));
92};
93
danilchap1e714ae2016-09-05 09:57:22 -070094class MockTransportFeedbackObserver : public TransportFeedbackObserver {
95 public:
Erik Språng30a276b2019-04-23 12:00:11 +020096 MOCK_METHOD1(OnAddPacket, void(const RtpPacketSendInfo&));
danilchap1e714ae2016-09-05 09:57:22 -070097 MOCK_METHOD1(OnTransportFeedback, void(const rtcp::TransportFeedback&));
elad.alonf9490002017-03-06 05:32:21 -080098 MOCK_CONST_METHOD0(GetTransportFeedbackVector, std::vector<PacketFeedback>());
danilchap1e714ae2016-09-05 09:57:22 -070099};
100
danilchap1e714ae2016-09-05 09:57:22 -0700101class MockModuleRtpRtcp : public RTCPReceiver::ModuleRtpRtcp {
102 public:
103 MOCK_METHOD1(SetTmmbn, void(std::vector<rtcp::TmmbItem>));
104 MOCK_METHOD0(OnRequestSendReport, void());
105 MOCK_METHOD1(OnReceivedNack, void(const std::vector<uint16_t>&));
106 MOCK_METHOD1(OnReceivedRtcpReportBlocks, void(const ReportBlockList&));
107};
108
spranga790d832016-12-02 07:29:44 -0800109class MockVideoBitrateAllocationObserver
110 : public VideoBitrateAllocationObserver {
111 public:
112 MOCK_METHOD1(OnBitrateAllocationUpdated,
Erik Språng566124a2018-04-23 12:32:22 +0200113 void(const VideoBitrateAllocation& allocation));
spranga790d832016-12-02 07:29:44 -0800114};
115
danilchap1e714ae2016-09-05 09:57:22 -0700116// SSRC of remote peer, that sends rtcp packet to the rtcp receiver under test.
117constexpr uint32_t kSenderSsrc = 0x10203;
118// SSRCs of local peer, that rtcp packet addressed to.
119constexpr uint32_t kReceiverMainSsrc = 0x123456;
120// RtcpReceiver can accept several ssrc, e.g. regular and rtx streams.
121constexpr uint32_t kReceiverExtraSsrc = 0x1234567;
122// SSRCs to ignore (i.e. not configured in RtcpReceiver).
123constexpr uint32_t kNotToUsSsrc = 0x654321;
124constexpr uint32_t kUnknownSenderSsrc = 0x54321;
125
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800126constexpr int64_t kRtcpIntervalMs = 1000;
127
danilchap1e714ae2016-09-05 09:57:22 -0700128} // namespace
129
hta@webrtc.org47059b52012-05-02 07:46:22 +0000130class RtcpReceiverTest : public ::testing::Test {
131 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000132 RtcpReceiverTest()
danilchap1e714ae2016-09-05 09:57:22 -0700133 : system_clock_(1335900000),
134 rtcp_receiver_(&system_clock_,
135 false,
136 &packet_type_counter_observer_,
137 &bandwidth_observer_,
138 &intra_frame_observer_,
Elad Alon0a8562e2019-04-09 11:55:13 +0200139 &rtcp_loss_notification_observer_,
danilchap1e714ae2016-09-05 09:57:22 -0700140 &transport_feedback_observer_,
spranga790d832016-12-02 07:29:44 -0800141 &bitrate_allocation_observer_,
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800142 kRtcpIntervalMs,
danilchap1e714ae2016-09-05 09:57:22 -0700143 &rtp_rtcp_impl_) {}
144 void SetUp() {
145 std::set<uint32_t> ssrcs = {kReceiverMainSsrc, kReceiverExtraSsrc};
danilchap1e714ae2016-09-05 09:57:22 -0700146 rtcp_receiver_.SetSsrcs(kReceiverMainSsrc, ssrcs);
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000147
danilchap1e714ae2016-09-05 09:57:22 -0700148 rtcp_receiver_.SetRemoteSSRC(kSenderSsrc);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000149 }
Erik Språng737336d2016-07-29 12:59:36 +0200150
danilchap1e714ae2016-09-05 09:57:22 -0700151 void InjectRtcpPacket(rtc::ArrayView<const uint8_t> raw) {
152 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
hta@webrtc.org47059b52012-05-02 07:46:22 +0000153 }
154
danilchap1e714ae2016-09-05 09:57:22 -0700155 void InjectRtcpPacket(const rtcp::RtcpPacket& packet) {
156 rtc::Buffer raw = packet.Build();
157 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
158 }
159
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000160 SimulatedClock system_clock_;
danilchap1e714ae2016-09-05 09:57:22 -0700161 // Callbacks to packet_type_counter_observer are frequent but most of the time
162 // are not interesting.
163 NiceMock<MockRtcpPacketTypeCounterObserver> packet_type_counter_observer_;
164 StrictMock<MockRtcpBandwidthObserver> bandwidth_observer_;
165 StrictMock<MockRtcpIntraFrameObserver> intra_frame_observer_;
Elad Alon0a8562e2019-04-09 11:55:13 +0200166 StrictMock<MockRtcpLossNotificationObserver> rtcp_loss_notification_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700167 StrictMock<MockTransportFeedbackObserver> transport_feedback_observer_;
spranga790d832016-12-02 07:29:44 -0800168 StrictMock<MockVideoBitrateAllocationObserver> bitrate_allocation_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700169 StrictMock<MockModuleRtpRtcp> rtp_rtcp_impl_;
hta@webrtc.org47059b52012-05-02 07:46:22 +0000170
danilchap1e714ae2016-09-05 09:57:22 -0700171 RTCPReceiver rtcp_receiver_;
172};
hta@webrtc.org47059b52012-05-02 07:46:22 +0000173
174TEST_F(RtcpReceiverTest, BrokenPacketIsIgnored) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000175 const uint8_t bad_packet[] = {0, 0, 0, 0};
danilchap1e714ae2016-09-05 09:57:22 -0700176 EXPECT_CALL(packet_type_counter_observer_,
177 RtcpPacketTypesCounterUpdated(_, _))
178 .Times(0);
179 InjectRtcpPacket(bad_packet);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000180}
181
danilchap50da1d32016-03-10 13:13:52 -0800182TEST_F(RtcpReceiverTest, InvalidFeedbackPacketIsIgnored) {
183 // Too short feedback packet.
danilchap1e714ae2016-09-05 09:57:22 -0700184 const uint8_t bad_packet[] = {0x81, rtcp::Rtpfb::kPacketType, 0, 0};
185
186 // TODO(danilchap): Add expectation RtcpPacketTypesCounterUpdated
187 // is not called once parser would be adjusted to avoid that callback on
188 // semi-valid packets.
189 InjectRtcpPacket(bad_packet);
danilchap50da1d32016-03-10 13:13:52 -0800190}
191
hta@webrtc.org47059b52012-05-02 07:46:22 +0000192TEST_F(RtcpReceiverTest, InjectSrPacket) {
danilchapa04d9c32017-07-25 04:03:39 -0700193 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
danilchap1e714ae2016-09-05 09:57:22 -0700194
195 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000196 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700197 sr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700198
199 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
200 EXPECT_CALL(bandwidth_observer_,
201 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
202 InjectRtcpPacket(sr);
203
danilchapa04d9c32017-07-25 04:03:39 -0700204 EXPECT_TRUE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
hta@webrtc.org47059b52012-05-02 07:46:22 +0000205}
206
danilchap1e714ae2016-09-05 09:57:22 -0700207TEST_F(RtcpReceiverTest, InjectSrPacketFromUnknownSender) {
208 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000209 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700210 sr.SetSenderSsrc(kUnknownSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700211
212 // The parser will handle report blocks in Sender Report from other than his
213 // expected peer.
214 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
215 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, now));
216 InjectRtcpPacket(sr);
217
218 // But will not flag that he's gotten sender information.
danilchapa04d9c32017-07-25 04:03:39 -0700219 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000220}
221
Danil Chapovalova094fd12016-02-22 18:59:36 +0100222TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesRTT) {
223 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100224 const int64_t kRttMs = r.Rand(1, 9 * 3600 * 1000);
225 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
226 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100227
Danil Chapovalova094fd12016-02-22 18:59:36 +0100228 int64_t rtt_ms = 0;
229 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700230 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100231
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200232 uint32_t sent_ntp =
233 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100234 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
235
236 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700237 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100238 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700239 block.SetMediaSsrc(kReceiverMainSsrc);
240 block.SetLastSr(sent_ntp);
241 block.SetDelayLastSr(kDelayNtp);
242 sr.AddReportBlock(block);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100243
danilchap1e714ae2016-09-05 09:57:22 -0700244 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
245 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
246 InjectRtcpPacket(sr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100247
248 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700249 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100250 EXPECT_NEAR(kRttMs, rtt_ms, 1);
251}
252
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100253TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesNegativeRTTAsOne) {
254 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100255 const int64_t kRttMs = r.Rand(-3600 * 1000, -1);
256 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
257 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
258
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100259 int64_t rtt_ms = 0;
260 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700261 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100262
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200263 uint32_t sent_ntp =
264 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100265 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
266
267 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700268 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100269 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700270 block.SetMediaSsrc(kReceiverMainSsrc);
271 block.SetLastSr(sent_ntp);
272 block.SetDelayLastSr(kDelayNtp);
273 sr.AddReportBlock(block);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100274
danilchap1e714ae2016-09-05 09:57:22 -0700275 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
276 EXPECT_CALL(bandwidth_observer_,
277 OnReceivedRtcpReceiverReport(SizeIs(1), _, _));
278 InjectRtcpPacket(sr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100279
280 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700281 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100282 EXPECT_EQ(1, rtt_ms);
283}
284
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100285TEST_F(
286 RtcpReceiverTest,
287 TwoReportBlocksWithLastOneWithoutLastSrCalculatesRttForBandwidthObserver) {
288 const int64_t kRttMs = 120;
289 const uint32_t kDelayNtp = 123000;
290 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
291
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200292 uint32_t sent_ntp =
293 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100294 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
295
296 rtcp::SenderReport sr;
297 sr.SetSenderSsrc(kSenderSsrc);
298 rtcp::ReportBlock block;
299 block.SetMediaSsrc(kReceiverMainSsrc);
300 block.SetLastSr(sent_ntp);
301 block.SetDelayLastSr(kDelayNtp);
302 sr.AddReportBlock(block);
303 block.SetMediaSsrc(kReceiverExtraSsrc);
304 block.SetLastSr(0);
305 sr.AddReportBlock(block);
306
307 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
308 EXPECT_CALL(bandwidth_observer_,
309 OnReceivedRtcpReceiverReport(SizeIs(2), kRttMs, _));
310 InjectRtcpPacket(sr);
311}
312
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000313TEST_F(RtcpReceiverTest, InjectRrPacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700314 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000315 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700316 rr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700317
318 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
319 EXPECT_CALL(bandwidth_observer_,
320 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
321 InjectRtcpPacket(rr);
322
danilchap1e714ae2016-09-05 09:57:22 -0700323 std::vector<RTCPReportBlock> report_blocks;
324 rtcp_receiver_.StatisticsReceived(&report_blocks);
325 EXPECT_TRUE(report_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000326}
327
328TEST_F(RtcpReceiverTest, InjectRrPacketWithReportBlockNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700329 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000330 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700331 rb.SetMediaSsrc(kNotToUsSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000332 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700333 rr.SetSenderSsrc(kSenderSsrc);
334 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000335
danilchap1e714ae2016-09-05 09:57:22 -0700336 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
337 EXPECT_CALL(bandwidth_observer_,
338 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
339 InjectRtcpPacket(rr);
340
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200341 EXPECT_EQ(0, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000342 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700343 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000344 EXPECT_TRUE(received_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000345}
346
347TEST_F(RtcpReceiverTest, InjectRrPacketWithOneReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700348 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000349
350 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700351 rb.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000352 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700353 rr.SetSenderSsrc(kSenderSsrc);
354 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000355
danilchap1e714ae2016-09-05 09:57:22 -0700356 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
357 EXPECT_CALL(bandwidth_observer_,
358 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
359 InjectRtcpPacket(rr);
360
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200361 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
362 std::vector<RTCPReportBlock> received_blocks;
363 rtcp_receiver_.StatisticsReceived(&received_blocks);
364 EXPECT_EQ(1u, received_blocks.size());
365}
366
367TEST_F(RtcpReceiverTest, InjectSrPacketWithOneReportBlock) {
368 int64_t now = system_clock_.TimeInMilliseconds();
369
370 rtcp::ReportBlock rb;
371 rb.SetMediaSsrc(kReceiverMainSsrc);
372 rtcp::SenderReport sr;
373 sr.SetSenderSsrc(kSenderSsrc);
374 sr.AddReportBlock(rb);
375
376 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
377 EXPECT_CALL(bandwidth_observer_,
378 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
379 InjectRtcpPacket(sr);
380
381 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000382 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700383 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000384 EXPECT_EQ(1u, received_blocks.size());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000385}
386
387TEST_F(RtcpReceiverTest, InjectRrPacketWithTwoReportBlocks) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000388 const uint16_t kSequenceNumbers[] = {10, 12423};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000389 const uint32_t kCumLost[] = {13, 555};
390 const uint8_t kFracLost[] = {20, 11};
danilchap1e714ae2016-09-05 09:57:22 -0700391 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000392
393 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700394 rb1.SetMediaSsrc(kReceiverMainSsrc);
395 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
396 rb1.SetFractionLost(10);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000397
398 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700399 rb2.SetMediaSsrc(kReceiverExtraSsrc);
400 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
401 rb2.SetFractionLost(0);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000402
403 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700404 rr1.SetSenderSsrc(kSenderSsrc);
405 rr1.AddReportBlock(rb1);
406 rr1.AddReportBlock(rb2);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000407
danilchap1e714ae2016-09-05 09:57:22 -0700408 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
409 EXPECT_CALL(bandwidth_observer_,
410 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
411 InjectRtcpPacket(rr1);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000412
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200413 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700414 std::vector<RTCPReportBlock> received_blocks;
415 rtcp_receiver_.StatisticsReceived(&received_blocks);
416 EXPECT_THAT(received_blocks,
srte3e69e5c2017-08-09 06:13:45 -0700417 UnorderedElementsAre(Field(&RTCPReportBlock::fraction_lost, 0),
418 Field(&RTCPReportBlock::fraction_lost, 10)));
danilchap1e714ae2016-09-05 09:57:22 -0700419
420 // Insert next receiver report with same ssrc but new values.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000421 rtcp::ReportBlock rb3;
danilchap822a16f2016-09-27 09:27:47 -0700422 rb3.SetMediaSsrc(kReceiverMainSsrc);
423 rb3.SetExtHighestSeqNum(kSequenceNumbers[0]);
424 rb3.SetFractionLost(kFracLost[0]);
425 rb3.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000426
427 rtcp::ReportBlock rb4;
danilchap822a16f2016-09-27 09:27:47 -0700428 rb4.SetMediaSsrc(kReceiverExtraSsrc);
429 rb4.SetExtHighestSeqNum(kSequenceNumbers[1]);
430 rb4.SetFractionLost(kFracLost[1]);
431 rb4.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000432
433 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700434 rr2.SetSenderSsrc(kSenderSsrc);
435 rr2.AddReportBlock(rb3);
436 rr2.AddReportBlock(rb4);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000437
danilchap1e714ae2016-09-05 09:57:22 -0700438 // Advance time to make 1st sent time and 2nd sent time different.
439 system_clock_.AdvanceTimeMilliseconds(500);
440 now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000441
danilchap1e714ae2016-09-05 09:57:22 -0700442 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
443 EXPECT_CALL(bandwidth_observer_,
444 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
445 InjectRtcpPacket(rr2);
446
447 received_blocks.clear();
448 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000449 EXPECT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700450 EXPECT_THAT(
451 received_blocks,
452 UnorderedElementsAre(
453 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
454 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
455 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
456 Field(&RTCPReportBlock::extended_highest_sequence_number,
457 kSequenceNumbers[0])),
458 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverExtraSsrc),
459 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
460 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
461 Field(&RTCPReportBlock::extended_highest_sequence_number,
462 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000463}
464
465TEST_F(RtcpReceiverTest, InjectRrPacketsFromTwoRemoteSsrcs) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000466 const uint32_t kSenderSsrc2 = 0x20304;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000467 const uint16_t kSequenceNumbers[] = {10, 12423};
Sebastian Jansson9701e0c2018-08-09 11:21:11 +0200468 const int32_t kCumLost[] = {13, 555};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000469 const uint8_t kFracLost[] = {20, 11};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000470
471 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700472 rb1.SetMediaSsrc(kReceiverMainSsrc);
473 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
474 rb1.SetFractionLost(kFracLost[0]);
475 rb1.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000476 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700477 rr1.SetSenderSsrc(kSenderSsrc);
478 rr1.AddReportBlock(rb1);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000479
danilchap1e714ae2016-09-05 09:57:22 -0700480 int64_t now = system_clock_.TimeInMilliseconds();
481
482 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
483 EXPECT_CALL(bandwidth_observer_,
484 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
485 InjectRtcpPacket(rr1);
486
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200487 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000488
489 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700490 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000491 EXPECT_EQ(1u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700492 EXPECT_EQ(kSenderSsrc, received_blocks[0].sender_ssrc);
493 EXPECT_EQ(kReceiverMainSsrc, received_blocks[0].source_ssrc);
494 EXPECT_EQ(kFracLost[0], received_blocks[0].fraction_lost);
495 EXPECT_EQ(kCumLost[0], received_blocks[0].packets_lost);
496 EXPECT_EQ(kSequenceNumbers[0],
497 received_blocks[0].extended_highest_sequence_number);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000498
499 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700500 rb2.SetMediaSsrc(kReceiverMainSsrc);
501 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
502 rb2.SetFractionLost(kFracLost[1]);
503 rb2.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000504 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700505 rr2.SetSenderSsrc(kSenderSsrc2);
506 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -0700507
508 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
509 EXPECT_CALL(bandwidth_observer_,
510 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
511 InjectRtcpPacket(rr2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000512
513 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700514 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000515 ASSERT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700516 EXPECT_THAT(
517 received_blocks,
518 UnorderedElementsAre(
519 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
520 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc),
521 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
522 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
523 Field(&RTCPReportBlock::extended_highest_sequence_number,
524 kSequenceNumbers[0])),
525 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
526 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc2),
527 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
528 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
529 Field(&RTCPReportBlock::extended_highest_sequence_number,
530 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000531}
532
533TEST_F(RtcpReceiverTest, GetRtt) {
danilchap28b03eb2016-10-05 06:59:44 -0700534 const uint32_t kSentCompactNtp = 0x1234;
535 const uint32_t kDelayCompactNtp = 0x222;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000536 // No report block received.
Erik Språng6b8d3552015-09-24 15:06:57 +0200537 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700538 -1, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000539
540 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700541 rb.SetMediaSsrc(kReceiverMainSsrc);
danilchap28b03eb2016-10-05 06:59:44 -0700542 rb.SetLastSr(kSentCompactNtp);
543 rb.SetDelayLastSr(kDelayCompactNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700544
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000545 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700546 rr.SetSenderSsrc(kSenderSsrc);
547 rr.AddReportBlock(rb);
danilchap1e714ae2016-09-05 09:57:22 -0700548 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000549
danilchap1e714ae2016-09-05 09:57:22 -0700550 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
551 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
552 InjectRtcpPacket(rr);
553
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200554 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700555 EXPECT_EQ(
556 0, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000557}
558
danilchap1e714ae2016-09-05 09:57:22 -0700559// Ij packets are ignored.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000560TEST_F(RtcpReceiverTest, InjectIjWithNoItem) {
danilchapf8506cb2015-11-13 07:33:20 -0800561 rtcp::ExtendedJitterReport ij;
danilchap1e714ae2016-09-05 09:57:22 -0700562 InjectRtcpPacket(ij);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000563}
564
danilchap1e714ae2016-09-05 09:57:22 -0700565// App packets are ignored.
566TEST_F(RtcpReceiverTest, InjectApp) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000567 rtcp::App app;
danilchap822a16f2016-09-27 09:27:47 -0700568 app.SetSubType(30);
569 app.SetName(0x17a177e);
danilchap1e714ae2016-09-05 09:57:22 -0700570 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
danilchap822a16f2016-09-27 09:27:47 -0700571 app.SetData(kData, sizeof(kData));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000572
danilchap1e714ae2016-09-05 09:57:22 -0700573 InjectRtcpPacket(app);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000574}
575
576TEST_F(RtcpReceiverTest, InjectSdesWithOneChunk) {
danilchap1e714ae2016-09-05 09:57:22 -0700577 const char kCname[] = "alice@host";
578 MockRtcpCallbackImpl callback;
579 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000580 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700581 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000582
danilchap1e714ae2016-09-05 09:57:22 -0700583 EXPECT_CALL(callback, CNameChanged(StrEq(kCname), kSenderSsrc));
584 InjectRtcpPacket(sdes);
585
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000586 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700587 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
588 EXPECT_EQ(0, strncmp(cName, kCname, RTCP_CNAME_SIZE));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000589}
590
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000591TEST_F(RtcpReceiverTest, InjectByePacket_RemovesCname) {
danilchap1e714ae2016-09-05 09:57:22 -0700592 const char kCname[] = "alice@host";
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
danilchap1e714ae2016-09-05 09:57:22 -0700596 InjectRtcpPacket(sdes);
597
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000598 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700599 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000600
601 // Verify that BYE removes the CNAME.
602 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700603 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700604
605 InjectRtcpPacket(bye);
606
607 EXPECT_EQ(-1, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000608}
609
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000610TEST_F(RtcpReceiverTest, InjectByePacket_RemovesReportBlocks) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000611 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700612 rb1.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000613 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700614 rb2.SetMediaSsrc(kReceiverExtraSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000615 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700616 rr.SetSenderSsrc(kSenderSsrc);
617 rr.AddReportBlock(rb1);
618 rr.AddReportBlock(rb2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000619
danilchap1e714ae2016-09-05 09:57:22 -0700620 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
621 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
622 InjectRtcpPacket(rr);
623
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000624 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700625 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000626 EXPECT_EQ(2u, received_blocks.size());
627
628 // Verify that BYE removes the report blocks.
629 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700630 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700631
632 InjectRtcpPacket(bye);
633
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000634 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700635 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000636 EXPECT_TRUE(received_blocks.empty());
637
danilchap1e714ae2016-09-05 09:57:22 -0700638 // Inject packet again.
639 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
640 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
641 InjectRtcpPacket(rr);
642
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000643 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700644 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000645 EXPECT_EQ(2u, received_blocks.size());
646}
647
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200648TEST_F(RtcpReceiverTest, InjectByePacketRemovesReferenceTimeInfo) {
649 rtcp::ExtendedReports xr;
650 xr.SetSenderSsrc(kSenderSsrc);
651 rtcp::Rrtr rrtr;
652 rrtr.SetNtp(NtpTime(0x10203, 0x40506));
653 xr.SetRrtr(rrtr);
654 InjectRtcpPacket(xr);
655
656 rtcp::Bye bye;
657 bye.SetSenderSsrc(kSenderSsrc);
658 InjectRtcpPacket(bye);
659
660 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
661}
662
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000663TEST_F(RtcpReceiverTest, InjectPliPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000664 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700665 pli.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700666
667 EXPECT_CALL(
668 packet_type_counter_observer_,
669 RtcpPacketTypesCounterUpdated(
670 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 1)));
671 EXPECT_CALL(intra_frame_observer_,
672 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
673 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000674}
675
676TEST_F(RtcpReceiverTest, PliPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000677 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700678 pli.SetMediaSsrc(kNotToUsSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700679
680 EXPECT_CALL(
681 packet_type_counter_observer_,
682 RtcpPacketTypesCounterUpdated(
683 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 0)));
684 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
685 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000686}
687
688TEST_F(RtcpReceiverTest, InjectFirPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000689 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700690 fir.AddRequestTo(kReceiverMainSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700691
692 EXPECT_CALL(
693 packet_type_counter_observer_,
694 RtcpPacketTypesCounterUpdated(
695 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::fir_packets, 1)));
696 EXPECT_CALL(intra_frame_observer_,
697 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
698 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000699}
700
701TEST_F(RtcpReceiverTest, FirPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000702 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700703 fir.AddRequestTo(kNotToUsSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700704
705 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
706 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000707}
708
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100709TEST_F(RtcpReceiverTest, ExtendedReportsPacketWithZeroReportBlocksIgnored) {
710 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700711 xr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700712
713 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000714}
715
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100716TEST_F(RtcpReceiverTest, InjectExtendedReportsReceiverReferenceTimePacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700717 const NtpTime kNtp(0x10203, 0x40506);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000718 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700719 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100720 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700721 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700722 xr.SetRrtr(rrtr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000723
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200724 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
725 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
726 EXPECT_THAT(last_xr_rtis, IsEmpty());
danilchap1e714ae2016-09-05 09:57:22 -0700727
728 InjectRtcpPacket(xr);
729
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200730 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
731 ASSERT_THAT(last_xr_rtis, SizeIs(1));
732 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
733 EXPECT_EQ(CompactNtp(kNtp), last_xr_rtis[0].last_rr);
734 EXPECT_EQ(0U, last_xr_rtis[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000735}
736
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100737TEST_F(RtcpReceiverTest, ExtendedReportsDlrrPacketNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700738 // Allow calculate rtt using dlrr/rrtr, simulating media receiver side.
739 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000740
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100741 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700742 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700743 xr.AddDlrrItem(ReceiveTimeInfo(kNotToUsSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700744
745 InjectRtcpPacket(xr);
746
747 int64_t rtt_ms = 0;
748 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000749}
750
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100751TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithSubBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700752 const uint32_t kLastRR = 0x12345;
753 const uint32_t kDelay = 0x23456;
754 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
755 int64_t rtt_ms = 0;
756 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000757
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100758 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700759 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700760 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
danilchap1e714ae2016-09-05 09:57:22 -0700761
762 InjectRtcpPacket(xr);
763
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200764 uint32_t compact_ntp_now =
765 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700766 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
767 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
768 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000769}
770
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100771TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithMultipleSubBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700772 const uint32_t kLastRR = 0x12345;
773 const uint32_t kDelay = 0x56789;
774 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000775
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100776 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700777 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700778 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
779 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 1, 0x12345, 0x67890));
780 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 2, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700781
782 InjectRtcpPacket(xr);
783
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200784 uint32_t compact_ntp_now =
785 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700786 int64_t rtt_ms = 0;
787 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
788 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
789 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000790}
791
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100792TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithMultipleReportBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700793 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000794
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000795 rtcp::Rrtr rrtr;
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100796 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700797 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700798 xr.SetRrtr(rrtr);
799 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700800
801 InjectRtcpPacket(xr);
802
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200803 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
804 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
805 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700806 int64_t rtt_ms = 0;
807 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000808}
809
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100810TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithUnknownReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700811 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000812
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000813 rtcp::Rrtr rrtr;
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100814 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700815 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700816 xr.SetRrtr(rrtr);
817 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700818
danilchap69e59e62016-02-17 03:11:42 -0800819 rtc::Buffer packet = xr.Build();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000820 // Modify the DLRR block to have an unsupported block type, from 5 to 6.
danilchap1e714ae2016-09-05 09:57:22 -0700821 ASSERT_EQ(5, packet.data()[20]);
822 packet.data()[20] = 6;
823 InjectRtcpPacket(packet);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000824
danilchap1e714ae2016-09-05 09:57:22 -0700825 // Validate Rrtr was received and processed.
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200826 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
827 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
828 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700829 // Validate Dlrr report wasn't processed.
830 int64_t rtt_ms = 0;
831 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000832}
833
danilchap1e714ae2016-09-05 09:57:22 -0700834TEST_F(RtcpReceiverTest, TestExtendedReportsRrRttInitiallyFalse) {
835 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
836
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000837 int64_t rtt_ms;
danilchap1e714ae2016-09-05 09:57:22 -0700838 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000839}
840
danilchap1e714ae2016-09-05 09:57:22 -0700841TEST_F(RtcpReceiverTest, RttCalculatedAfterExtendedReportsDlrr) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100842 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100843 const int64_t kRttMs = rand.Rand(1, 9 * 3600 * 1000);
844 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
845 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700846 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200847 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalova094fd12016-02-22 18:59:36 +0100848 uint32_t sent_ntp = CompactNtp(now);
849 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
850
Danil Chapovalova094fd12016-02-22 18:59:36 +0100851 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700852 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700853 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700854
855 InjectRtcpPacket(xr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100856
857 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700858 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100859 EXPECT_NEAR(kRttMs, rtt_ms, 1);
860}
861
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100862TEST_F(RtcpReceiverTest, XrDlrrCalculatesNegativeRttAsOne) {
863 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100864 const int64_t kRttMs = rand.Rand(-3600 * 1000, -1);
865 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
866 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200867 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100868 uint32_t sent_ntp = CompactNtp(now);
869 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
danilchap1e714ae2016-09-05 09:57:22 -0700870 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100871
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100872 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700873 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700874 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700875
876 InjectRtcpPacket(xr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100877
878 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700879 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100880 EXPECT_EQ(1, rtt_ms);
881}
882
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200883TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfoInitiallyEmpty) {
884 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000885}
886
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200887TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfo) {
Danil Chapovalovfc47ed62015-12-07 14:46:35 +0100888 const NtpTime kNtp(0x10203, 0x40506);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100889 const uint32_t kNtpMid = CompactNtp(kNtp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000890
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000891 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700892 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100893 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700894 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700895 xr.SetRrtr(rrtr);
danilchap1e714ae2016-09-05 09:57:22 -0700896
897 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000898
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000899 system_clock_.AdvanceTimeMilliseconds(1000);
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200900
901 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
902 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
903 ASSERT_THAT(last_xr_rtis, SizeIs(1));
904 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
905 EXPECT_EQ(kNtpMid, last_xr_rtis[0].last_rr);
906 EXPECT_EQ(65536U, last_xr_rtis[0].delay_since_last_rr);
907}
908
909TEST_F(RtcpReceiverTest,
910 ReceivedRrtrFromSameSsrcUpdatesReceivedReferenceTimeInfo) {
911 const NtpTime kNtp1(0x10203, 0x40506);
912 const NtpTime kNtp2(0x11223, 0x44556);
913 const int64_t kDelayMs = 2000;
914
915 rtcp::ExtendedReports xr;
916 xr.SetSenderSsrc(kSenderSsrc);
917 rtcp::Rrtr rrtr1;
918 rrtr1.SetNtp(kNtp1);
919 xr.SetRrtr(rrtr1);
920 InjectRtcpPacket(xr);
921 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
922 rtcp::Rrtr rrtr2;
923 rrtr2.SetNtp(kNtp2);
924 xr.SetRrtr(rrtr2);
925 InjectRtcpPacket(xr);
926 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
927
928 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
929 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
930 ASSERT_THAT(last_xr_rtis, SizeIs(1));
931 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
932 EXPECT_EQ(CompactNtp(kNtp2), last_xr_rtis[0].last_rr);
933 EXPECT_EQ(kDelayMs * 65536 / 1000, last_xr_rtis[0].delay_since_last_rr);
934}
935
936TEST_F(RtcpReceiverTest, StoresLastReceivedRrtrPerSsrc) {
937 const size_t kNumBufferedReports = 1;
938 const size_t kNumReports =
939 rtcp::ExtendedReports::kMaxNumberOfDlrrItems + kNumBufferedReports;
940 for (size_t i = 0; i < kNumReports; ++i) {
941 rtcp::ExtendedReports xr;
942 xr.SetSenderSsrc(i * 100);
943 rtcp::Rrtr rrtr;
944 rrtr.SetNtp(NtpTime(i * 200, i * 300));
945 xr.SetRrtr(rrtr);
946 InjectRtcpPacket(xr);
947 system_clock_.AdvanceTimeMilliseconds(1000);
948 }
949
950 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
951 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
952 ASSERT_THAT(last_xr_rtis,
953 SizeIs(rtcp::ExtendedReports::kMaxNumberOfDlrrItems));
954 for (size_t i = 0; i < rtcp::ExtendedReports::kMaxNumberOfDlrrItems; ++i) {
955 EXPECT_EQ(i * 100, last_xr_rtis[i].ssrc);
956 EXPECT_EQ(CompactNtp(NtpTime(i * 200, i * 300)), last_xr_rtis[i].last_rr);
957 EXPECT_EQ(65536U * (kNumReports - i), last_xr_rtis[i].delay_since_last_rr);
958 }
959
960 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
961 ASSERT_THAT(last_xr_rtis, SizeIs(kNumBufferedReports));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000962}
963
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000964TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000965 const uint16_t kSequenceNumber = 1234;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000966 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000967
968 // No RR received, shouldn't trigger a timeout.
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800969 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
970 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000971
972 // Add a RR and advance the clock just enough to not trigger a timeout.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000973 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700974 rb1.SetMediaSsrc(kReceiverMainSsrc);
975 rb1.SetExtHighestSeqNum(kSequenceNumber);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000976 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700977 rr1.SetSenderSsrc(kSenderSsrc);
978 rr1.AddReportBlock(rb1);
danilchap1e714ae2016-09-05 09:57:22 -0700979
980 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
981 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
982 InjectRtcpPacket(rr1);
983
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000984 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs - 1);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800985 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
986 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000987
988 // Add a RR with the same extended max as the previous RR to trigger a
989 // sequence number timeout, but not a RR timeout.
danilchap1e714ae2016-09-05 09:57:22 -0700990 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
991 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
992 InjectRtcpPacket(rr1);
993
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000994 system_clock_.AdvanceTimeMilliseconds(2);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800995 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
996 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000997
998 // Advance clock enough to trigger an RR timeout too.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000999 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001000 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001001
1002 // We should only get one timeout even though we still haven't received a new
1003 // RR.
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001004 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1005 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001006
1007 // Add a new RR with increase sequence number to reset timers.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001008 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001009 rb2.SetMediaSsrc(kReceiverMainSsrc);
1010 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001011 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001012 rr2.SetSenderSsrc(kSenderSsrc);
1013 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001014
1015 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1016 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1017 InjectRtcpPacket(rr2);
1018
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001019 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1020 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001021
1022 // Verify we can get a timeout again once we've received new RR.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001023 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -07001024 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1025 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1026 InjectRtcpPacket(rr2);
1027
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001028 system_clock_.AdvanceTimeMilliseconds(kRtcpIntervalMs + 1);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001029 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1030 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
danilchap1e714ae2016-09-05 09:57:22 -07001031
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001032 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001033 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001034}
1035
hta@webrtc.org47059b52012-05-02 07:46:22 +00001036TEST_F(RtcpReceiverTest, TmmbrReceivedWithNoIncomingPacket) {
danilchap1e714ae2016-09-05 09:57:22 -07001037 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001038}
1039
1040TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) {
danilchap1e714ae2016-09-05 09:57:22 -07001041 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001042 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001043 tmmbr.SetSenderSsrc(kSenderSsrc);
1044 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001045 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001046 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001047 rtcp::CompoundPacket compound;
1048 compound.Append(&sr);
1049 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001050
danilchap1e714ae2016-09-05 09:57:22 -07001051 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1052 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(SizeIs(1)));
1053 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1054 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1055 InjectRtcpPacket(compound);
1056
1057 std::vector<rtcp::TmmbItem> tmmbr_received = rtcp_receiver_.TmmbrReceived();
1058 ASSERT_EQ(1u, tmmbr_received.size());
1059 EXPECT_EQ(kBitrateBps, tmmbr_received[0].bitrate_bps());
1060 EXPECT_EQ(kSenderSsrc, tmmbr_received[0].ssrc());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001061}
1062
1063TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -07001064 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001065 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001066 tmmbr.SetSenderSsrc(kSenderSsrc);
1067 tmmbr.AddTmmbr(rtcp::TmmbItem(kNotToUsSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001068
1069 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001070 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001071 rtcp::CompoundPacket compound;
1072 compound.Append(&sr);
1073 compound.Append(&tmmbr);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001074
danilchap1e714ae2016-09-05 09:57:22 -07001075 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1076 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1077 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1078 InjectRtcpPacket(compound);
1079
1080 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001081}
1082
1083TEST_F(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001084 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001085 tmmbr.SetSenderSsrc(kSenderSsrc);
1086 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 0, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001087 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001088 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001089 rtcp::CompoundPacket compound;
1090 compound.Append(&sr);
1091 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001092
danilchap1e714ae2016-09-05 09:57:22 -07001093 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1094 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1095 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1096 InjectRtcpPacket(compound);
1097
1098 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001099}
1100
hta@webrtc.org404843e2012-05-02 09:56:45 +00001101TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001102 // Inject 3 packets "from" kSenderSsrc, kSenderSsrc+1, kSenderSsrc+2.
hta@webrtc.org404843e2012-05-02 09:56:45 +00001103 // The times of arrival are starttime + 0, starttime + 5 and starttime + 10.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001104 for (uint32_t ssrc = kSenderSsrc; ssrc < kSenderSsrc + 3; ++ssrc) {
1105 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001106 tmmbr.SetSenderSsrc(ssrc);
1107 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 30000, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001108 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001109 sr.SetSenderSsrc(ssrc);
danilchap7a4116a2016-03-14 08:19:28 -07001110 rtcp::CompoundPacket compound;
1111 compound.Append(&sr);
1112 compound.Append(&tmmbr);
danilchap1e714ae2016-09-05 09:57:22 -07001113
1114 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1115 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(_));
1116 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1117 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_));
1118 InjectRtcpPacket(compound);
1119
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001120 // 5 seconds between each packet.
1121 system_clock_.AdvanceTimeMilliseconds(5000);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001122 }
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001123 // It is now starttime + 15.
danilchap1e714ae2016-09-05 09:57:22 -07001124 std::vector<rtcp::TmmbItem> candidate_set = rtcp_receiver_.TmmbrReceived();
1125 ASSERT_EQ(3u, candidate_set.size());
1126 EXPECT_EQ(30000U, candidate_set[0].bitrate_bps());
1127
hta@webrtc.org404843e2012-05-02 09:56:45 +00001128 // We expect the timeout to be 25 seconds. Advance the clock by 12
1129 // seconds, timing out the first packet.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001130 system_clock_.AdvanceTimeMilliseconds(12000);
danilchap1e714ae2016-09-05 09:57:22 -07001131 candidate_set = rtcp_receiver_.TmmbrReceived();
1132 ASSERT_EQ(2u, candidate_set.size());
danilchap287e5482016-08-16 15:15:39 -07001133 EXPECT_EQ(kSenderSsrc + 1, candidate_set[0].ssrc());
hta@webrtc.org404843e2012-05-02 09:56:45 +00001134}
1135
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001136TEST_F(RtcpReceiverTest, Callbacks) {
danilchap1e714ae2016-09-05 09:57:22 -07001137 MockRtcpCallbackImpl callback;
1138 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001139
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001140 const uint8_t kFractionLoss = 3;
1141 const uint32_t kCumulativeLoss = 7;
1142 const uint32_t kJitter = 9;
1143 const uint16_t kSequenceNumber = 1234;
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001144
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001145 // First packet, all numbers should just propagate.
1146 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -07001147 rb1.SetMediaSsrc(kReceiverMainSsrc);
1148 rb1.SetExtHighestSeqNum(kSequenceNumber);
1149 rb1.SetFractionLost(kFractionLoss);
1150 rb1.SetCumulativeLost(kCumulativeLoss);
1151 rb1.SetJitter(kJitter);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001152
1153 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -07001154 rr1.SetSenderSsrc(kSenderSsrc);
1155 rr1.AddReportBlock(rb1);
srte186d9c32017-08-04 05:03:53 -07001156 EXPECT_CALL(callback,
1157 StatisticsUpdated(
1158 AllOf(Field(&RtcpStatistics::fraction_lost, kFractionLoss),
1159 Field(&RtcpStatistics::packets_lost, kCumulativeLoss),
1160 Field(&RtcpStatistics::extended_highest_sequence_number,
1161 kSequenceNumber),
1162 Field(&RtcpStatistics::jitter, kJitter)),
1163 kReceiverMainSsrc));
danilchap1e714ae2016-09-05 09:57:22 -07001164 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1165 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1166 InjectRtcpPacket(rr1);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001167
danilchap1e714ae2016-09-05 09:57:22 -07001168 rtcp_receiver_.RegisterRtcpStatisticsCallback(nullptr);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001169
danilchap1e714ae2016-09-05 09:57:22 -07001170 // Add arbitrary numbers, callback should not be called.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001171 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001172 rb2.SetMediaSsrc(kReceiverMainSsrc);
1173 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
1174 rb2.SetFractionLost(42);
1175 rb2.SetCumulativeLost(137);
1176 rb2.SetJitter(4711);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001177
1178 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001179 rr2.SetSenderSsrc(kSenderSsrc);
1180 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001181
1182 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1183 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1184 EXPECT_CALL(callback, StatisticsUpdated(_, _)).Times(0);
1185 InjectRtcpPacket(rr2);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001186}
hta@webrtc.org404843e2012-05-02 09:56:45 +00001187
Henrik Boströmf2047872019-05-16 13:32:20 +02001188TEST_F(RtcpReceiverTest,
1189 VerifyBlockAndTimestampObtainedFromReportBlockDataObserver) {
1190 MockReportBlockDataObserverImpl observer;
1191 rtcp_receiver_.SetReportBlockDataObserver(&observer);
1192
1193 const uint8_t kFractionLoss = 3;
1194 const uint32_t kCumulativeLoss = 7;
1195 const uint32_t kJitter = 9;
1196 const uint16_t kSequenceNumber = 1234;
1197 const int64_t kUtcNowUs = 42;
1198
1199 // The "report_block_timestamp_utc_us" is obtained from the global UTC clock
1200 // (not the simulcated |system_clock_|) and requires a scoped fake clock.
1201 rtc::ScopedFakeClock fake_clock;
1202 fake_clock.SetTime(Timestamp::us(kUtcNowUs));
1203
1204 rtcp::ReportBlock rtcp_block;
1205 rtcp_block.SetMediaSsrc(kReceiverMainSsrc);
1206 rtcp_block.SetExtHighestSeqNum(kSequenceNumber);
1207 rtcp_block.SetFractionLost(kFractionLoss);
1208 rtcp_block.SetCumulativeLost(kCumulativeLoss);
1209 rtcp_block.SetJitter(kJitter);
1210
1211 rtcp::ReceiverReport rtcp_report;
1212 rtcp_report.SetSenderSsrc(kSenderSsrc);
1213 rtcp_report.AddReportBlock(rtcp_block);
1214 EXPECT_CALL(observer, OnReportBlockDataUpdated)
1215 .WillOnce([&](ReportBlockData report_block_data) {
1216 const auto& report_block = report_block_data.report_block();
1217 EXPECT_EQ(rtcp_block.source_ssrc(), report_block.source_ssrc);
1218 EXPECT_EQ(kSenderSsrc, report_block.sender_ssrc);
1219 EXPECT_EQ(rtcp_block.fraction_lost(), report_block.fraction_lost);
1220 EXPECT_EQ(rtcp_block.cumulative_lost_signed(),
1221 report_block.packets_lost);
1222 EXPECT_EQ(rtcp_block.extended_high_seq_num(),
1223 report_block.extended_highest_sequence_number);
1224 EXPECT_EQ(rtcp_block.jitter(), report_block.jitter);
1225 EXPECT_EQ(kUtcNowUs, report_block_data.report_block_timestamp_utc_us());
1226 // No RTT is calculated in this test.
1227 EXPECT_EQ(0u, report_block_data.num_rtts());
1228 });
1229 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1230 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1231 InjectRtcpPacket(rtcp_report);
1232}
1233
1234TEST_F(RtcpReceiverTest, VerifyRttObtainedFromReportBlockDataObserver) {
1235 MockReportBlockDataObserverImpl observer;
1236 rtcp_receiver_.SetReportBlockDataObserver(&observer);
1237
1238 const int64_t kRttMs = 120;
1239 const uint32_t kDelayNtp = 123000;
1240 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
1241
1242 uint32_t sent_ntp =
1243 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
1244 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
1245
1246 rtcp::SenderReport sr;
1247 sr.SetSenderSsrc(kSenderSsrc);
1248 rtcp::ReportBlock block;
1249 block.SetMediaSsrc(kReceiverMainSsrc);
1250 block.SetLastSr(sent_ntp);
1251 block.SetDelayLastSr(kDelayNtp);
1252 sr.AddReportBlock(block);
1253 block.SetMediaSsrc(kReceiverExtraSsrc);
1254 block.SetLastSr(0);
1255 sr.AddReportBlock(block);
1256
1257 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1258 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1259 InSequence sequence;
1260 EXPECT_CALL(observer, OnReportBlockDataUpdated)
1261 .WillOnce([&](ReportBlockData report_block_data) {
1262 EXPECT_EQ(kReceiverMainSsrc,
1263 report_block_data.report_block().source_ssrc);
1264 EXPECT_EQ(1u, report_block_data.num_rtts());
1265 EXPECT_EQ(kRttMs, report_block_data.min_rtt_ms());
1266 EXPECT_EQ(kRttMs, report_block_data.max_rtt_ms());
1267 EXPECT_EQ(kRttMs, report_block_data.sum_rtt_ms());
1268 EXPECT_EQ(kRttMs, report_block_data.last_rtt_ms());
1269 });
1270 EXPECT_CALL(observer, OnReportBlockDataUpdated)
1271 .WillOnce([](ReportBlockData report_block_data) {
1272 EXPECT_EQ(kReceiverExtraSsrc,
1273 report_block_data.report_block().source_ssrc);
1274 EXPECT_EQ(0u, report_block_data.num_rtts());
1275 });
1276 InjectRtcpPacket(sr);
1277}
1278
1279TEST_F(RtcpReceiverTest, GetReportBlockDataAfterOneReportBlock) {
1280 const uint16_t kSequenceNumber = 1234;
1281
1282 rtcp::ReportBlock rtcp_block;
1283 rtcp_block.SetMediaSsrc(kReceiverMainSsrc);
1284 rtcp_block.SetExtHighestSeqNum(kSequenceNumber);
1285
1286 rtcp::ReceiverReport rtcp_report;
1287 rtcp_report.SetSenderSsrc(kSenderSsrc);
1288 rtcp_report.AddReportBlock(rtcp_block);
1289 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1290 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1291 InjectRtcpPacket(rtcp_report);
1292
1293 auto report_block_datas = rtcp_receiver_.GetLatestReportBlockData();
1294 ASSERT_THAT(report_block_datas, SizeIs(1));
1295 EXPECT_EQ(kReceiverMainSsrc,
1296 report_block_datas[0].report_block().source_ssrc);
1297 EXPECT_EQ(
1298 kSequenceNumber,
1299 report_block_datas[0].report_block().extended_highest_sequence_number);
1300}
1301
1302TEST_F(RtcpReceiverTest, GetReportBlockDataAfterTwoReportBlocksOfSameSsrc) {
1303 const uint16_t kSequenceNumber1 = 1234;
1304 const uint16_t kSequenceNumber2 = 1235;
1305
1306 rtcp::ReportBlock rtcp_block1;
1307 rtcp_block1.SetMediaSsrc(kReceiverMainSsrc);
1308 rtcp_block1.SetExtHighestSeqNum(kSequenceNumber1);
1309
1310 rtcp::ReceiverReport rtcp_report1;
1311 rtcp_report1.SetSenderSsrc(kSenderSsrc);
1312 rtcp_report1.AddReportBlock(rtcp_block1);
1313 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1314 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1315 InjectRtcpPacket(rtcp_report1);
1316
1317 // Inject a report block with an increased the sequence number for the same
1318 // source SSRC.
1319 rtcp::ReportBlock rtcp_block2;
1320 rtcp_block2.SetMediaSsrc(kReceiverMainSsrc);
1321 rtcp_block2.SetExtHighestSeqNum(kSequenceNumber2);
1322
1323 rtcp::ReceiverReport rtcp_report2;
1324 rtcp_report2.SetSenderSsrc(kSenderSsrc);
1325 rtcp_report2.AddReportBlock(rtcp_block2);
1326 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1327 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1328 InjectRtcpPacket(rtcp_report2);
1329
1330 // Only the latest block should be returned.
1331 auto report_block_datas = rtcp_receiver_.GetLatestReportBlockData();
1332 ASSERT_THAT(report_block_datas, SizeIs(1));
1333 EXPECT_EQ(kReceiverMainSsrc,
1334 report_block_datas[0].report_block().source_ssrc);
1335 EXPECT_EQ(
1336 kSequenceNumber2,
1337 report_block_datas[0].report_block().extended_highest_sequence_number);
1338}
1339
1340TEST_F(RtcpReceiverTest,
1341 GetReportBlockDataAfterTwoReportBlocksOfDifferentSsrcs) {
1342 const uint16_t kSequenceNumber1 = 1234;
1343 const uint16_t kSequenceNumber2 = 42;
1344
1345 rtcp::ReportBlock rtcp_block1;
1346 rtcp_block1.SetMediaSsrc(kReceiverMainSsrc);
1347 rtcp_block1.SetExtHighestSeqNum(kSequenceNumber1);
1348
1349 rtcp::ReceiverReport rtcp_report1;
1350 rtcp_report1.SetSenderSsrc(kSenderSsrc);
1351 rtcp_report1.AddReportBlock(rtcp_block1);
1352 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1353 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1354 InjectRtcpPacket(rtcp_report1);
1355
1356 // Inject a report block for a different source SSRC.
1357 rtcp::ReportBlock rtcp_block2;
1358 rtcp_block2.SetMediaSsrc(kReceiverExtraSsrc);
1359 rtcp_block2.SetExtHighestSeqNum(kSequenceNumber2);
1360
1361 rtcp::ReceiverReport rtcp_report2;
1362 rtcp_report2.SetSenderSsrc(kSenderSsrc);
1363 rtcp_report2.AddReportBlock(rtcp_block2);
1364 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks);
1365 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport);
1366 InjectRtcpPacket(rtcp_report2);
1367
1368 // Both report blocks should be returned.
1369 auto report_block_datas = rtcp_receiver_.GetLatestReportBlockData();
1370 ASSERT_THAT(report_block_datas, SizeIs(2));
1371 EXPECT_EQ(kReceiverMainSsrc,
1372 report_block_datas[0].report_block().source_ssrc);
1373 EXPECT_EQ(
1374 kSequenceNumber1,
1375 report_block_datas[0].report_block().extended_highest_sequence_number);
1376 EXPECT_EQ(kReceiverExtraSsrc,
1377 report_block_datas[1].report_block().source_ssrc);
1378 EXPECT_EQ(
1379 kSequenceNumber2,
1380 report_block_datas[1].report_block().extended_highest_sequence_number);
1381}
1382
sprang49f9cdb2015-10-01 03:06:57 -07001383TEST_F(RtcpReceiverTest, ReceivesTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001384 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001385 packet.SetMediaSsrc(kReceiverMainSsrc);
1386 packet.SetSenderSsrc(kSenderSsrc);
1387 packet.SetBase(1, 1000);
1388 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001389
danilchap1e714ae2016-09-05 09:57:22 -07001390 EXPECT_CALL(
1391 transport_feedback_observer_,
1392 OnTransportFeedback(AllOf(
1393 Property(&rtcp::TransportFeedback::media_ssrc, kReceiverMainSsrc),
1394 Property(&rtcp::TransportFeedback::sender_ssrc, kSenderSsrc))));
1395 InjectRtcpPacket(packet);
sprang49f9cdb2015-10-01 03:06:57 -07001396}
1397
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001398TEST_F(RtcpReceiverTest, ReceivesRemb) {
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001399 const uint32_t kBitrateBps = 500000;
1400 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001401 remb.SetSenderSsrc(kSenderSsrc);
1402 remb.SetBitrateBps(kBitrateBps);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001403
danilchap1e714ae2016-09-05 09:57:22 -07001404 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1405 InjectRtcpPacket(remb);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001406}
1407
sprang49f9cdb2015-10-01 03:06:57 -07001408TEST_F(RtcpReceiverTest, HandlesInvalidTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001409 // Send a compound packet with a TransportFeedback followed by something else.
1410 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001411 packet.SetMediaSsrc(kReceiverMainSsrc);
1412 packet.SetSenderSsrc(kSenderSsrc);
1413 packet.SetBase(1, 1000);
1414 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001415
1416 static uint32_t kBitrateBps = 50000;
1417 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001418 remb.SetSenderSsrc(kSenderSsrc);
1419 remb.SetBitrateBps(kBitrateBps);
danilchap7a4116a2016-03-14 08:19:28 -07001420 rtcp::CompoundPacket compound;
1421 compound.Append(&packet);
1422 compound.Append(&remb);
1423 rtc::Buffer built_packet = compound.Build();
sprang49f9cdb2015-10-01 03:06:57 -07001424
1425 // Modify the TransportFeedback packet so that it is invalid.
1426 const size_t kStatusCountOffset = 14;
Yves Gerey665174f2018-06-19 15:03:05 +02001427 ByteWriter<uint16_t>::WriteBigEndian(&built_packet.data()[kStatusCountOffset],
1428 42);
sprang49f9cdb2015-10-01 03:06:57 -07001429
danilchap1e714ae2016-09-05 09:57:22 -07001430 // Stress no transport feedback is expected.
1431 EXPECT_CALL(transport_feedback_observer_, OnTransportFeedback(_)).Times(0);
1432 // But remb should be processed and cause a callback
1433 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1434 InjectRtcpPacket(built_packet);
sprang49f9cdb2015-10-01 03:06:57 -07001435}
1436
danilchap1e714ae2016-09-05 09:57:22 -07001437TEST_F(RtcpReceiverTest, Nack) {
1438 const uint16_t kNackList1[] = {1, 2, 3, 5};
danilchap142f0192016-10-20 08:22:42 -07001439 const uint16_t kNackList23[] = {5, 7, 30, 40, 41, 58, 59, 61, 63};
1440 const size_t kNackListLength2 = 4;
1441 const size_t kNackListLength3 = arraysize(kNackList23) - kNackListLength2;
danilchap1e714ae2016-09-05 09:57:22 -07001442 std::set<uint16_t> nack_set;
1443 nack_set.insert(std::begin(kNackList1), std::end(kNackList1));
danilchap142f0192016-10-20 08:22:42 -07001444 nack_set.insert(std::begin(kNackList23), std::end(kNackList23));
danilchap1e714ae2016-09-05 09:57:22 -07001445
danilchap142f0192016-10-20 08:22:42 -07001446 rtcp::Nack nack1;
1447 nack1.SetSenderSsrc(kSenderSsrc);
1448 nack1.SetMediaSsrc(kReceiverMainSsrc);
1449 nack1.SetPacketIds(kNackList1, arraysize(kNackList1));
danilchap1e714ae2016-09-05 09:57:22 -07001450
1451 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList1)));
danilchap1e714ae2016-09-05 09:57:22 -07001452 EXPECT_CALL(packet_type_counter_observer_,
1453 RtcpPacketTypesCounterUpdated(
1454 kReceiverMainSsrc,
1455 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
danilchap142f0192016-10-20 08:22:42 -07001456 arraysize(kNackList1)),
1457 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1458 arraysize(kNackList1)))));
1459 InjectRtcpPacket(nack1);
1460
1461 rtcp::Nack nack2;
1462 nack2.SetSenderSsrc(kSenderSsrc);
1463 nack2.SetMediaSsrc(kReceiverMainSsrc);
1464 nack2.SetPacketIds(kNackList23, kNackListLength2);
1465
1466 rtcp::Nack nack3;
1467 nack3.SetSenderSsrc(kSenderSsrc);
1468 nack3.SetMediaSsrc(kReceiverMainSsrc);
1469 nack3.SetPacketIds(kNackList23 + kNackListLength2, kNackListLength3);
1470
1471 rtcp::CompoundPacket two_nacks;
1472 two_nacks.Append(&nack2);
1473 two_nacks.Append(&nack3);
1474
1475 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList23)));
1476 EXPECT_CALL(packet_type_counter_observer_,
1477 RtcpPacketTypesCounterUpdated(
1478 kReceiverMainSsrc,
1479 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
1480 arraysize(kNackList1) + arraysize(kNackList23)),
danilchap1e714ae2016-09-05 09:57:22 -07001481 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1482 nack_set.size()))));
danilchap142f0192016-10-20 08:22:42 -07001483 InjectRtcpPacket(two_nacks);
danilchap1e714ae2016-09-05 09:57:22 -07001484}
1485
1486TEST_F(RtcpReceiverTest, NackNotForUsIgnored) {
1487 const uint16_t kNackList1[] = {1, 2, 3, 5};
1488 const size_t kNackListLength1 = std::end(kNackList1) - std::begin(kNackList1);
1489
1490 rtcp::Nack nack;
danilchap822a16f2016-09-27 09:27:47 -07001491 nack.SetSenderSsrc(kSenderSsrc);
1492 nack.SetMediaSsrc(kNotToUsSsrc);
1493 nack.SetPacketIds(kNackList1, kNackListLength1);
danilchap1e714ae2016-09-05 09:57:22 -07001494
1495 EXPECT_CALL(packet_type_counter_observer_,
1496 RtcpPacketTypesCounterUpdated(
1497 _, Field(&RtcpPacketTypeCounter::nack_requests, 0)));
1498 InjectRtcpPacket(nack);
1499}
1500
1501TEST_F(RtcpReceiverTest, ForceSenderReport) {
1502 rtcp::RapidResyncRequest rr;
danilchap822a16f2016-09-27 09:27:47 -07001503 rr.SetSenderSsrc(kSenderSsrc);
1504 rr.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -07001505
1506 EXPECT_CALL(rtp_rtcp_impl_, OnRequestSendReport());
1507 InjectRtcpPacket(rr);
1508}
hta@webrtc.org47059b52012-05-02 07:46:22 +00001509
spranga790d832016-12-02 07:29:44 -08001510TEST_F(RtcpReceiverTest, ReceivesTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001511 VideoBitrateAllocation expected_allocation;
spranga790d832016-12-02 07:29:44 -08001512 expected_allocation.SetBitrate(0, 0, 10000);
1513 expected_allocation.SetBitrate(0, 1, 20000);
1514 expected_allocation.SetBitrate(1, 0, 40000);
1515 expected_allocation.SetBitrate(1, 1, 80000);
1516
1517 rtcp::TargetBitrate bitrate;
1518 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1519 bitrate.AddTargetBitrate(0, 1, expected_allocation.GetBitrate(0, 1) / 1000);
1520 bitrate.AddTargetBitrate(1, 0, expected_allocation.GetBitrate(1, 0) / 1000);
1521 bitrate.AddTargetBitrate(1, 1, expected_allocation.GetBitrate(1, 1) / 1000);
1522
1523 rtcp::ExtendedReports xr;
1524 xr.SetTargetBitrate(bitrate);
1525
sprangb32aaf92017-08-28 05:49:12 -07001526 // Wrong sender ssrc, target bitrate should be discarded.
1527 xr.SetSenderSsrc(kSenderSsrc + 1);
1528 EXPECT_CALL(bitrate_allocation_observer_,
1529 OnBitrateAllocationUpdated(expected_allocation))
1530 .Times(0);
1531 InjectRtcpPacket(xr);
1532
1533 // Set correct ssrc, callback should be called once.
1534 xr.SetSenderSsrc(kSenderSsrc);
spranga790d832016-12-02 07:29:44 -08001535 EXPECT_CALL(bitrate_allocation_observer_,
1536 OnBitrateAllocationUpdated(expected_allocation));
1537 InjectRtcpPacket(xr);
1538}
1539
sprang6d314c72016-12-06 06:08:53 -08001540TEST_F(RtcpReceiverTest, HandlesIncorrectTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001541 VideoBitrateAllocation expected_allocation;
sprang6d314c72016-12-06 06:08:53 -08001542 expected_allocation.SetBitrate(0, 0, 10000);
1543
1544 rtcp::TargetBitrate bitrate;
1545 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1546 bitrate.AddTargetBitrate(0, kMaxTemporalStreams, 20000);
1547 bitrate.AddTargetBitrate(kMaxSpatialLayers, 0, 40000);
1548
1549 rtcp::ExtendedReports xr;
1550 xr.SetTargetBitrate(bitrate);
sprangb32aaf92017-08-28 05:49:12 -07001551 xr.SetSenderSsrc(kSenderSsrc);
sprang6d314c72016-12-06 06:08:53 -08001552
1553 EXPECT_CALL(bitrate_allocation_observer_,
1554 OnBitrateAllocationUpdated(expected_allocation));
1555 InjectRtcpPacket(xr);
1556}
1557
hta@webrtc.org47059b52012-05-02 07:46:22 +00001558} // namespace webrtc