blob: a576fdc5e9a576391985fe84379d8c143204db2b [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
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800110constexpr int64_t kRtcpIntervalMs = 1000;
111
danilchap1e714ae2016-09-05 09:57:22 -0700112} // namespace
113
hta@webrtc.org47059b52012-05-02 07:46:22 +0000114class RtcpReceiverTest : public ::testing::Test {
115 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000116 RtcpReceiverTest()
danilchap1e714ae2016-09-05 09:57:22 -0700117 : system_clock_(1335900000),
118 rtcp_receiver_(&system_clock_,
119 false,
120 &packet_type_counter_observer_,
121 &bandwidth_observer_,
122 &intra_frame_observer_,
123 &transport_feedback_observer_,
spranga790d832016-12-02 07:29:44 -0800124 &bitrate_allocation_observer_,
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800125 kRtcpIntervalMs,
danilchap1e714ae2016-09-05 09:57:22 -0700126 &rtp_rtcp_impl_) {}
127 void SetUp() {
128 std::set<uint32_t> ssrcs = {kReceiverMainSsrc, kReceiverExtraSsrc};
danilchap1e714ae2016-09-05 09:57:22 -0700129 rtcp_receiver_.SetSsrcs(kReceiverMainSsrc, ssrcs);
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000130
danilchap1e714ae2016-09-05 09:57:22 -0700131 rtcp_receiver_.SetRemoteSSRC(kSenderSsrc);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000132 }
Erik Språng737336d2016-07-29 12:59:36 +0200133
danilchap1e714ae2016-09-05 09:57:22 -0700134 void InjectRtcpPacket(rtc::ArrayView<const uint8_t> raw) {
135 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
hta@webrtc.org47059b52012-05-02 07:46:22 +0000136 }
137
danilchap1e714ae2016-09-05 09:57:22 -0700138 void InjectRtcpPacket(const rtcp::RtcpPacket& packet) {
139 rtc::Buffer raw = packet.Build();
140 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
141 }
142
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000143 SimulatedClock system_clock_;
danilchap1e714ae2016-09-05 09:57:22 -0700144 // Callbacks to packet_type_counter_observer are frequent but most of the time
145 // are not interesting.
146 NiceMock<MockRtcpPacketTypeCounterObserver> packet_type_counter_observer_;
147 StrictMock<MockRtcpBandwidthObserver> bandwidth_observer_;
148 StrictMock<MockRtcpIntraFrameObserver> intra_frame_observer_;
149 StrictMock<MockTransportFeedbackObserver> transport_feedback_observer_;
spranga790d832016-12-02 07:29:44 -0800150 StrictMock<MockVideoBitrateAllocationObserver> bitrate_allocation_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700151 StrictMock<MockModuleRtpRtcp> rtp_rtcp_impl_;
hta@webrtc.org47059b52012-05-02 07:46:22 +0000152
danilchap1e714ae2016-09-05 09:57:22 -0700153 RTCPReceiver rtcp_receiver_;
154};
hta@webrtc.org47059b52012-05-02 07:46:22 +0000155
156TEST_F(RtcpReceiverTest, BrokenPacketIsIgnored) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000157 const uint8_t bad_packet[] = {0, 0, 0, 0};
danilchap1e714ae2016-09-05 09:57:22 -0700158 EXPECT_CALL(packet_type_counter_observer_,
159 RtcpPacketTypesCounterUpdated(_, _))
160 .Times(0);
161 InjectRtcpPacket(bad_packet);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000162}
163
danilchap50da1d32016-03-10 13:13:52 -0800164TEST_F(RtcpReceiverTest, InvalidFeedbackPacketIsIgnored) {
165 // Too short feedback packet.
danilchap1e714ae2016-09-05 09:57:22 -0700166 const uint8_t bad_packet[] = {0x81, rtcp::Rtpfb::kPacketType, 0, 0};
167
168 // TODO(danilchap): Add expectation RtcpPacketTypesCounterUpdated
169 // is not called once parser would be adjusted to avoid that callback on
170 // semi-valid packets.
171 InjectRtcpPacket(bad_packet);
danilchap50da1d32016-03-10 13:13:52 -0800172}
173
hta@webrtc.org47059b52012-05-02 07:46:22 +0000174TEST_F(RtcpReceiverTest, InjectSrPacket) {
danilchapa04d9c32017-07-25 04:03:39 -0700175 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
danilchap1e714ae2016-09-05 09:57:22 -0700176
177 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000178 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700179 sr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700180
181 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
182 EXPECT_CALL(bandwidth_observer_,
183 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
184 InjectRtcpPacket(sr);
185
danilchapa04d9c32017-07-25 04:03:39 -0700186 EXPECT_TRUE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
hta@webrtc.org47059b52012-05-02 07:46:22 +0000187}
188
danilchap1e714ae2016-09-05 09:57:22 -0700189TEST_F(RtcpReceiverTest, InjectSrPacketFromUnknownSender) {
190 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000191 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700192 sr.SetSenderSsrc(kUnknownSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700193
194 // The parser will handle report blocks in Sender Report from other than his
195 // expected peer.
196 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
197 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, now));
198 InjectRtcpPacket(sr);
199
200 // But will not flag that he's gotten sender information.
danilchapa04d9c32017-07-25 04:03:39 -0700201 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000202}
203
Danil Chapovalova094fd12016-02-22 18:59:36 +0100204TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesRTT) {
205 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100206 const int64_t kRttMs = r.Rand(1, 9 * 3600 * 1000);
207 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
208 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100209
Danil Chapovalova094fd12016-02-22 18:59:36 +0100210 int64_t rtt_ms = 0;
211 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700212 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100213
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200214 uint32_t sent_ntp =
215 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100216 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
217
218 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700219 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100220 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700221 block.SetMediaSsrc(kReceiverMainSsrc);
222 block.SetLastSr(sent_ntp);
223 block.SetDelayLastSr(kDelayNtp);
224 sr.AddReportBlock(block);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100225
danilchap1e714ae2016-09-05 09:57:22 -0700226 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
227 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
228 InjectRtcpPacket(sr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100229
230 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700231 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100232 EXPECT_NEAR(kRttMs, rtt_ms, 1);
233}
234
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100235TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesNegativeRTTAsOne) {
236 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100237 const int64_t kRttMs = r.Rand(-3600 * 1000, -1);
238 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
239 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
240
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100241 int64_t rtt_ms = 0;
242 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700243 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100244
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200245 uint32_t sent_ntp =
246 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100247 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
248
249 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700250 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100251 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700252 block.SetMediaSsrc(kReceiverMainSsrc);
253 block.SetLastSr(sent_ntp);
254 block.SetDelayLastSr(kDelayNtp);
255 sr.AddReportBlock(block);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100256
danilchap1e714ae2016-09-05 09:57:22 -0700257 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
258 EXPECT_CALL(bandwidth_observer_,
259 OnReceivedRtcpReceiverReport(SizeIs(1), _, _));
260 InjectRtcpPacket(sr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100261
262 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700263 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100264 EXPECT_EQ(1, rtt_ms);
265}
266
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100267TEST_F(
268 RtcpReceiverTest,
269 TwoReportBlocksWithLastOneWithoutLastSrCalculatesRttForBandwidthObserver) {
270 const int64_t kRttMs = 120;
271 const uint32_t kDelayNtp = 123000;
272 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
273
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200274 uint32_t sent_ntp =
275 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100276 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
277
278 rtcp::SenderReport sr;
279 sr.SetSenderSsrc(kSenderSsrc);
280 rtcp::ReportBlock block;
281 block.SetMediaSsrc(kReceiverMainSsrc);
282 block.SetLastSr(sent_ntp);
283 block.SetDelayLastSr(kDelayNtp);
284 sr.AddReportBlock(block);
285 block.SetMediaSsrc(kReceiverExtraSsrc);
286 block.SetLastSr(0);
287 sr.AddReportBlock(block);
288
289 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
290 EXPECT_CALL(bandwidth_observer_,
291 OnReceivedRtcpReceiverReport(SizeIs(2), kRttMs, _));
292 InjectRtcpPacket(sr);
293}
294
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000295TEST_F(RtcpReceiverTest, InjectRrPacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700296 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000297 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700298 rr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700299
300 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
301 EXPECT_CALL(bandwidth_observer_,
302 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
303 InjectRtcpPacket(rr);
304
danilchap1e714ae2016-09-05 09:57:22 -0700305 std::vector<RTCPReportBlock> report_blocks;
306 rtcp_receiver_.StatisticsReceived(&report_blocks);
307 EXPECT_TRUE(report_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000308}
309
310TEST_F(RtcpReceiverTest, InjectRrPacketWithReportBlockNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700311 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000312 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700313 rb.SetMediaSsrc(kNotToUsSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000314 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700315 rr.SetSenderSsrc(kSenderSsrc);
316 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000317
danilchap1e714ae2016-09-05 09:57:22 -0700318 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
319 EXPECT_CALL(bandwidth_observer_,
320 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
321 InjectRtcpPacket(rr);
322
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200323 EXPECT_EQ(0, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000324 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700325 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000326 EXPECT_TRUE(received_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000327}
328
329TEST_F(RtcpReceiverTest, InjectRrPacketWithOneReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700330 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000331
332 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700333 rb.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000334 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700335 rr.SetSenderSsrc(kSenderSsrc);
336 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000337
danilchap1e714ae2016-09-05 09:57:22 -0700338 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
339 EXPECT_CALL(bandwidth_observer_,
340 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
341 InjectRtcpPacket(rr);
342
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200343 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
344 std::vector<RTCPReportBlock> received_blocks;
345 rtcp_receiver_.StatisticsReceived(&received_blocks);
346 EXPECT_EQ(1u, received_blocks.size());
347}
348
349TEST_F(RtcpReceiverTest, InjectSrPacketWithOneReportBlock) {
350 int64_t now = system_clock_.TimeInMilliseconds();
351
352 rtcp::ReportBlock rb;
353 rb.SetMediaSsrc(kReceiverMainSsrc);
354 rtcp::SenderReport sr;
355 sr.SetSenderSsrc(kSenderSsrc);
356 sr.AddReportBlock(rb);
357
358 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
359 EXPECT_CALL(bandwidth_observer_,
360 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
361 InjectRtcpPacket(sr);
362
363 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000364 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700365 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000366 EXPECT_EQ(1u, received_blocks.size());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000367}
368
369TEST_F(RtcpReceiverTest, InjectRrPacketWithTwoReportBlocks) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000370 const uint16_t kSequenceNumbers[] = {10, 12423};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000371 const uint32_t kCumLost[] = {13, 555};
372 const uint8_t kFracLost[] = {20, 11};
danilchap1e714ae2016-09-05 09:57:22 -0700373 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000374
375 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700376 rb1.SetMediaSsrc(kReceiverMainSsrc);
377 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
378 rb1.SetFractionLost(10);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000379
380 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700381 rb2.SetMediaSsrc(kReceiverExtraSsrc);
382 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
383 rb2.SetFractionLost(0);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000384
385 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700386 rr1.SetSenderSsrc(kSenderSsrc);
387 rr1.AddReportBlock(rb1);
388 rr1.AddReportBlock(rb2);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000389
danilchap1e714ae2016-09-05 09:57:22 -0700390 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
391 EXPECT_CALL(bandwidth_observer_,
392 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
393 InjectRtcpPacket(rr1);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000394
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200395 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700396 std::vector<RTCPReportBlock> received_blocks;
397 rtcp_receiver_.StatisticsReceived(&received_blocks);
398 EXPECT_THAT(received_blocks,
srte3e69e5c2017-08-09 06:13:45 -0700399 UnorderedElementsAre(Field(&RTCPReportBlock::fraction_lost, 0),
400 Field(&RTCPReportBlock::fraction_lost, 10)));
danilchap1e714ae2016-09-05 09:57:22 -0700401
402 // Insert next receiver report with same ssrc but new values.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000403 rtcp::ReportBlock rb3;
danilchap822a16f2016-09-27 09:27:47 -0700404 rb3.SetMediaSsrc(kReceiverMainSsrc);
405 rb3.SetExtHighestSeqNum(kSequenceNumbers[0]);
406 rb3.SetFractionLost(kFracLost[0]);
407 rb3.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000408
409 rtcp::ReportBlock rb4;
danilchap822a16f2016-09-27 09:27:47 -0700410 rb4.SetMediaSsrc(kReceiverExtraSsrc);
411 rb4.SetExtHighestSeqNum(kSequenceNumbers[1]);
412 rb4.SetFractionLost(kFracLost[1]);
413 rb4.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000414
415 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700416 rr2.SetSenderSsrc(kSenderSsrc);
417 rr2.AddReportBlock(rb3);
418 rr2.AddReportBlock(rb4);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000419
danilchap1e714ae2016-09-05 09:57:22 -0700420 // Advance time to make 1st sent time and 2nd sent time different.
421 system_clock_.AdvanceTimeMilliseconds(500);
422 now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000423
danilchap1e714ae2016-09-05 09:57:22 -0700424 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
425 EXPECT_CALL(bandwidth_observer_,
426 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
427 InjectRtcpPacket(rr2);
428
429 received_blocks.clear();
430 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000431 EXPECT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700432 EXPECT_THAT(
433 received_blocks,
434 UnorderedElementsAre(
435 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
436 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
437 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
438 Field(&RTCPReportBlock::extended_highest_sequence_number,
439 kSequenceNumbers[0])),
440 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverExtraSsrc),
441 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
442 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
443 Field(&RTCPReportBlock::extended_highest_sequence_number,
444 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000445}
446
447TEST_F(RtcpReceiverTest, InjectRrPacketsFromTwoRemoteSsrcs) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000448 const uint32_t kSenderSsrc2 = 0x20304;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000449 const uint16_t kSequenceNumbers[] = {10, 12423};
Sebastian Jansson9701e0c2018-08-09 11:21:11 +0200450 const int32_t kCumLost[] = {13, 555};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000451 const uint8_t kFracLost[] = {20, 11};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000452
453 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700454 rb1.SetMediaSsrc(kReceiverMainSsrc);
455 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
456 rb1.SetFractionLost(kFracLost[0]);
457 rb1.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000458 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700459 rr1.SetSenderSsrc(kSenderSsrc);
460 rr1.AddReportBlock(rb1);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000461
danilchap1e714ae2016-09-05 09:57:22 -0700462 int64_t now = system_clock_.TimeInMilliseconds();
463
464 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
465 EXPECT_CALL(bandwidth_observer_,
466 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
467 InjectRtcpPacket(rr1);
468
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200469 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000470
471 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700472 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000473 EXPECT_EQ(1u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700474 EXPECT_EQ(kSenderSsrc, received_blocks[0].sender_ssrc);
475 EXPECT_EQ(kReceiverMainSsrc, received_blocks[0].source_ssrc);
476 EXPECT_EQ(kFracLost[0], received_blocks[0].fraction_lost);
477 EXPECT_EQ(kCumLost[0], received_blocks[0].packets_lost);
478 EXPECT_EQ(kSequenceNumbers[0],
479 received_blocks[0].extended_highest_sequence_number);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000480
481 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700482 rb2.SetMediaSsrc(kReceiverMainSsrc);
483 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
484 rb2.SetFractionLost(kFracLost[1]);
485 rb2.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000486 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700487 rr2.SetSenderSsrc(kSenderSsrc2);
488 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -0700489
490 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
491 EXPECT_CALL(bandwidth_observer_,
492 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
493 InjectRtcpPacket(rr2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000494
495 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700496 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000497 ASSERT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700498 EXPECT_THAT(
499 received_blocks,
500 UnorderedElementsAre(
501 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
502 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc),
503 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
504 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
505 Field(&RTCPReportBlock::extended_highest_sequence_number,
506 kSequenceNumbers[0])),
507 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
508 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc2),
509 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
510 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
511 Field(&RTCPReportBlock::extended_highest_sequence_number,
512 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000513}
514
515TEST_F(RtcpReceiverTest, GetRtt) {
danilchap28b03eb2016-10-05 06:59:44 -0700516 const uint32_t kSentCompactNtp = 0x1234;
517 const uint32_t kDelayCompactNtp = 0x222;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000518 // No report block received.
Erik Språng6b8d3552015-09-24 15:06:57 +0200519 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700520 -1, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000521
522 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700523 rb.SetMediaSsrc(kReceiverMainSsrc);
danilchap28b03eb2016-10-05 06:59:44 -0700524 rb.SetLastSr(kSentCompactNtp);
525 rb.SetDelayLastSr(kDelayCompactNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700526
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000527 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700528 rr.SetSenderSsrc(kSenderSsrc);
529 rr.AddReportBlock(rb);
danilchap1e714ae2016-09-05 09:57:22 -0700530 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000531
danilchap1e714ae2016-09-05 09:57:22 -0700532 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
533 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
534 InjectRtcpPacket(rr);
535
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200536 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700537 EXPECT_EQ(
538 0, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000539}
540
danilchap1e714ae2016-09-05 09:57:22 -0700541// Ij packets are ignored.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000542TEST_F(RtcpReceiverTest, InjectIjWithNoItem) {
danilchapf8506cb2015-11-13 07:33:20 -0800543 rtcp::ExtendedJitterReport ij;
danilchap1e714ae2016-09-05 09:57:22 -0700544 InjectRtcpPacket(ij);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000545}
546
danilchap1e714ae2016-09-05 09:57:22 -0700547// App packets are ignored.
548TEST_F(RtcpReceiverTest, InjectApp) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000549 rtcp::App app;
danilchap822a16f2016-09-27 09:27:47 -0700550 app.SetSubType(30);
551 app.SetName(0x17a177e);
danilchap1e714ae2016-09-05 09:57:22 -0700552 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
danilchap822a16f2016-09-27 09:27:47 -0700553 app.SetData(kData, sizeof(kData));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000554
danilchap1e714ae2016-09-05 09:57:22 -0700555 InjectRtcpPacket(app);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000556}
557
558TEST_F(RtcpReceiverTest, InjectSdesWithOneChunk) {
danilchap1e714ae2016-09-05 09:57:22 -0700559 const char kCname[] = "alice@host";
560 MockRtcpCallbackImpl callback;
561 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000562 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700563 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000564
danilchap1e714ae2016-09-05 09:57:22 -0700565 EXPECT_CALL(callback, CNameChanged(StrEq(kCname), kSenderSsrc));
566 InjectRtcpPacket(sdes);
567
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000568 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700569 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
570 EXPECT_EQ(0, strncmp(cName, kCname, RTCP_CNAME_SIZE));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000571}
572
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000573TEST_F(RtcpReceiverTest, InjectByePacket_RemovesCname) {
danilchap1e714ae2016-09-05 09:57:22 -0700574 const char kCname[] = "alice@host";
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000575 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700576 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000577
danilchap1e714ae2016-09-05 09:57:22 -0700578 InjectRtcpPacket(sdes);
579
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000580 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700581 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000582
583 // Verify that BYE removes the CNAME.
584 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700585 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700586
587 InjectRtcpPacket(bye);
588
589 EXPECT_EQ(-1, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000590}
591
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000592TEST_F(RtcpReceiverTest, InjectByePacket_RemovesReportBlocks) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000593 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700594 rb1.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000595 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700596 rb2.SetMediaSsrc(kReceiverExtraSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000597 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700598 rr.SetSenderSsrc(kSenderSsrc);
599 rr.AddReportBlock(rb1);
600 rr.AddReportBlock(rb2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000601
danilchap1e714ae2016-09-05 09:57:22 -0700602 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
603 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
604 InjectRtcpPacket(rr);
605
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000606 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700607 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000608 EXPECT_EQ(2u, received_blocks.size());
609
610 // Verify that BYE removes the report blocks.
611 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700612 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700613
614 InjectRtcpPacket(bye);
615
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000616 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700617 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000618 EXPECT_TRUE(received_blocks.empty());
619
danilchap1e714ae2016-09-05 09:57:22 -0700620 // Inject packet again.
621 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
622 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
623 InjectRtcpPacket(rr);
624
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000625 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700626 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000627 EXPECT_EQ(2u, received_blocks.size());
628}
629
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200630TEST_F(RtcpReceiverTest, InjectByePacketRemovesReferenceTimeInfo) {
631 rtcp::ExtendedReports xr;
632 xr.SetSenderSsrc(kSenderSsrc);
633 rtcp::Rrtr rrtr;
634 rrtr.SetNtp(NtpTime(0x10203, 0x40506));
635 xr.SetRrtr(rrtr);
636 InjectRtcpPacket(xr);
637
638 rtcp::Bye bye;
639 bye.SetSenderSsrc(kSenderSsrc);
640 InjectRtcpPacket(bye);
641
642 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
643}
644
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000645TEST_F(RtcpReceiverTest, InjectPliPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000646 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700647 pli.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700648
649 EXPECT_CALL(
650 packet_type_counter_observer_,
651 RtcpPacketTypesCounterUpdated(
652 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 1)));
653 EXPECT_CALL(intra_frame_observer_,
654 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
655 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000656}
657
658TEST_F(RtcpReceiverTest, PliPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000659 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700660 pli.SetMediaSsrc(kNotToUsSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700661
662 EXPECT_CALL(
663 packet_type_counter_observer_,
664 RtcpPacketTypesCounterUpdated(
665 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 0)));
666 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
667 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000668}
669
670TEST_F(RtcpReceiverTest, InjectFirPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000671 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700672 fir.AddRequestTo(kReceiverMainSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700673
674 EXPECT_CALL(
675 packet_type_counter_observer_,
676 RtcpPacketTypesCounterUpdated(
677 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::fir_packets, 1)));
678 EXPECT_CALL(intra_frame_observer_,
679 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
680 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000681}
682
683TEST_F(RtcpReceiverTest, FirPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000684 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700685 fir.AddRequestTo(kNotToUsSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700686
687 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
688 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000689}
690
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100691TEST_F(RtcpReceiverTest, ExtendedReportsPacketWithZeroReportBlocksIgnored) {
692 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700693 xr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700694
695 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000696}
697
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100698TEST_F(RtcpReceiverTest, InjectExtendedReportsReceiverReferenceTimePacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700699 const NtpTime kNtp(0x10203, 0x40506);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000700 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700701 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100702 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700703 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700704 xr.SetRrtr(rrtr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000705
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200706 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
707 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
708 EXPECT_THAT(last_xr_rtis, IsEmpty());
danilchap1e714ae2016-09-05 09:57:22 -0700709
710 InjectRtcpPacket(xr);
711
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200712 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
713 ASSERT_THAT(last_xr_rtis, SizeIs(1));
714 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
715 EXPECT_EQ(CompactNtp(kNtp), last_xr_rtis[0].last_rr);
716 EXPECT_EQ(0U, last_xr_rtis[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000717}
718
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100719TEST_F(RtcpReceiverTest, ExtendedReportsDlrrPacketNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700720 // Allow calculate rtt using dlrr/rrtr, simulating media receiver side.
721 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000722
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100723 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700724 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700725 xr.AddDlrrItem(ReceiveTimeInfo(kNotToUsSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700726
727 InjectRtcpPacket(xr);
728
729 int64_t rtt_ms = 0;
730 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000731}
732
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100733TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithSubBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700734 const uint32_t kLastRR = 0x12345;
735 const uint32_t kDelay = 0x23456;
736 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
737 int64_t rtt_ms = 0;
738 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000739
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100740 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700741 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700742 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
danilchap1e714ae2016-09-05 09:57:22 -0700743
744 InjectRtcpPacket(xr);
745
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200746 uint32_t compact_ntp_now =
747 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700748 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
749 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
750 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000751}
752
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100753TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithMultipleSubBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700754 const uint32_t kLastRR = 0x12345;
755 const uint32_t kDelay = 0x56789;
756 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
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));
761 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 1, 0x12345, 0x67890));
762 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 2, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700763
764 InjectRtcpPacket(xr);
765
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200766 uint32_t compact_ntp_now =
767 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700768 int64_t rtt_ms = 0;
769 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
770 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
771 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000772}
773
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100774TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithMultipleReportBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700775 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000776
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000777 rtcp::Rrtr rrtr;
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100778 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700779 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700780 xr.SetRrtr(rrtr);
781 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700782
783 InjectRtcpPacket(xr);
784
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200785 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
786 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
787 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700788 int64_t rtt_ms = 0;
789 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000790}
791
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100792TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithUnknownReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700793 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org38599512013-11-12 08:08:26 +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
danilchap69e59e62016-02-17 03:11:42 -0800801 rtc::Buffer packet = xr.Build();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000802 // Modify the DLRR block to have an unsupported block type, from 5 to 6.
danilchap1e714ae2016-09-05 09:57:22 -0700803 ASSERT_EQ(5, packet.data()[20]);
804 packet.data()[20] = 6;
805 InjectRtcpPacket(packet);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000806
danilchap1e714ae2016-09-05 09:57:22 -0700807 // Validate Rrtr was received and processed.
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200808 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
809 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
810 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700811 // Validate Dlrr report wasn't processed.
812 int64_t rtt_ms = 0;
813 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000814}
815
danilchap1e714ae2016-09-05 09:57:22 -0700816TEST_F(RtcpReceiverTest, TestExtendedReportsRrRttInitiallyFalse) {
817 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
818
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000819 int64_t rtt_ms;
danilchap1e714ae2016-09-05 09:57:22 -0700820 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000821}
822
danilchap1e714ae2016-09-05 09:57:22 -0700823TEST_F(RtcpReceiverTest, RttCalculatedAfterExtendedReportsDlrr) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100824 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100825 const int64_t kRttMs = rand.Rand(1, 9 * 3600 * 1000);
826 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
827 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700828 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200829 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalova094fd12016-02-22 18:59:36 +0100830 uint32_t sent_ntp = CompactNtp(now);
831 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
832
Danil Chapovalova094fd12016-02-22 18:59:36 +0100833 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700834 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700835 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700836
837 InjectRtcpPacket(xr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100838
839 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700840 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100841 EXPECT_NEAR(kRttMs, rtt_ms, 1);
842}
843
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100844TEST_F(RtcpReceiverTest, XrDlrrCalculatesNegativeRttAsOne) {
845 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100846 const int64_t kRttMs = rand.Rand(-3600 * 1000, -1);
847 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
848 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200849 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100850 uint32_t sent_ntp = CompactNtp(now);
851 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
danilchap1e714ae2016-09-05 09:57:22 -0700852 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100853
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100854 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700855 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700856 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700857
858 InjectRtcpPacket(xr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100859
860 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700861 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100862 EXPECT_EQ(1, rtt_ms);
863}
864
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200865TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfoInitiallyEmpty) {
866 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000867}
868
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200869TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfo) {
Danil Chapovalovfc47ed62015-12-07 14:46:35 +0100870 const NtpTime kNtp(0x10203, 0x40506);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100871 const uint32_t kNtpMid = CompactNtp(kNtp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000872
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000873 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700874 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100875 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700876 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700877 xr.SetRrtr(rrtr);
danilchap1e714ae2016-09-05 09:57:22 -0700878
879 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000880
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000881 system_clock_.AdvanceTimeMilliseconds(1000);
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200882
883 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
884 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
885 ASSERT_THAT(last_xr_rtis, SizeIs(1));
886 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
887 EXPECT_EQ(kNtpMid, last_xr_rtis[0].last_rr);
888 EXPECT_EQ(65536U, last_xr_rtis[0].delay_since_last_rr);
889}
890
891TEST_F(RtcpReceiverTest,
892 ReceivedRrtrFromSameSsrcUpdatesReceivedReferenceTimeInfo) {
893 const NtpTime kNtp1(0x10203, 0x40506);
894 const NtpTime kNtp2(0x11223, 0x44556);
895 const int64_t kDelayMs = 2000;
896
897 rtcp::ExtendedReports xr;
898 xr.SetSenderSsrc(kSenderSsrc);
899 rtcp::Rrtr rrtr1;
900 rrtr1.SetNtp(kNtp1);
901 xr.SetRrtr(rrtr1);
902 InjectRtcpPacket(xr);
903 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
904 rtcp::Rrtr rrtr2;
905 rrtr2.SetNtp(kNtp2);
906 xr.SetRrtr(rrtr2);
907 InjectRtcpPacket(xr);
908 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
909
910 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
911 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
912 ASSERT_THAT(last_xr_rtis, SizeIs(1));
913 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
914 EXPECT_EQ(CompactNtp(kNtp2), last_xr_rtis[0].last_rr);
915 EXPECT_EQ(kDelayMs * 65536 / 1000, last_xr_rtis[0].delay_since_last_rr);
916}
917
918TEST_F(RtcpReceiverTest, StoresLastReceivedRrtrPerSsrc) {
919 const size_t kNumBufferedReports = 1;
920 const size_t kNumReports =
921 rtcp::ExtendedReports::kMaxNumberOfDlrrItems + kNumBufferedReports;
922 for (size_t i = 0; i < kNumReports; ++i) {
923 rtcp::ExtendedReports xr;
924 xr.SetSenderSsrc(i * 100);
925 rtcp::Rrtr rrtr;
926 rrtr.SetNtp(NtpTime(i * 200, i * 300));
927 xr.SetRrtr(rrtr);
928 InjectRtcpPacket(xr);
929 system_clock_.AdvanceTimeMilliseconds(1000);
930 }
931
932 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
933 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
934 ASSERT_THAT(last_xr_rtis,
935 SizeIs(rtcp::ExtendedReports::kMaxNumberOfDlrrItems));
936 for (size_t i = 0; i < rtcp::ExtendedReports::kMaxNumberOfDlrrItems; ++i) {
937 EXPECT_EQ(i * 100, last_xr_rtis[i].ssrc);
938 EXPECT_EQ(CompactNtp(NtpTime(i * 200, i * 300)), last_xr_rtis[i].last_rr);
939 EXPECT_EQ(65536U * (kNumReports - i), last_xr_rtis[i].delay_since_last_rr);
940 }
941
942 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
943 ASSERT_THAT(last_xr_rtis, SizeIs(kNumBufferedReports));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000944}
945
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000946TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000947 const uint16_t kSequenceNumber = 1234;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000948 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000949
950 // No RR received, shouldn't trigger a timeout.
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800951 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
952 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000953
954 // Add a RR and advance the clock just enough to not trigger a timeout.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000955 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700956 rb1.SetMediaSsrc(kReceiverMainSsrc);
957 rb1.SetExtHighestSeqNum(kSequenceNumber);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000958 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700959 rr1.SetSenderSsrc(kSenderSsrc);
960 rr1.AddReportBlock(rb1);
danilchap1e714ae2016-09-05 09:57:22 -0700961
962 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
963 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
964 InjectRtcpPacket(rr1);
965
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000966 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs - 1);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800967 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
968 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000969
970 // Add a RR with the same extended max as the previous RR to trigger a
971 // sequence number timeout, but not a RR timeout.
danilchap1e714ae2016-09-05 09:57:22 -0700972 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
973 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
974 InjectRtcpPacket(rr1);
975
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000976 system_clock_.AdvanceTimeMilliseconds(2);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800977 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
978 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000979
980 // Advance clock enough to trigger an RR timeout too.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000981 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800982 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000983
984 // We should only get one timeout even though we still haven't received a new
985 // RR.
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800986 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
987 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000988
989 // Add a new RR with increase sequence number to reset timers.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000990 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700991 rb2.SetMediaSsrc(kReceiverMainSsrc);
992 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000993 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700994 rr2.SetSenderSsrc(kSenderSsrc);
995 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -0700996
997 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
998 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
999 InjectRtcpPacket(rr2);
1000
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001001 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1002 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001003
1004 // Verify we can get a timeout again once we've received new RR.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001005 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -07001006 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1007 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1008 InjectRtcpPacket(rr2);
1009
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001010 system_clock_.AdvanceTimeMilliseconds(kRtcpIntervalMs + 1);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001011 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1012 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
danilchap1e714ae2016-09-05 09:57:22 -07001013
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001014 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001015 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001016}
1017
hta@webrtc.org47059b52012-05-02 07:46:22 +00001018TEST_F(RtcpReceiverTest, TmmbrReceivedWithNoIncomingPacket) {
danilchap1e714ae2016-09-05 09:57:22 -07001019 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001020}
1021
1022TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) {
danilchap1e714ae2016-09-05 09:57:22 -07001023 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001024 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001025 tmmbr.SetSenderSsrc(kSenderSsrc);
1026 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001027 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001028 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001029 rtcp::CompoundPacket compound;
1030 compound.Append(&sr);
1031 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001032
danilchap1e714ae2016-09-05 09:57:22 -07001033 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1034 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(SizeIs(1)));
1035 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1036 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1037 InjectRtcpPacket(compound);
1038
1039 std::vector<rtcp::TmmbItem> tmmbr_received = rtcp_receiver_.TmmbrReceived();
1040 ASSERT_EQ(1u, tmmbr_received.size());
1041 EXPECT_EQ(kBitrateBps, tmmbr_received[0].bitrate_bps());
1042 EXPECT_EQ(kSenderSsrc, tmmbr_received[0].ssrc());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001043}
1044
1045TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -07001046 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001047 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001048 tmmbr.SetSenderSsrc(kSenderSsrc);
1049 tmmbr.AddTmmbr(rtcp::TmmbItem(kNotToUsSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001050
1051 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001052 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001053 rtcp::CompoundPacket compound;
1054 compound.Append(&sr);
1055 compound.Append(&tmmbr);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001056
danilchap1e714ae2016-09-05 09:57:22 -07001057 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1058 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1059 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1060 InjectRtcpPacket(compound);
1061
1062 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001063}
1064
1065TEST_F(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001066 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001067 tmmbr.SetSenderSsrc(kSenderSsrc);
1068 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 0, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001069 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);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +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
hta@webrtc.org404843e2012-05-02 09:56:45 +00001083TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001084 // Inject 3 packets "from" kSenderSsrc, kSenderSsrc+1, kSenderSsrc+2.
hta@webrtc.org404843e2012-05-02 09:56:45 +00001085 // The times of arrival are starttime + 0, starttime + 5 and starttime + 10.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001086 for (uint32_t ssrc = kSenderSsrc; ssrc < kSenderSsrc + 3; ++ssrc) {
1087 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001088 tmmbr.SetSenderSsrc(ssrc);
1089 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 30000, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001090 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001091 sr.SetSenderSsrc(ssrc);
danilchap7a4116a2016-03-14 08:19:28 -07001092 rtcp::CompoundPacket compound;
1093 compound.Append(&sr);
1094 compound.Append(&tmmbr);
danilchap1e714ae2016-09-05 09:57:22 -07001095
1096 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1097 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(_));
1098 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1099 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_));
1100 InjectRtcpPacket(compound);
1101
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001102 // 5 seconds between each packet.
1103 system_clock_.AdvanceTimeMilliseconds(5000);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001104 }
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001105 // It is now starttime + 15.
danilchap1e714ae2016-09-05 09:57:22 -07001106 std::vector<rtcp::TmmbItem> candidate_set = rtcp_receiver_.TmmbrReceived();
1107 ASSERT_EQ(3u, candidate_set.size());
1108 EXPECT_EQ(30000U, candidate_set[0].bitrate_bps());
1109
hta@webrtc.org404843e2012-05-02 09:56:45 +00001110 // We expect the timeout to be 25 seconds. Advance the clock by 12
1111 // seconds, timing out the first packet.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001112 system_clock_.AdvanceTimeMilliseconds(12000);
danilchap1e714ae2016-09-05 09:57:22 -07001113 candidate_set = rtcp_receiver_.TmmbrReceived();
1114 ASSERT_EQ(2u, candidate_set.size());
danilchap287e5482016-08-16 15:15:39 -07001115 EXPECT_EQ(kSenderSsrc + 1, candidate_set[0].ssrc());
hta@webrtc.org404843e2012-05-02 09:56:45 +00001116}
1117
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001118TEST_F(RtcpReceiverTest, Callbacks) {
danilchap1e714ae2016-09-05 09:57:22 -07001119 MockRtcpCallbackImpl callback;
1120 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001121
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001122 const uint8_t kFractionLoss = 3;
1123 const uint32_t kCumulativeLoss = 7;
1124 const uint32_t kJitter = 9;
1125 const uint16_t kSequenceNumber = 1234;
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001126
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001127 // First packet, all numbers should just propagate.
1128 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -07001129 rb1.SetMediaSsrc(kReceiverMainSsrc);
1130 rb1.SetExtHighestSeqNum(kSequenceNumber);
1131 rb1.SetFractionLost(kFractionLoss);
1132 rb1.SetCumulativeLost(kCumulativeLoss);
1133 rb1.SetJitter(kJitter);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001134
1135 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -07001136 rr1.SetSenderSsrc(kSenderSsrc);
1137 rr1.AddReportBlock(rb1);
srte186d9c32017-08-04 05:03:53 -07001138 EXPECT_CALL(callback,
1139 StatisticsUpdated(
1140 AllOf(Field(&RtcpStatistics::fraction_lost, kFractionLoss),
1141 Field(&RtcpStatistics::packets_lost, kCumulativeLoss),
1142 Field(&RtcpStatistics::extended_highest_sequence_number,
1143 kSequenceNumber),
1144 Field(&RtcpStatistics::jitter, kJitter)),
1145 kReceiverMainSsrc));
danilchap1e714ae2016-09-05 09:57:22 -07001146 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1147 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1148 InjectRtcpPacket(rr1);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001149
danilchap1e714ae2016-09-05 09:57:22 -07001150 rtcp_receiver_.RegisterRtcpStatisticsCallback(nullptr);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001151
danilchap1e714ae2016-09-05 09:57:22 -07001152 // Add arbitrary numbers, callback should not be called.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001153 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001154 rb2.SetMediaSsrc(kReceiverMainSsrc);
1155 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
1156 rb2.SetFractionLost(42);
1157 rb2.SetCumulativeLost(137);
1158 rb2.SetJitter(4711);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001159
1160 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001161 rr2.SetSenderSsrc(kSenderSsrc);
1162 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001163
1164 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1165 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1166 EXPECT_CALL(callback, StatisticsUpdated(_, _)).Times(0);
1167 InjectRtcpPacket(rr2);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001168}
hta@webrtc.org404843e2012-05-02 09:56:45 +00001169
sprang49f9cdb2015-10-01 03:06:57 -07001170TEST_F(RtcpReceiverTest, ReceivesTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001171 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001172 packet.SetMediaSsrc(kReceiverMainSsrc);
1173 packet.SetSenderSsrc(kSenderSsrc);
1174 packet.SetBase(1, 1000);
1175 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001176
danilchap1e714ae2016-09-05 09:57:22 -07001177 EXPECT_CALL(
1178 transport_feedback_observer_,
1179 OnTransportFeedback(AllOf(
1180 Property(&rtcp::TransportFeedback::media_ssrc, kReceiverMainSsrc),
1181 Property(&rtcp::TransportFeedback::sender_ssrc, kSenderSsrc))));
1182 InjectRtcpPacket(packet);
sprang49f9cdb2015-10-01 03:06:57 -07001183}
1184
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001185TEST_F(RtcpReceiverTest, ReceivesRemb) {
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001186 const uint32_t kBitrateBps = 500000;
1187 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001188 remb.SetSenderSsrc(kSenderSsrc);
1189 remb.SetBitrateBps(kBitrateBps);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001190
danilchap1e714ae2016-09-05 09:57:22 -07001191 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1192 InjectRtcpPacket(remb);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001193}
1194
sprang49f9cdb2015-10-01 03:06:57 -07001195TEST_F(RtcpReceiverTest, HandlesInvalidTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001196 // Send a compound packet with a TransportFeedback followed by something else.
1197 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001198 packet.SetMediaSsrc(kReceiverMainSsrc);
1199 packet.SetSenderSsrc(kSenderSsrc);
1200 packet.SetBase(1, 1000);
1201 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001202
1203 static uint32_t kBitrateBps = 50000;
1204 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001205 remb.SetSenderSsrc(kSenderSsrc);
1206 remb.SetBitrateBps(kBitrateBps);
danilchap7a4116a2016-03-14 08:19:28 -07001207 rtcp::CompoundPacket compound;
1208 compound.Append(&packet);
1209 compound.Append(&remb);
1210 rtc::Buffer built_packet = compound.Build();
sprang49f9cdb2015-10-01 03:06:57 -07001211
1212 // Modify the TransportFeedback packet so that it is invalid.
1213 const size_t kStatusCountOffset = 14;
Yves Gerey665174f2018-06-19 15:03:05 +02001214 ByteWriter<uint16_t>::WriteBigEndian(&built_packet.data()[kStatusCountOffset],
1215 42);
sprang49f9cdb2015-10-01 03:06:57 -07001216
danilchap1e714ae2016-09-05 09:57:22 -07001217 // Stress no transport feedback is expected.
1218 EXPECT_CALL(transport_feedback_observer_, OnTransportFeedback(_)).Times(0);
1219 // But remb should be processed and cause a callback
1220 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1221 InjectRtcpPacket(built_packet);
sprang49f9cdb2015-10-01 03:06:57 -07001222}
1223
danilchap1e714ae2016-09-05 09:57:22 -07001224TEST_F(RtcpReceiverTest, Nack) {
1225 const uint16_t kNackList1[] = {1, 2, 3, 5};
danilchap142f0192016-10-20 08:22:42 -07001226 const uint16_t kNackList23[] = {5, 7, 30, 40, 41, 58, 59, 61, 63};
1227 const size_t kNackListLength2 = 4;
1228 const size_t kNackListLength3 = arraysize(kNackList23) - kNackListLength2;
danilchap1e714ae2016-09-05 09:57:22 -07001229 std::set<uint16_t> nack_set;
1230 nack_set.insert(std::begin(kNackList1), std::end(kNackList1));
danilchap142f0192016-10-20 08:22:42 -07001231 nack_set.insert(std::begin(kNackList23), std::end(kNackList23));
danilchap1e714ae2016-09-05 09:57:22 -07001232
danilchap142f0192016-10-20 08:22:42 -07001233 rtcp::Nack nack1;
1234 nack1.SetSenderSsrc(kSenderSsrc);
1235 nack1.SetMediaSsrc(kReceiverMainSsrc);
1236 nack1.SetPacketIds(kNackList1, arraysize(kNackList1));
danilchap1e714ae2016-09-05 09:57:22 -07001237
1238 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList1)));
danilchap1e714ae2016-09-05 09:57:22 -07001239 EXPECT_CALL(packet_type_counter_observer_,
1240 RtcpPacketTypesCounterUpdated(
1241 kReceiverMainSsrc,
1242 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
danilchap142f0192016-10-20 08:22:42 -07001243 arraysize(kNackList1)),
1244 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1245 arraysize(kNackList1)))));
1246 InjectRtcpPacket(nack1);
1247
1248 rtcp::Nack nack2;
1249 nack2.SetSenderSsrc(kSenderSsrc);
1250 nack2.SetMediaSsrc(kReceiverMainSsrc);
1251 nack2.SetPacketIds(kNackList23, kNackListLength2);
1252
1253 rtcp::Nack nack3;
1254 nack3.SetSenderSsrc(kSenderSsrc);
1255 nack3.SetMediaSsrc(kReceiverMainSsrc);
1256 nack3.SetPacketIds(kNackList23 + kNackListLength2, kNackListLength3);
1257
1258 rtcp::CompoundPacket two_nacks;
1259 two_nacks.Append(&nack2);
1260 two_nacks.Append(&nack3);
1261
1262 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList23)));
1263 EXPECT_CALL(packet_type_counter_observer_,
1264 RtcpPacketTypesCounterUpdated(
1265 kReceiverMainSsrc,
1266 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
1267 arraysize(kNackList1) + arraysize(kNackList23)),
danilchap1e714ae2016-09-05 09:57:22 -07001268 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1269 nack_set.size()))));
danilchap142f0192016-10-20 08:22:42 -07001270 InjectRtcpPacket(two_nacks);
danilchap1e714ae2016-09-05 09:57:22 -07001271}
1272
1273TEST_F(RtcpReceiverTest, NackNotForUsIgnored) {
1274 const uint16_t kNackList1[] = {1, 2, 3, 5};
1275 const size_t kNackListLength1 = std::end(kNackList1) - std::begin(kNackList1);
1276
1277 rtcp::Nack nack;
danilchap822a16f2016-09-27 09:27:47 -07001278 nack.SetSenderSsrc(kSenderSsrc);
1279 nack.SetMediaSsrc(kNotToUsSsrc);
1280 nack.SetPacketIds(kNackList1, kNackListLength1);
danilchap1e714ae2016-09-05 09:57:22 -07001281
1282 EXPECT_CALL(packet_type_counter_observer_,
1283 RtcpPacketTypesCounterUpdated(
1284 _, Field(&RtcpPacketTypeCounter::nack_requests, 0)));
1285 InjectRtcpPacket(nack);
1286}
1287
1288TEST_F(RtcpReceiverTest, ForceSenderReport) {
1289 rtcp::RapidResyncRequest rr;
danilchap822a16f2016-09-27 09:27:47 -07001290 rr.SetSenderSsrc(kSenderSsrc);
1291 rr.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -07001292
1293 EXPECT_CALL(rtp_rtcp_impl_, OnRequestSendReport());
1294 InjectRtcpPacket(rr);
1295}
hta@webrtc.org47059b52012-05-02 07:46:22 +00001296
spranga790d832016-12-02 07:29:44 -08001297TEST_F(RtcpReceiverTest, ReceivesTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001298 VideoBitrateAllocation expected_allocation;
spranga790d832016-12-02 07:29:44 -08001299 expected_allocation.SetBitrate(0, 0, 10000);
1300 expected_allocation.SetBitrate(0, 1, 20000);
1301 expected_allocation.SetBitrate(1, 0, 40000);
1302 expected_allocation.SetBitrate(1, 1, 80000);
1303
1304 rtcp::TargetBitrate bitrate;
1305 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1306 bitrate.AddTargetBitrate(0, 1, expected_allocation.GetBitrate(0, 1) / 1000);
1307 bitrate.AddTargetBitrate(1, 0, expected_allocation.GetBitrate(1, 0) / 1000);
1308 bitrate.AddTargetBitrate(1, 1, expected_allocation.GetBitrate(1, 1) / 1000);
1309
1310 rtcp::ExtendedReports xr;
1311 xr.SetTargetBitrate(bitrate);
1312
sprangb32aaf92017-08-28 05:49:12 -07001313 // Wrong sender ssrc, target bitrate should be discarded.
1314 xr.SetSenderSsrc(kSenderSsrc + 1);
1315 EXPECT_CALL(bitrate_allocation_observer_,
1316 OnBitrateAllocationUpdated(expected_allocation))
1317 .Times(0);
1318 InjectRtcpPacket(xr);
1319
1320 // Set correct ssrc, callback should be called once.
1321 xr.SetSenderSsrc(kSenderSsrc);
spranga790d832016-12-02 07:29:44 -08001322 EXPECT_CALL(bitrate_allocation_observer_,
1323 OnBitrateAllocationUpdated(expected_allocation));
1324 InjectRtcpPacket(xr);
1325}
1326
sprang6d314c72016-12-06 06:08:53 -08001327TEST_F(RtcpReceiverTest, HandlesIncorrectTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001328 VideoBitrateAllocation expected_allocation;
sprang6d314c72016-12-06 06:08:53 -08001329 expected_allocation.SetBitrate(0, 0, 10000);
1330
1331 rtcp::TargetBitrate bitrate;
1332 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1333 bitrate.AddTargetBitrate(0, kMaxTemporalStreams, 20000);
1334 bitrate.AddTargetBitrate(kMaxSpatialLayers, 0, 40000);
1335
1336 rtcp::ExtendedReports xr;
1337 xr.SetTargetBitrate(bitrate);
sprangb32aaf92017-08-28 05:49:12 -07001338 xr.SetSenderSsrc(kSenderSsrc);
sprang6d314c72016-12-06 06:08:53 -08001339
1340 EXPECT_CALL(bitrate_allocation_observer_,
1341 OnBitrateAllocationUpdated(expected_allocation));
1342 InjectRtcpPacket(xr);
1343}
1344
hta@webrtc.org47059b52012-05-02 07:46:22 +00001345} // namespace webrtc