blob: 4be8d737509b9f4a98f0301750c63ab317e06aef [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"
Erik Språngeeaa8f92018-05-17 12:35:56 +020014#include "api/video/video_bitrate_allocation.h"
Jiawei Ou4206a0a2018-07-20 15:49:43 -070015#include "api/video/video_bitrate_allocator.h"
Mirko Bonadei71207422017-09-15 13:58:09 +020016#include "common_types.h" // NOLINT(build/include)
Sebastian Janssonef9daee2018-02-22 14:49:02 +010017#include "modules/rtp_rtcp/mocks/mock_rtcp_bandwidth_observer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "modules/rtp_rtcp/source/byte_io.h"
19#include "modules/rtp_rtcp/source/rtcp_packet.h"
20#include "modules/rtp_rtcp/source/rtcp_packet/app.h"
21#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
22#include "modules/rtp_rtcp/source/rtcp_packet/compound_packet.h"
23#include "modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.h"
24#include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
25#include "modules/rtp_rtcp/source/rtcp_packet/fir.h"
26#include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
27#include "modules/rtp_rtcp/source/rtcp_packet/pli.h"
28#include "modules/rtp_rtcp/source/rtcp_packet/rapid_resync_request.h"
29#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
30#include "modules/rtp_rtcp/source/rtcp_packet/remb.h"
31#include "modules/rtp_rtcp/source/rtcp_packet/sdes.h"
32#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
33#include "modules/rtp_rtcp/source/rtcp_packet/tmmbr.h"
34#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
35#include "modules/rtp_rtcp/source/rtcp_receiver.h"
36#include "modules/rtp_rtcp/source/time_util.h"
37#include "rtc_base/arraysize.h"
38#include "rtc_base/random.h"
39#include "system_wrappers/include/ntp_time.h"
40#include "test/gmock.h"
41#include "test/gtest.h"
hta@webrtc.org47059b52012-05-02 07:46:22 +000042
43namespace webrtc {
danilchap1e714ae2016-09-05 09:57:22 -070044namespace {
hta@webrtc.org47059b52012-05-02 07:46:22 +000045
danilchap1e714ae2016-09-05 09:57:22 -070046using ::testing::_;
47using ::testing::AllOf;
48using ::testing::ElementsAreArray;
49using ::testing::Field;
50using ::testing::IsEmpty;
51using ::testing::NiceMock;
52using ::testing::Property;
53using ::testing::SizeIs;
54using ::testing::StrEq;
55using ::testing::StrictMock;
56using ::testing::UnorderedElementsAre;
danilchap80ac24d2016-10-31 08:40:47 -070057using rtcp::ReceiveTimeInfo;
hta@webrtc.org47059b52012-05-02 07:46:22 +000058
danilchap1e714ae2016-09-05 09:57:22 -070059class MockRtcpPacketTypeCounterObserver : public RtcpPacketTypeCounterObserver {
hta@webrtc.org47059b52012-05-02 07:46:22 +000060 public:
danilchap1e714ae2016-09-05 09:57:22 -070061 MOCK_METHOD2(RtcpPacketTypesCounterUpdated,
62 void(uint32_t, const RtcpPacketTypeCounter&));
hta@webrtc.org47059b52012-05-02 07:46:22 +000063};
64
danilchap1e714ae2016-09-05 09:57:22 -070065class MockRtcpIntraFrameObserver : public RtcpIntraFrameObserver {
66 public:
67 MOCK_METHOD1(OnReceivedIntraFrameRequest, void(uint32_t));
danilchap1e714ae2016-09-05 09:57:22 -070068};
69
70class MockRtcpCallbackImpl : public RtcpStatisticsCallback {
71 public:
72 MOCK_METHOD2(StatisticsUpdated, void(const RtcpStatistics&, uint32_t));
73 MOCK_METHOD2(CNameChanged, void(const char*, uint32_t));
74};
75
76class MockTransportFeedbackObserver : public TransportFeedbackObserver {
77 public:
elad.alond12a8e12017-03-23 11:04:48 -070078 MOCK_METHOD3(AddPacket, void(uint32_t, uint16_t, size_t));
79 MOCK_METHOD4(AddPacket,
80 void(uint32_t, uint16_t, size_t, const PacedPacketInfo&));
danilchap1e714ae2016-09-05 09:57:22 -070081 MOCK_METHOD1(OnTransportFeedback, void(const rtcp::TransportFeedback&));
elad.alonf9490002017-03-06 05:32:21 -080082 MOCK_CONST_METHOD0(GetTransportFeedbackVector, std::vector<PacketFeedback>());
danilchap1e714ae2016-09-05 09:57:22 -070083};
84
danilchap1e714ae2016-09-05 09:57:22 -070085class MockModuleRtpRtcp : public RTCPReceiver::ModuleRtpRtcp {
86 public:
87 MOCK_METHOD1(SetTmmbn, void(std::vector<rtcp::TmmbItem>));
88 MOCK_METHOD0(OnRequestSendReport, void());
89 MOCK_METHOD1(OnReceivedNack, void(const std::vector<uint16_t>&));
90 MOCK_METHOD1(OnReceivedRtcpReportBlocks, void(const ReportBlockList&));
91};
92
spranga790d832016-12-02 07:29:44 -080093class MockVideoBitrateAllocationObserver
94 : public VideoBitrateAllocationObserver {
95 public:
96 MOCK_METHOD1(OnBitrateAllocationUpdated,
Erik Språng566124a2018-04-23 12:32:22 +020097 void(const VideoBitrateAllocation& allocation));
spranga790d832016-12-02 07:29:44 -080098};
99
danilchap1e714ae2016-09-05 09:57:22 -0700100// SSRC of remote peer, that sends rtcp packet to the rtcp receiver under test.
101constexpr uint32_t kSenderSsrc = 0x10203;
102// SSRCs of local peer, that rtcp packet addressed to.
103constexpr uint32_t kReceiverMainSsrc = 0x123456;
104// RtcpReceiver can accept several ssrc, e.g. regular and rtx streams.
105constexpr uint32_t kReceiverExtraSsrc = 0x1234567;
106// SSRCs to ignore (i.e. not configured in RtcpReceiver).
107constexpr uint32_t kNotToUsSsrc = 0x654321;
108constexpr uint32_t kUnknownSenderSsrc = 0x54321;
109
110} // namespace
111
hta@webrtc.org47059b52012-05-02 07:46:22 +0000112class RtcpReceiverTest : public ::testing::Test {
113 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000114 RtcpReceiverTest()
danilchap1e714ae2016-09-05 09:57:22 -0700115 : system_clock_(1335900000),
116 rtcp_receiver_(&system_clock_,
117 false,
118 &packet_type_counter_observer_,
119 &bandwidth_observer_,
120 &intra_frame_observer_,
121 &transport_feedback_observer_,
spranga790d832016-12-02 07:29:44 -0800122 &bitrate_allocation_observer_,
danilchap1e714ae2016-09-05 09:57:22 -0700123 &rtp_rtcp_impl_) {}
124 void SetUp() {
125 std::set<uint32_t> ssrcs = {kReceiverMainSsrc, kReceiverExtraSsrc};
danilchap1e714ae2016-09-05 09:57:22 -0700126 rtcp_receiver_.SetSsrcs(kReceiverMainSsrc, ssrcs);
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000127
danilchap1e714ae2016-09-05 09:57:22 -0700128 rtcp_receiver_.SetRemoteSSRC(kSenderSsrc);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000129 }
Erik Språng737336d2016-07-29 12:59:36 +0200130
danilchap1e714ae2016-09-05 09:57:22 -0700131 void InjectRtcpPacket(rtc::ArrayView<const uint8_t> raw) {
132 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
hta@webrtc.org47059b52012-05-02 07:46:22 +0000133 }
134
danilchap1e714ae2016-09-05 09:57:22 -0700135 void InjectRtcpPacket(const rtcp::RtcpPacket& packet) {
136 rtc::Buffer raw = packet.Build();
137 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
138 }
139
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000140 SimulatedClock system_clock_;
danilchap1e714ae2016-09-05 09:57:22 -0700141 // Callbacks to packet_type_counter_observer are frequent but most of the time
142 // are not interesting.
143 NiceMock<MockRtcpPacketTypeCounterObserver> packet_type_counter_observer_;
144 StrictMock<MockRtcpBandwidthObserver> bandwidth_observer_;
145 StrictMock<MockRtcpIntraFrameObserver> intra_frame_observer_;
146 StrictMock<MockTransportFeedbackObserver> transport_feedback_observer_;
spranga790d832016-12-02 07:29:44 -0800147 StrictMock<MockVideoBitrateAllocationObserver> bitrate_allocation_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700148 StrictMock<MockModuleRtpRtcp> rtp_rtcp_impl_;
hta@webrtc.org47059b52012-05-02 07:46:22 +0000149
danilchap1e714ae2016-09-05 09:57:22 -0700150 RTCPReceiver rtcp_receiver_;
151};
hta@webrtc.org47059b52012-05-02 07:46:22 +0000152
153TEST_F(RtcpReceiverTest, BrokenPacketIsIgnored) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000154 const uint8_t bad_packet[] = {0, 0, 0, 0};
danilchap1e714ae2016-09-05 09:57:22 -0700155 EXPECT_CALL(packet_type_counter_observer_,
156 RtcpPacketTypesCounterUpdated(_, _))
157 .Times(0);
158 InjectRtcpPacket(bad_packet);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000159}
160
danilchap50da1d32016-03-10 13:13:52 -0800161TEST_F(RtcpReceiverTest, InvalidFeedbackPacketIsIgnored) {
162 // Too short feedback packet.
danilchap1e714ae2016-09-05 09:57:22 -0700163 const uint8_t bad_packet[] = {0x81, rtcp::Rtpfb::kPacketType, 0, 0};
164
165 // TODO(danilchap): Add expectation RtcpPacketTypesCounterUpdated
166 // is not called once parser would be adjusted to avoid that callback on
167 // semi-valid packets.
168 InjectRtcpPacket(bad_packet);
danilchap50da1d32016-03-10 13:13:52 -0800169}
170
hta@webrtc.org47059b52012-05-02 07:46:22 +0000171TEST_F(RtcpReceiverTest, InjectSrPacket) {
danilchapa04d9c32017-07-25 04:03:39 -0700172 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
danilchap1e714ae2016-09-05 09:57:22 -0700173
174 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000175 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700176 sr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700177
178 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
179 EXPECT_CALL(bandwidth_observer_,
180 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
181 InjectRtcpPacket(sr);
182
danilchapa04d9c32017-07-25 04:03:39 -0700183 EXPECT_TRUE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
hta@webrtc.org47059b52012-05-02 07:46:22 +0000184}
185
danilchap1e714ae2016-09-05 09:57:22 -0700186TEST_F(RtcpReceiverTest, InjectSrPacketFromUnknownSender) {
187 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000188 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700189 sr.SetSenderSsrc(kUnknownSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700190
191 // The parser will handle report blocks in Sender Report from other than his
192 // expected peer.
193 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
194 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, now));
195 InjectRtcpPacket(sr);
196
197 // But will not flag that he's gotten sender information.
danilchapa04d9c32017-07-25 04:03:39 -0700198 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000199}
200
Danil Chapovalova094fd12016-02-22 18:59:36 +0100201TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesRTT) {
202 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100203 const int64_t kRttMs = r.Rand(1, 9 * 3600 * 1000);
204 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
205 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100206
Danil Chapovalova094fd12016-02-22 18:59:36 +0100207 int64_t rtt_ms = 0;
208 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700209 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100210
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200211 uint32_t sent_ntp =
212 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100213 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
214
215 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700216 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100217 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700218 block.SetMediaSsrc(kReceiverMainSsrc);
219 block.SetLastSr(sent_ntp);
220 block.SetDelayLastSr(kDelayNtp);
221 sr.AddReportBlock(block);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100222
danilchap1e714ae2016-09-05 09:57:22 -0700223 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
224 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
225 InjectRtcpPacket(sr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100226
227 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700228 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100229 EXPECT_NEAR(kRttMs, rtt_ms, 1);
230}
231
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100232TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesNegativeRTTAsOne) {
233 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100234 const int64_t kRttMs = r.Rand(-3600 * 1000, -1);
235 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
236 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
237
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100238 int64_t rtt_ms = 0;
239 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700240 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100241
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200242 uint32_t sent_ntp =
243 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100244 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
245
246 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700247 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100248 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700249 block.SetMediaSsrc(kReceiverMainSsrc);
250 block.SetLastSr(sent_ntp);
251 block.SetDelayLastSr(kDelayNtp);
252 sr.AddReportBlock(block);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100253
danilchap1e714ae2016-09-05 09:57:22 -0700254 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
255 EXPECT_CALL(bandwidth_observer_,
256 OnReceivedRtcpReceiverReport(SizeIs(1), _, _));
257 InjectRtcpPacket(sr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100258
259 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700260 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100261 EXPECT_EQ(1, rtt_ms);
262}
263
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100264TEST_F(
265 RtcpReceiverTest,
266 TwoReportBlocksWithLastOneWithoutLastSrCalculatesRttForBandwidthObserver) {
267 const int64_t kRttMs = 120;
268 const uint32_t kDelayNtp = 123000;
269 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
270
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200271 uint32_t sent_ntp =
272 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100273 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
274
275 rtcp::SenderReport sr;
276 sr.SetSenderSsrc(kSenderSsrc);
277 rtcp::ReportBlock block;
278 block.SetMediaSsrc(kReceiverMainSsrc);
279 block.SetLastSr(sent_ntp);
280 block.SetDelayLastSr(kDelayNtp);
281 sr.AddReportBlock(block);
282 block.SetMediaSsrc(kReceiverExtraSsrc);
283 block.SetLastSr(0);
284 sr.AddReportBlock(block);
285
286 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
287 EXPECT_CALL(bandwidth_observer_,
288 OnReceivedRtcpReceiverReport(SizeIs(2), kRttMs, _));
289 InjectRtcpPacket(sr);
290}
291
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000292TEST_F(RtcpReceiverTest, InjectRrPacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700293 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000294 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700295 rr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700296
297 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
298 EXPECT_CALL(bandwidth_observer_,
299 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
300 InjectRtcpPacket(rr);
301
danilchap1e714ae2016-09-05 09:57:22 -0700302 std::vector<RTCPReportBlock> report_blocks;
303 rtcp_receiver_.StatisticsReceived(&report_blocks);
304 EXPECT_TRUE(report_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000305}
306
307TEST_F(RtcpReceiverTest, InjectRrPacketWithReportBlockNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700308 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000309 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700310 rb.SetMediaSsrc(kNotToUsSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000311 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700312 rr.SetSenderSsrc(kSenderSsrc);
313 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000314
danilchap1e714ae2016-09-05 09:57:22 -0700315 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
316 EXPECT_CALL(bandwidth_observer_,
317 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
318 InjectRtcpPacket(rr);
319
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200320 EXPECT_EQ(0, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000321 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700322 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000323 EXPECT_TRUE(received_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000324}
325
326TEST_F(RtcpReceiverTest, InjectRrPacketWithOneReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700327 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000328
329 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700330 rb.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000331 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700332 rr.SetSenderSsrc(kSenderSsrc);
333 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000334
danilchap1e714ae2016-09-05 09:57:22 -0700335 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
336 EXPECT_CALL(bandwidth_observer_,
337 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
338 InjectRtcpPacket(rr);
339
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200340 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
341 std::vector<RTCPReportBlock> received_blocks;
342 rtcp_receiver_.StatisticsReceived(&received_blocks);
343 EXPECT_EQ(1u, received_blocks.size());
344}
345
346TEST_F(RtcpReceiverTest, InjectSrPacketWithOneReportBlock) {
347 int64_t now = system_clock_.TimeInMilliseconds();
348
349 rtcp::ReportBlock rb;
350 rb.SetMediaSsrc(kReceiverMainSsrc);
351 rtcp::SenderReport sr;
352 sr.SetSenderSsrc(kSenderSsrc);
353 sr.AddReportBlock(rb);
354
355 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
356 EXPECT_CALL(bandwidth_observer_,
357 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
358 InjectRtcpPacket(sr);
359
360 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000361 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700362 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000363 EXPECT_EQ(1u, received_blocks.size());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000364}
365
366TEST_F(RtcpReceiverTest, InjectRrPacketWithTwoReportBlocks) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000367 const uint16_t kSequenceNumbers[] = {10, 12423};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000368 const uint32_t kCumLost[] = {13, 555};
369 const uint8_t kFracLost[] = {20, 11};
danilchap1e714ae2016-09-05 09:57:22 -0700370 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000371
372 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700373 rb1.SetMediaSsrc(kReceiverMainSsrc);
374 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
375 rb1.SetFractionLost(10);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000376
377 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700378 rb2.SetMediaSsrc(kReceiverExtraSsrc);
379 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
380 rb2.SetFractionLost(0);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000381
382 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700383 rr1.SetSenderSsrc(kSenderSsrc);
384 rr1.AddReportBlock(rb1);
385 rr1.AddReportBlock(rb2);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000386
danilchap1e714ae2016-09-05 09:57:22 -0700387 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
388 EXPECT_CALL(bandwidth_observer_,
389 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
390 InjectRtcpPacket(rr1);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000391
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200392 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700393 std::vector<RTCPReportBlock> received_blocks;
394 rtcp_receiver_.StatisticsReceived(&received_blocks);
395 EXPECT_THAT(received_blocks,
srte3e69e5c2017-08-09 06:13:45 -0700396 UnorderedElementsAre(Field(&RTCPReportBlock::fraction_lost, 0),
397 Field(&RTCPReportBlock::fraction_lost, 10)));
danilchap1e714ae2016-09-05 09:57:22 -0700398
399 // Insert next receiver report with same ssrc but new values.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000400 rtcp::ReportBlock rb3;
danilchap822a16f2016-09-27 09:27:47 -0700401 rb3.SetMediaSsrc(kReceiverMainSsrc);
402 rb3.SetExtHighestSeqNum(kSequenceNumbers[0]);
403 rb3.SetFractionLost(kFracLost[0]);
404 rb3.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000405
406 rtcp::ReportBlock rb4;
danilchap822a16f2016-09-27 09:27:47 -0700407 rb4.SetMediaSsrc(kReceiverExtraSsrc);
408 rb4.SetExtHighestSeqNum(kSequenceNumbers[1]);
409 rb4.SetFractionLost(kFracLost[1]);
410 rb4.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000411
412 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700413 rr2.SetSenderSsrc(kSenderSsrc);
414 rr2.AddReportBlock(rb3);
415 rr2.AddReportBlock(rb4);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000416
danilchap1e714ae2016-09-05 09:57:22 -0700417 // Advance time to make 1st sent time and 2nd sent time different.
418 system_clock_.AdvanceTimeMilliseconds(500);
419 now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000420
danilchap1e714ae2016-09-05 09:57:22 -0700421 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
422 EXPECT_CALL(bandwidth_observer_,
423 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
424 InjectRtcpPacket(rr2);
425
426 received_blocks.clear();
427 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000428 EXPECT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700429 EXPECT_THAT(
430 received_blocks,
431 UnorderedElementsAre(
432 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
433 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
434 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
435 Field(&RTCPReportBlock::extended_highest_sequence_number,
436 kSequenceNumbers[0])),
437 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverExtraSsrc),
438 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
439 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
440 Field(&RTCPReportBlock::extended_highest_sequence_number,
441 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000442}
443
444TEST_F(RtcpReceiverTest, InjectRrPacketsFromTwoRemoteSsrcs) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000445 const uint32_t kSenderSsrc2 = 0x20304;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000446 const uint16_t kSequenceNumbers[] = {10, 12423};
Sebastian Jansson9701e0c2018-08-09 11:21:11 +0200447 const int32_t kCumLost[] = {13, 555};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000448 const uint8_t kFracLost[] = {20, 11};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000449
450 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700451 rb1.SetMediaSsrc(kReceiverMainSsrc);
452 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
453 rb1.SetFractionLost(kFracLost[0]);
454 rb1.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000455 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700456 rr1.SetSenderSsrc(kSenderSsrc);
457 rr1.AddReportBlock(rb1);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000458
danilchap1e714ae2016-09-05 09:57:22 -0700459 int64_t now = system_clock_.TimeInMilliseconds();
460
461 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
462 EXPECT_CALL(bandwidth_observer_,
463 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
464 InjectRtcpPacket(rr1);
465
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200466 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000467
468 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700469 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000470 EXPECT_EQ(1u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700471 EXPECT_EQ(kSenderSsrc, received_blocks[0].sender_ssrc);
472 EXPECT_EQ(kReceiverMainSsrc, received_blocks[0].source_ssrc);
473 EXPECT_EQ(kFracLost[0], received_blocks[0].fraction_lost);
474 EXPECT_EQ(kCumLost[0], received_blocks[0].packets_lost);
475 EXPECT_EQ(kSequenceNumbers[0],
476 received_blocks[0].extended_highest_sequence_number);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000477
478 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700479 rb2.SetMediaSsrc(kReceiverMainSsrc);
480 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
481 rb2.SetFractionLost(kFracLost[1]);
482 rb2.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000483 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700484 rr2.SetSenderSsrc(kSenderSsrc2);
485 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -0700486
487 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
488 EXPECT_CALL(bandwidth_observer_,
489 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
490 InjectRtcpPacket(rr2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000491
492 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700493 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000494 ASSERT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700495 EXPECT_THAT(
496 received_blocks,
497 UnorderedElementsAre(
498 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
499 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc),
500 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
501 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
502 Field(&RTCPReportBlock::extended_highest_sequence_number,
503 kSequenceNumbers[0])),
504 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
505 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc2),
506 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
507 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
508 Field(&RTCPReportBlock::extended_highest_sequence_number,
509 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000510}
511
512TEST_F(RtcpReceiverTest, GetRtt) {
danilchap28b03eb2016-10-05 06:59:44 -0700513 const uint32_t kSentCompactNtp = 0x1234;
514 const uint32_t kDelayCompactNtp = 0x222;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000515 // No report block received.
Erik Språng6b8d3552015-09-24 15:06:57 +0200516 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700517 -1, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000518
519 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700520 rb.SetMediaSsrc(kReceiverMainSsrc);
danilchap28b03eb2016-10-05 06:59:44 -0700521 rb.SetLastSr(kSentCompactNtp);
522 rb.SetDelayLastSr(kDelayCompactNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700523
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000524 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700525 rr.SetSenderSsrc(kSenderSsrc);
526 rr.AddReportBlock(rb);
danilchap1e714ae2016-09-05 09:57:22 -0700527 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000528
danilchap1e714ae2016-09-05 09:57:22 -0700529 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
530 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
531 InjectRtcpPacket(rr);
532
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200533 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700534 EXPECT_EQ(
535 0, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000536}
537
danilchap1e714ae2016-09-05 09:57:22 -0700538// Ij packets are ignored.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000539TEST_F(RtcpReceiverTest, InjectIjWithNoItem) {
danilchapf8506cb2015-11-13 07:33:20 -0800540 rtcp::ExtendedJitterReport ij;
danilchap1e714ae2016-09-05 09:57:22 -0700541 InjectRtcpPacket(ij);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000542}
543
danilchap1e714ae2016-09-05 09:57:22 -0700544// App packets are ignored.
545TEST_F(RtcpReceiverTest, InjectApp) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000546 rtcp::App app;
danilchap822a16f2016-09-27 09:27:47 -0700547 app.SetSubType(30);
548 app.SetName(0x17a177e);
danilchap1e714ae2016-09-05 09:57:22 -0700549 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
danilchap822a16f2016-09-27 09:27:47 -0700550 app.SetData(kData, sizeof(kData));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000551
danilchap1e714ae2016-09-05 09:57:22 -0700552 InjectRtcpPacket(app);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000553}
554
555TEST_F(RtcpReceiverTest, InjectSdesWithOneChunk) {
danilchap1e714ae2016-09-05 09:57:22 -0700556 const char kCname[] = "alice@host";
557 MockRtcpCallbackImpl callback;
558 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000559 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700560 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000561
danilchap1e714ae2016-09-05 09:57:22 -0700562 EXPECT_CALL(callback, CNameChanged(StrEq(kCname), kSenderSsrc));
563 InjectRtcpPacket(sdes);
564
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000565 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700566 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
567 EXPECT_EQ(0, strncmp(cName, kCname, RTCP_CNAME_SIZE));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000568}
569
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000570TEST_F(RtcpReceiverTest, InjectByePacket_RemovesCname) {
danilchap1e714ae2016-09-05 09:57:22 -0700571 const char kCname[] = "alice@host";
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000572 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700573 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000574
danilchap1e714ae2016-09-05 09:57:22 -0700575 InjectRtcpPacket(sdes);
576
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000577 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700578 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000579
580 // Verify that BYE removes the CNAME.
581 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700582 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700583
584 InjectRtcpPacket(bye);
585
586 EXPECT_EQ(-1, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000587}
588
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000589TEST_F(RtcpReceiverTest, InjectByePacket_RemovesReportBlocks) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000590 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700591 rb1.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000592 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700593 rb2.SetMediaSsrc(kReceiverExtraSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000594 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700595 rr.SetSenderSsrc(kSenderSsrc);
596 rr.AddReportBlock(rb1);
597 rr.AddReportBlock(rb2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000598
danilchap1e714ae2016-09-05 09:57:22 -0700599 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
600 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
601 InjectRtcpPacket(rr);
602
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000603 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700604 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000605 EXPECT_EQ(2u, received_blocks.size());
606
607 // Verify that BYE removes the report blocks.
608 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700609 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700610
611 InjectRtcpPacket(bye);
612
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000613 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700614 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000615 EXPECT_TRUE(received_blocks.empty());
616
danilchap1e714ae2016-09-05 09:57:22 -0700617 // Inject packet again.
618 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
619 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
620 InjectRtcpPacket(rr);
621
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000622 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700623 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000624 EXPECT_EQ(2u, received_blocks.size());
625}
626
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200627TEST_F(RtcpReceiverTest, InjectByePacketRemovesReferenceTimeInfo) {
628 rtcp::ExtendedReports xr;
629 xr.SetSenderSsrc(kSenderSsrc);
630 rtcp::Rrtr rrtr;
631 rrtr.SetNtp(NtpTime(0x10203, 0x40506));
632 xr.SetRrtr(rrtr);
633 InjectRtcpPacket(xr);
634
635 rtcp::Bye bye;
636 bye.SetSenderSsrc(kSenderSsrc);
637 InjectRtcpPacket(bye);
638
639 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
640}
641
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000642TEST_F(RtcpReceiverTest, InjectPliPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000643 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700644 pli.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700645
646 EXPECT_CALL(
647 packet_type_counter_observer_,
648 RtcpPacketTypesCounterUpdated(
649 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 1)));
650 EXPECT_CALL(intra_frame_observer_,
651 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
652 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000653}
654
655TEST_F(RtcpReceiverTest, PliPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000656 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700657 pli.SetMediaSsrc(kNotToUsSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700658
659 EXPECT_CALL(
660 packet_type_counter_observer_,
661 RtcpPacketTypesCounterUpdated(
662 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 0)));
663 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
664 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000665}
666
667TEST_F(RtcpReceiverTest, InjectFirPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000668 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700669 fir.AddRequestTo(kReceiverMainSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700670
671 EXPECT_CALL(
672 packet_type_counter_observer_,
673 RtcpPacketTypesCounterUpdated(
674 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::fir_packets, 1)));
675 EXPECT_CALL(intra_frame_observer_,
676 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
677 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000678}
679
680TEST_F(RtcpReceiverTest, FirPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000681 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700682 fir.AddRequestTo(kNotToUsSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700683
684 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
685 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000686}
687
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100688TEST_F(RtcpReceiverTest, ExtendedReportsPacketWithZeroReportBlocksIgnored) {
689 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700690 xr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700691
692 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000693}
694
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100695TEST_F(RtcpReceiverTest, InjectExtendedReportsReceiverReferenceTimePacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700696 const NtpTime kNtp(0x10203, 0x40506);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000697 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700698 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100699 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700700 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700701 xr.SetRrtr(rrtr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000702
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200703 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
704 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
705 EXPECT_THAT(last_xr_rtis, IsEmpty());
danilchap1e714ae2016-09-05 09:57:22 -0700706
707 InjectRtcpPacket(xr);
708
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200709 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
710 ASSERT_THAT(last_xr_rtis, SizeIs(1));
711 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
712 EXPECT_EQ(CompactNtp(kNtp), last_xr_rtis[0].last_rr);
713 EXPECT_EQ(0U, last_xr_rtis[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000714}
715
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100716TEST_F(RtcpReceiverTest, ExtendedReportsDlrrPacketNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700717 // Allow calculate rtt using dlrr/rrtr, simulating media receiver side.
718 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000719
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.AddDlrrItem(ReceiveTimeInfo(kNotToUsSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700723
724 InjectRtcpPacket(xr);
725
726 int64_t rtt_ms = 0;
727 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000728}
729
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100730TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithSubBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700731 const uint32_t kLastRR = 0x12345;
732 const uint32_t kDelay = 0x23456;
733 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
734 int64_t rtt_ms = 0;
735 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000736
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100737 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700738 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700739 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
danilchap1e714ae2016-09-05 09:57:22 -0700740
741 InjectRtcpPacket(xr);
742
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200743 uint32_t compact_ntp_now =
744 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700745 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
746 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
747 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000748}
749
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100750TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithMultipleSubBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700751 const uint32_t kLastRR = 0x12345;
752 const uint32_t kDelay = 0x56789;
753 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000754
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100755 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700756 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700757 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
758 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 1, 0x12345, 0x67890));
759 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 2, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700760
761 InjectRtcpPacket(xr);
762
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200763 uint32_t compact_ntp_now =
764 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700765 int64_t rtt_ms = 0;
766 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, InjectExtendedReportsPacketWithMultipleReportBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700772 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000773
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000774 rtcp::Rrtr rrtr;
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100775 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700776 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700777 xr.SetRrtr(rrtr);
778 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700779
780 InjectRtcpPacket(xr);
781
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200782 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
783 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
784 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700785 int64_t rtt_ms = 0;
786 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000787}
788
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100789TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithUnknownReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700790 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000791
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000792 rtcp::Rrtr rrtr;
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100793 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700794 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700795 xr.SetRrtr(rrtr);
796 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700797
danilchap69e59e62016-02-17 03:11:42 -0800798 rtc::Buffer packet = xr.Build();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000799 // Modify the DLRR block to have an unsupported block type, from 5 to 6.
danilchap1e714ae2016-09-05 09:57:22 -0700800 ASSERT_EQ(5, packet.data()[20]);
801 packet.data()[20] = 6;
802 InjectRtcpPacket(packet);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000803
danilchap1e714ae2016-09-05 09:57:22 -0700804 // Validate Rrtr was received and processed.
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200805 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
806 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
807 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700808 // Validate Dlrr report wasn't processed.
809 int64_t rtt_ms = 0;
810 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000811}
812
danilchap1e714ae2016-09-05 09:57:22 -0700813TEST_F(RtcpReceiverTest, TestExtendedReportsRrRttInitiallyFalse) {
814 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
815
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000816 int64_t rtt_ms;
danilchap1e714ae2016-09-05 09:57:22 -0700817 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000818}
819
danilchap1e714ae2016-09-05 09:57:22 -0700820TEST_F(RtcpReceiverTest, RttCalculatedAfterExtendedReportsDlrr) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100821 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100822 const int64_t kRttMs = rand.Rand(1, 9 * 3600 * 1000);
823 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
824 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700825 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200826 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalova094fd12016-02-22 18:59:36 +0100827 uint32_t sent_ntp = CompactNtp(now);
828 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
829
Danil Chapovalova094fd12016-02-22 18:59:36 +0100830 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700831 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700832 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700833
834 InjectRtcpPacket(xr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100835
836 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700837 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100838 EXPECT_NEAR(kRttMs, rtt_ms, 1);
839}
840
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100841TEST_F(RtcpReceiverTest, XrDlrrCalculatesNegativeRttAsOne) {
842 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100843 const int64_t kRttMs = rand.Rand(-3600 * 1000, -1);
844 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
845 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200846 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100847 uint32_t sent_ntp = CompactNtp(now);
848 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
danilchap1e714ae2016-09-05 09:57:22 -0700849 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100850
Danil Chapovalovc1e55c72016-03-09 15:14:35 +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 Chapovalovc1e55c72016-03-09 15:14:35 +0100856
857 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700858 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100859 EXPECT_EQ(1, rtt_ms);
860}
861
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200862TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfoInitiallyEmpty) {
863 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000864}
865
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200866TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfo) {
Danil Chapovalovfc47ed62015-12-07 14:46:35 +0100867 const NtpTime kNtp(0x10203, 0x40506);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100868 const uint32_t kNtpMid = CompactNtp(kNtp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000869
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000870 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700871 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100872 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700873 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700874 xr.SetRrtr(rrtr);
danilchap1e714ae2016-09-05 09:57:22 -0700875
876 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000877
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000878 system_clock_.AdvanceTimeMilliseconds(1000);
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200879
880 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
881 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
882 ASSERT_THAT(last_xr_rtis, SizeIs(1));
883 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
884 EXPECT_EQ(kNtpMid, last_xr_rtis[0].last_rr);
885 EXPECT_EQ(65536U, last_xr_rtis[0].delay_since_last_rr);
886}
887
888TEST_F(RtcpReceiverTest,
889 ReceivedRrtrFromSameSsrcUpdatesReceivedReferenceTimeInfo) {
890 const NtpTime kNtp1(0x10203, 0x40506);
891 const NtpTime kNtp2(0x11223, 0x44556);
892 const int64_t kDelayMs = 2000;
893
894 rtcp::ExtendedReports xr;
895 xr.SetSenderSsrc(kSenderSsrc);
896 rtcp::Rrtr rrtr1;
897 rrtr1.SetNtp(kNtp1);
898 xr.SetRrtr(rrtr1);
899 InjectRtcpPacket(xr);
900 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
901 rtcp::Rrtr rrtr2;
902 rrtr2.SetNtp(kNtp2);
903 xr.SetRrtr(rrtr2);
904 InjectRtcpPacket(xr);
905 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
906
907 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
908 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
909 ASSERT_THAT(last_xr_rtis, SizeIs(1));
910 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
911 EXPECT_EQ(CompactNtp(kNtp2), last_xr_rtis[0].last_rr);
912 EXPECT_EQ(kDelayMs * 65536 / 1000, last_xr_rtis[0].delay_since_last_rr);
913}
914
915TEST_F(RtcpReceiverTest, StoresLastReceivedRrtrPerSsrc) {
916 const size_t kNumBufferedReports = 1;
917 const size_t kNumReports =
918 rtcp::ExtendedReports::kMaxNumberOfDlrrItems + kNumBufferedReports;
919 for (size_t i = 0; i < kNumReports; ++i) {
920 rtcp::ExtendedReports xr;
921 xr.SetSenderSsrc(i * 100);
922 rtcp::Rrtr rrtr;
923 rrtr.SetNtp(NtpTime(i * 200, i * 300));
924 xr.SetRrtr(rrtr);
925 InjectRtcpPacket(xr);
926 system_clock_.AdvanceTimeMilliseconds(1000);
927 }
928
929 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
930 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
931 ASSERT_THAT(last_xr_rtis,
932 SizeIs(rtcp::ExtendedReports::kMaxNumberOfDlrrItems));
933 for (size_t i = 0; i < rtcp::ExtendedReports::kMaxNumberOfDlrrItems; ++i) {
934 EXPECT_EQ(i * 100, last_xr_rtis[i].ssrc);
935 EXPECT_EQ(CompactNtp(NtpTime(i * 200, i * 300)), last_xr_rtis[i].last_rr);
936 EXPECT_EQ(65536U * (kNumReports - i), last_xr_rtis[i].delay_since_last_rr);
937 }
938
939 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
940 ASSERT_THAT(last_xr_rtis, SizeIs(kNumBufferedReports));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000941}
942
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000943TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000944 const int64_t kRtcpIntervalMs = 1000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000945 const uint16_t kSequenceNumber = 1234;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000946 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000947
948 // No RR received, shouldn't trigger a timeout.
danilchap1e714ae2016-09-05 09:57:22 -0700949 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
950 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000951
952 // Add a RR and advance the clock just enough to not trigger a timeout.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000953 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700954 rb1.SetMediaSsrc(kReceiverMainSsrc);
955 rb1.SetExtHighestSeqNum(kSequenceNumber);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000956 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700957 rr1.SetSenderSsrc(kSenderSsrc);
958 rr1.AddReportBlock(rb1);
danilchap1e714ae2016-09-05 09:57:22 -0700959
960 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
961 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
962 InjectRtcpPacket(rr1);
963
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000964 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs - 1);
danilchap1e714ae2016-09-05 09:57:22 -0700965 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
966 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000967
968 // Add a RR with the same extended max as the previous RR to trigger a
969 // sequence number timeout, but not a RR timeout.
danilchap1e714ae2016-09-05 09:57:22 -0700970 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
971 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
972 InjectRtcpPacket(rr1);
973
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000974 system_clock_.AdvanceTimeMilliseconds(2);
danilchap1e714ae2016-09-05 09:57:22 -0700975 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
976 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000977
978 // Advance clock enough to trigger an RR timeout too.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000979 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -0700980 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000981
982 // We should only get one timeout even though we still haven't received a new
983 // RR.
danilchap1e714ae2016-09-05 09:57:22 -0700984 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
985 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000986
987 // Add a new RR with increase sequence number to reset timers.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000988 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700989 rb2.SetMediaSsrc(kReceiverMainSsrc);
990 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000991 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700992 rr2.SetSenderSsrc(kSenderSsrc);
993 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -0700994
995 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
996 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
997 InjectRtcpPacket(rr2);
998
999 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
1000 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001001
1002 // Verify we can get a timeout again once we've received new RR.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001003 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -07001004 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1005 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1006 InjectRtcpPacket(rr2);
1007
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001008 system_clock_.AdvanceTimeMilliseconds(kRtcpIntervalMs + 1);
danilchap1e714ae2016-09-05 09:57:22 -07001009 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
1010 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
1011
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001012 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -07001013 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001014}
1015
hta@webrtc.org47059b52012-05-02 07:46:22 +00001016TEST_F(RtcpReceiverTest, TmmbrReceivedWithNoIncomingPacket) {
danilchap1e714ae2016-09-05 09:57:22 -07001017 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001018}
1019
1020TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) {
danilchap1e714ae2016-09-05 09:57:22 -07001021 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001022 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001023 tmmbr.SetSenderSsrc(kSenderSsrc);
1024 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001025 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001026 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001027 rtcp::CompoundPacket compound;
1028 compound.Append(&sr);
1029 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001030
danilchap1e714ae2016-09-05 09:57:22 -07001031 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1032 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(SizeIs(1)));
1033 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1034 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1035 InjectRtcpPacket(compound);
1036
1037 std::vector<rtcp::TmmbItem> tmmbr_received = rtcp_receiver_.TmmbrReceived();
1038 ASSERT_EQ(1u, tmmbr_received.size());
1039 EXPECT_EQ(kBitrateBps, tmmbr_received[0].bitrate_bps());
1040 EXPECT_EQ(kSenderSsrc, tmmbr_received[0].ssrc());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001041}
1042
1043TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -07001044 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001045 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001046 tmmbr.SetSenderSsrc(kSenderSsrc);
1047 tmmbr.AddTmmbr(rtcp::TmmbItem(kNotToUsSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001048
1049 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001050 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001051 rtcp::CompoundPacket compound;
1052 compound.Append(&sr);
1053 compound.Append(&tmmbr);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001054
danilchap1e714ae2016-09-05 09:57:22 -07001055 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1056 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1057 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1058 InjectRtcpPacket(compound);
1059
1060 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001061}
1062
1063TEST_F(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001064 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001065 tmmbr.SetSenderSsrc(kSenderSsrc);
1066 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 0, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001067 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001068 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001069 rtcp::CompoundPacket compound;
1070 compound.Append(&sr);
1071 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001072
danilchap1e714ae2016-09-05 09:57:22 -07001073 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1074 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1075 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1076 InjectRtcpPacket(compound);
1077
1078 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001079}
1080
hta@webrtc.org404843e2012-05-02 09:56:45 +00001081TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001082 // Inject 3 packets "from" kSenderSsrc, kSenderSsrc+1, kSenderSsrc+2.
hta@webrtc.org404843e2012-05-02 09:56:45 +00001083 // The times of arrival are starttime + 0, starttime + 5 and starttime + 10.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001084 for (uint32_t ssrc = kSenderSsrc; ssrc < kSenderSsrc + 3; ++ssrc) {
1085 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001086 tmmbr.SetSenderSsrc(ssrc);
1087 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 30000, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001088 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001089 sr.SetSenderSsrc(ssrc);
danilchap7a4116a2016-03-14 08:19:28 -07001090 rtcp::CompoundPacket compound;
1091 compound.Append(&sr);
1092 compound.Append(&tmmbr);
danilchap1e714ae2016-09-05 09:57:22 -07001093
1094 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1095 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(_));
1096 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1097 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_));
1098 InjectRtcpPacket(compound);
1099
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001100 // 5 seconds between each packet.
1101 system_clock_.AdvanceTimeMilliseconds(5000);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001102 }
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001103 // It is now starttime + 15.
danilchap1e714ae2016-09-05 09:57:22 -07001104 std::vector<rtcp::TmmbItem> candidate_set = rtcp_receiver_.TmmbrReceived();
1105 ASSERT_EQ(3u, candidate_set.size());
1106 EXPECT_EQ(30000U, candidate_set[0].bitrate_bps());
1107
hta@webrtc.org404843e2012-05-02 09:56:45 +00001108 // We expect the timeout to be 25 seconds. Advance the clock by 12
1109 // seconds, timing out the first packet.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001110 system_clock_.AdvanceTimeMilliseconds(12000);
danilchap1e714ae2016-09-05 09:57:22 -07001111 candidate_set = rtcp_receiver_.TmmbrReceived();
1112 ASSERT_EQ(2u, candidate_set.size());
danilchap287e5482016-08-16 15:15:39 -07001113 EXPECT_EQ(kSenderSsrc + 1, candidate_set[0].ssrc());
hta@webrtc.org404843e2012-05-02 09:56:45 +00001114}
1115
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001116TEST_F(RtcpReceiverTest, Callbacks) {
danilchap1e714ae2016-09-05 09:57:22 -07001117 MockRtcpCallbackImpl callback;
1118 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001119
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001120 const uint8_t kFractionLoss = 3;
1121 const uint32_t kCumulativeLoss = 7;
1122 const uint32_t kJitter = 9;
1123 const uint16_t kSequenceNumber = 1234;
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001124
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001125 // First packet, all numbers should just propagate.
1126 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -07001127 rb1.SetMediaSsrc(kReceiverMainSsrc);
1128 rb1.SetExtHighestSeqNum(kSequenceNumber);
1129 rb1.SetFractionLost(kFractionLoss);
1130 rb1.SetCumulativeLost(kCumulativeLoss);
1131 rb1.SetJitter(kJitter);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001132
1133 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -07001134 rr1.SetSenderSsrc(kSenderSsrc);
1135 rr1.AddReportBlock(rb1);
srte186d9c32017-08-04 05:03:53 -07001136 EXPECT_CALL(callback,
1137 StatisticsUpdated(
1138 AllOf(Field(&RtcpStatistics::fraction_lost, kFractionLoss),
1139 Field(&RtcpStatistics::packets_lost, kCumulativeLoss),
1140 Field(&RtcpStatistics::extended_highest_sequence_number,
1141 kSequenceNumber),
1142 Field(&RtcpStatistics::jitter, kJitter)),
1143 kReceiverMainSsrc));
danilchap1e714ae2016-09-05 09:57:22 -07001144 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1145 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1146 InjectRtcpPacket(rr1);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001147
danilchap1e714ae2016-09-05 09:57:22 -07001148 rtcp_receiver_.RegisterRtcpStatisticsCallback(nullptr);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001149
danilchap1e714ae2016-09-05 09:57:22 -07001150 // Add arbitrary numbers, callback should not be called.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001151 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001152 rb2.SetMediaSsrc(kReceiverMainSsrc);
1153 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
1154 rb2.SetFractionLost(42);
1155 rb2.SetCumulativeLost(137);
1156 rb2.SetJitter(4711);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001157
1158 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001159 rr2.SetSenderSsrc(kSenderSsrc);
1160 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001161
1162 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1163 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1164 EXPECT_CALL(callback, StatisticsUpdated(_, _)).Times(0);
1165 InjectRtcpPacket(rr2);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001166}
hta@webrtc.org404843e2012-05-02 09:56:45 +00001167
sprang49f9cdb2015-10-01 03:06:57 -07001168TEST_F(RtcpReceiverTest, ReceivesTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001169 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001170 packet.SetMediaSsrc(kReceiverMainSsrc);
1171 packet.SetSenderSsrc(kSenderSsrc);
1172 packet.SetBase(1, 1000);
1173 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001174
danilchap1e714ae2016-09-05 09:57:22 -07001175 EXPECT_CALL(
1176 transport_feedback_observer_,
1177 OnTransportFeedback(AllOf(
1178 Property(&rtcp::TransportFeedback::media_ssrc, kReceiverMainSsrc),
1179 Property(&rtcp::TransportFeedback::sender_ssrc, kSenderSsrc))));
1180 InjectRtcpPacket(packet);
sprang49f9cdb2015-10-01 03:06:57 -07001181}
1182
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001183TEST_F(RtcpReceiverTest, ReceivesRemb) {
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001184 const uint32_t kBitrateBps = 500000;
1185 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001186 remb.SetSenderSsrc(kSenderSsrc);
1187 remb.SetBitrateBps(kBitrateBps);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001188
danilchap1e714ae2016-09-05 09:57:22 -07001189 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1190 InjectRtcpPacket(remb);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001191}
1192
sprang49f9cdb2015-10-01 03:06:57 -07001193TEST_F(RtcpReceiverTest, HandlesInvalidTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001194 // Send a compound packet with a TransportFeedback followed by something else.
1195 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001196 packet.SetMediaSsrc(kReceiverMainSsrc);
1197 packet.SetSenderSsrc(kSenderSsrc);
1198 packet.SetBase(1, 1000);
1199 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001200
1201 static uint32_t kBitrateBps = 50000;
1202 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001203 remb.SetSenderSsrc(kSenderSsrc);
1204 remb.SetBitrateBps(kBitrateBps);
danilchap7a4116a2016-03-14 08:19:28 -07001205 rtcp::CompoundPacket compound;
1206 compound.Append(&packet);
1207 compound.Append(&remb);
1208 rtc::Buffer built_packet = compound.Build();
sprang49f9cdb2015-10-01 03:06:57 -07001209
1210 // Modify the TransportFeedback packet so that it is invalid.
1211 const size_t kStatusCountOffset = 14;
Yves Gerey665174f2018-06-19 15:03:05 +02001212 ByteWriter<uint16_t>::WriteBigEndian(&built_packet.data()[kStatusCountOffset],
1213 42);
sprang49f9cdb2015-10-01 03:06:57 -07001214
danilchap1e714ae2016-09-05 09:57:22 -07001215 // Stress no transport feedback is expected.
1216 EXPECT_CALL(transport_feedback_observer_, OnTransportFeedback(_)).Times(0);
1217 // But remb should be processed and cause a callback
1218 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1219 InjectRtcpPacket(built_packet);
sprang49f9cdb2015-10-01 03:06:57 -07001220}
1221
danilchap1e714ae2016-09-05 09:57:22 -07001222TEST_F(RtcpReceiverTest, Nack) {
1223 const uint16_t kNackList1[] = {1, 2, 3, 5};
danilchap142f0192016-10-20 08:22:42 -07001224 const uint16_t kNackList23[] = {5, 7, 30, 40, 41, 58, 59, 61, 63};
1225 const size_t kNackListLength2 = 4;
1226 const size_t kNackListLength3 = arraysize(kNackList23) - kNackListLength2;
danilchap1e714ae2016-09-05 09:57:22 -07001227 std::set<uint16_t> nack_set;
1228 nack_set.insert(std::begin(kNackList1), std::end(kNackList1));
danilchap142f0192016-10-20 08:22:42 -07001229 nack_set.insert(std::begin(kNackList23), std::end(kNackList23));
danilchap1e714ae2016-09-05 09:57:22 -07001230
danilchap142f0192016-10-20 08:22:42 -07001231 rtcp::Nack nack1;
1232 nack1.SetSenderSsrc(kSenderSsrc);
1233 nack1.SetMediaSsrc(kReceiverMainSsrc);
1234 nack1.SetPacketIds(kNackList1, arraysize(kNackList1));
danilchap1e714ae2016-09-05 09:57:22 -07001235
1236 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList1)));
danilchap1e714ae2016-09-05 09:57:22 -07001237 EXPECT_CALL(packet_type_counter_observer_,
1238 RtcpPacketTypesCounterUpdated(
1239 kReceiverMainSsrc,
1240 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
danilchap142f0192016-10-20 08:22:42 -07001241 arraysize(kNackList1)),
1242 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1243 arraysize(kNackList1)))));
1244 InjectRtcpPacket(nack1);
1245
1246 rtcp::Nack nack2;
1247 nack2.SetSenderSsrc(kSenderSsrc);
1248 nack2.SetMediaSsrc(kReceiverMainSsrc);
1249 nack2.SetPacketIds(kNackList23, kNackListLength2);
1250
1251 rtcp::Nack nack3;
1252 nack3.SetSenderSsrc(kSenderSsrc);
1253 nack3.SetMediaSsrc(kReceiverMainSsrc);
1254 nack3.SetPacketIds(kNackList23 + kNackListLength2, kNackListLength3);
1255
1256 rtcp::CompoundPacket two_nacks;
1257 two_nacks.Append(&nack2);
1258 two_nacks.Append(&nack3);
1259
1260 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList23)));
1261 EXPECT_CALL(packet_type_counter_observer_,
1262 RtcpPacketTypesCounterUpdated(
1263 kReceiverMainSsrc,
1264 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
1265 arraysize(kNackList1) + arraysize(kNackList23)),
danilchap1e714ae2016-09-05 09:57:22 -07001266 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1267 nack_set.size()))));
danilchap142f0192016-10-20 08:22:42 -07001268 InjectRtcpPacket(two_nacks);
danilchap1e714ae2016-09-05 09:57:22 -07001269}
1270
1271TEST_F(RtcpReceiverTest, NackNotForUsIgnored) {
1272 const uint16_t kNackList1[] = {1, 2, 3, 5};
1273 const size_t kNackListLength1 = std::end(kNackList1) - std::begin(kNackList1);
1274
1275 rtcp::Nack nack;
danilchap822a16f2016-09-27 09:27:47 -07001276 nack.SetSenderSsrc(kSenderSsrc);
1277 nack.SetMediaSsrc(kNotToUsSsrc);
1278 nack.SetPacketIds(kNackList1, kNackListLength1);
danilchap1e714ae2016-09-05 09:57:22 -07001279
1280 EXPECT_CALL(packet_type_counter_observer_,
1281 RtcpPacketTypesCounterUpdated(
1282 _, Field(&RtcpPacketTypeCounter::nack_requests, 0)));
1283 InjectRtcpPacket(nack);
1284}
1285
1286TEST_F(RtcpReceiverTest, ForceSenderReport) {
1287 rtcp::RapidResyncRequest rr;
danilchap822a16f2016-09-27 09:27:47 -07001288 rr.SetSenderSsrc(kSenderSsrc);
1289 rr.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -07001290
1291 EXPECT_CALL(rtp_rtcp_impl_, OnRequestSendReport());
1292 InjectRtcpPacket(rr);
1293}
hta@webrtc.org47059b52012-05-02 07:46:22 +00001294
spranga790d832016-12-02 07:29:44 -08001295TEST_F(RtcpReceiverTest, ReceivesTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001296 VideoBitrateAllocation expected_allocation;
spranga790d832016-12-02 07:29:44 -08001297 expected_allocation.SetBitrate(0, 0, 10000);
1298 expected_allocation.SetBitrate(0, 1, 20000);
1299 expected_allocation.SetBitrate(1, 0, 40000);
1300 expected_allocation.SetBitrate(1, 1, 80000);
1301
1302 rtcp::TargetBitrate bitrate;
1303 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1304 bitrate.AddTargetBitrate(0, 1, expected_allocation.GetBitrate(0, 1) / 1000);
1305 bitrate.AddTargetBitrate(1, 0, expected_allocation.GetBitrate(1, 0) / 1000);
1306 bitrate.AddTargetBitrate(1, 1, expected_allocation.GetBitrate(1, 1) / 1000);
1307
1308 rtcp::ExtendedReports xr;
1309 xr.SetTargetBitrate(bitrate);
1310
sprangb32aaf92017-08-28 05:49:12 -07001311 // Wrong sender ssrc, target bitrate should be discarded.
1312 xr.SetSenderSsrc(kSenderSsrc + 1);
1313 EXPECT_CALL(bitrate_allocation_observer_,
1314 OnBitrateAllocationUpdated(expected_allocation))
1315 .Times(0);
1316 InjectRtcpPacket(xr);
1317
1318 // Set correct ssrc, callback should be called once.
1319 xr.SetSenderSsrc(kSenderSsrc);
spranga790d832016-12-02 07:29:44 -08001320 EXPECT_CALL(bitrate_allocation_observer_,
1321 OnBitrateAllocationUpdated(expected_allocation));
1322 InjectRtcpPacket(xr);
1323}
1324
sprang6d314c72016-12-06 06:08:53 -08001325TEST_F(RtcpReceiverTest, HandlesIncorrectTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001326 VideoBitrateAllocation expected_allocation;
sprang6d314c72016-12-06 06:08:53 -08001327 expected_allocation.SetBitrate(0, 0, 10000);
1328
1329 rtcp::TargetBitrate bitrate;
1330 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1331 bitrate.AddTargetBitrate(0, kMaxTemporalStreams, 20000);
1332 bitrate.AddTargetBitrate(kMaxSpatialLayers, 0, 40000);
1333
1334 rtcp::ExtendedReports xr;
1335 xr.SetTargetBitrate(bitrate);
sprangb32aaf92017-08-28 05:49:12 -07001336 xr.SetSenderSsrc(kSenderSsrc);
sprang6d314c72016-12-06 06:08:53 -08001337
1338 EXPECT_CALL(bitrate_allocation_observer_,
1339 OnBitrateAllocationUpdated(expected_allocation));
1340 InjectRtcpPacket(xr);
1341}
1342
hta@webrtc.org47059b52012-05-02 07:46:22 +00001343} // namespace webrtc