blob: 41d47256653aea8589dace922f83e5167cfca537 [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"
Mirko Bonadei71207422017-09-15 13:58:09 +020015#include "common_types.h" // NOLINT(build/include)
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "common_video/include/video_bitrate_allocator.h"
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
danilchap37953762017-02-09 11:15:25 -0800211 uint32_t sent_ntp = CompactNtp(system_clock_.CurrentNtpTime());
Danil Chapovalova094fd12016-02-22 18:59:36 +0100212 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
213
214 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700215 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100216 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700217 block.SetMediaSsrc(kReceiverMainSsrc);
218 block.SetLastSr(sent_ntp);
219 block.SetDelayLastSr(kDelayNtp);
220 sr.AddReportBlock(block);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100221
danilchap1e714ae2016-09-05 09:57:22 -0700222 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
223 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
224 InjectRtcpPacket(sr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100225
226 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700227 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100228 EXPECT_NEAR(kRttMs, rtt_ms, 1);
229}
230
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100231TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesNegativeRTTAsOne) {
232 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100233 const int64_t kRttMs = r.Rand(-3600 * 1000, -1);
234 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
235 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
236
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100237 int64_t rtt_ms = 0;
238 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700239 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100240
danilchap37953762017-02-09 11:15:25 -0800241 uint32_t sent_ntp = CompactNtp(system_clock_.CurrentNtpTime());
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100242 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
243
244 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700245 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100246 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700247 block.SetMediaSsrc(kReceiverMainSsrc);
248 block.SetLastSr(sent_ntp);
249 block.SetDelayLastSr(kDelayNtp);
250 sr.AddReportBlock(block);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100251
danilchap1e714ae2016-09-05 09:57:22 -0700252 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
253 EXPECT_CALL(bandwidth_observer_,
254 OnReceivedRtcpReceiverReport(SizeIs(1), _, _));
255 InjectRtcpPacket(sr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100256
257 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700258 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100259 EXPECT_EQ(1, rtt_ms);
260}
261
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100262TEST_F(
263 RtcpReceiverTest,
264 TwoReportBlocksWithLastOneWithoutLastSrCalculatesRttForBandwidthObserver) {
265 const int64_t kRttMs = 120;
266 const uint32_t kDelayNtp = 123000;
267 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
268
269 uint32_t sent_ntp = CompactNtp(system_clock_.CurrentNtpTime());
270 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
271
272 rtcp::SenderReport sr;
273 sr.SetSenderSsrc(kSenderSsrc);
274 rtcp::ReportBlock block;
275 block.SetMediaSsrc(kReceiverMainSsrc);
276 block.SetLastSr(sent_ntp);
277 block.SetDelayLastSr(kDelayNtp);
278 sr.AddReportBlock(block);
279 block.SetMediaSsrc(kReceiverExtraSsrc);
280 block.SetLastSr(0);
281 sr.AddReportBlock(block);
282
283 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
284 EXPECT_CALL(bandwidth_observer_,
285 OnReceivedRtcpReceiverReport(SizeIs(2), kRttMs, _));
286 InjectRtcpPacket(sr);
287}
288
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000289TEST_F(RtcpReceiverTest, InjectRrPacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700290 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000291 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700292 rr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700293
294 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
295 EXPECT_CALL(bandwidth_observer_,
296 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
297 InjectRtcpPacket(rr);
298
danilchap1e714ae2016-09-05 09:57:22 -0700299 std::vector<RTCPReportBlock> report_blocks;
300 rtcp_receiver_.StatisticsReceived(&report_blocks);
301 EXPECT_TRUE(report_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000302}
303
304TEST_F(RtcpReceiverTest, InjectRrPacketWithReportBlockNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700305 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000306 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700307 rb.SetMediaSsrc(kNotToUsSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000308 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700309 rr.SetSenderSsrc(kSenderSsrc);
310 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000311
danilchap1e714ae2016-09-05 09:57:22 -0700312 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
313 EXPECT_CALL(bandwidth_observer_,
314 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
315 InjectRtcpPacket(rr);
316
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200317 EXPECT_EQ(0, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000318 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700319 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000320 EXPECT_TRUE(received_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000321}
322
323TEST_F(RtcpReceiverTest, InjectRrPacketWithOneReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700324 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000325
326 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700327 rb.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000328 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700329 rr.SetSenderSsrc(kSenderSsrc);
330 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000331
danilchap1e714ae2016-09-05 09:57:22 -0700332 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
333 EXPECT_CALL(bandwidth_observer_,
334 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
335 InjectRtcpPacket(rr);
336
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200337 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
338 std::vector<RTCPReportBlock> received_blocks;
339 rtcp_receiver_.StatisticsReceived(&received_blocks);
340 EXPECT_EQ(1u, received_blocks.size());
341}
342
343TEST_F(RtcpReceiverTest, InjectSrPacketWithOneReportBlock) {
344 int64_t now = system_clock_.TimeInMilliseconds();
345
346 rtcp::ReportBlock rb;
347 rb.SetMediaSsrc(kReceiverMainSsrc);
348 rtcp::SenderReport sr;
349 sr.SetSenderSsrc(kSenderSsrc);
350 sr.AddReportBlock(rb);
351
352 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
353 EXPECT_CALL(bandwidth_observer_,
354 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
355 InjectRtcpPacket(sr);
356
357 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000358 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700359 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000360 EXPECT_EQ(1u, received_blocks.size());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000361}
362
363TEST_F(RtcpReceiverTest, InjectRrPacketWithTwoReportBlocks) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000364 const uint16_t kSequenceNumbers[] = {10, 12423};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000365 const uint32_t kCumLost[] = {13, 555};
366 const uint8_t kFracLost[] = {20, 11};
danilchap1e714ae2016-09-05 09:57:22 -0700367 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000368
369 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700370 rb1.SetMediaSsrc(kReceiverMainSsrc);
371 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
372 rb1.SetFractionLost(10);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000373
374 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700375 rb2.SetMediaSsrc(kReceiverExtraSsrc);
376 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
377 rb2.SetFractionLost(0);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000378
379 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700380 rr1.SetSenderSsrc(kSenderSsrc);
381 rr1.AddReportBlock(rb1);
382 rr1.AddReportBlock(rb2);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000383
danilchap1e714ae2016-09-05 09:57:22 -0700384 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
385 EXPECT_CALL(bandwidth_observer_,
386 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
387 InjectRtcpPacket(rr1);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000388
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200389 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700390 std::vector<RTCPReportBlock> received_blocks;
391 rtcp_receiver_.StatisticsReceived(&received_blocks);
392 EXPECT_THAT(received_blocks,
srte3e69e5c2017-08-09 06:13:45 -0700393 UnorderedElementsAre(Field(&RTCPReportBlock::fraction_lost, 0),
394 Field(&RTCPReportBlock::fraction_lost, 10)));
danilchap1e714ae2016-09-05 09:57:22 -0700395
396 // Insert next receiver report with same ssrc but new values.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000397 rtcp::ReportBlock rb3;
danilchap822a16f2016-09-27 09:27:47 -0700398 rb3.SetMediaSsrc(kReceiverMainSsrc);
399 rb3.SetExtHighestSeqNum(kSequenceNumbers[0]);
400 rb3.SetFractionLost(kFracLost[0]);
401 rb3.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000402
403 rtcp::ReportBlock rb4;
danilchap822a16f2016-09-27 09:27:47 -0700404 rb4.SetMediaSsrc(kReceiverExtraSsrc);
405 rb4.SetExtHighestSeqNum(kSequenceNumbers[1]);
406 rb4.SetFractionLost(kFracLost[1]);
407 rb4.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000408
409 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700410 rr2.SetSenderSsrc(kSenderSsrc);
411 rr2.AddReportBlock(rb3);
412 rr2.AddReportBlock(rb4);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000413
danilchap1e714ae2016-09-05 09:57:22 -0700414 // Advance time to make 1st sent time and 2nd sent time different.
415 system_clock_.AdvanceTimeMilliseconds(500);
416 now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000417
danilchap1e714ae2016-09-05 09:57:22 -0700418 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
419 EXPECT_CALL(bandwidth_observer_,
420 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
421 InjectRtcpPacket(rr2);
422
423 received_blocks.clear();
424 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000425 EXPECT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700426 EXPECT_THAT(
427 received_blocks,
428 UnorderedElementsAre(
429 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
430 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
431 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
432 Field(&RTCPReportBlock::extended_highest_sequence_number,
433 kSequenceNumbers[0])),
434 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverExtraSsrc),
435 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
436 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
437 Field(&RTCPReportBlock::extended_highest_sequence_number,
438 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000439}
440
441TEST_F(RtcpReceiverTest, InjectRrPacketsFromTwoRemoteSsrcs) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000442 const uint32_t kSenderSsrc2 = 0x20304;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000443 const uint16_t kSequenceNumbers[] = {10, 12423};
444 const uint32_t kCumLost[] = {13, 555};
445 const uint8_t kFracLost[] = {20, 11};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000446
447 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700448 rb1.SetMediaSsrc(kReceiverMainSsrc);
449 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
450 rb1.SetFractionLost(kFracLost[0]);
451 rb1.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000452 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700453 rr1.SetSenderSsrc(kSenderSsrc);
454 rr1.AddReportBlock(rb1);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000455
danilchap1e714ae2016-09-05 09:57:22 -0700456 int64_t now = system_clock_.TimeInMilliseconds();
457
458 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
459 EXPECT_CALL(bandwidth_observer_,
460 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
461 InjectRtcpPacket(rr1);
462
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200463 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000464
465 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700466 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000467 EXPECT_EQ(1u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700468 EXPECT_EQ(kSenderSsrc, received_blocks[0].sender_ssrc);
469 EXPECT_EQ(kReceiverMainSsrc, received_blocks[0].source_ssrc);
470 EXPECT_EQ(kFracLost[0], received_blocks[0].fraction_lost);
471 EXPECT_EQ(kCumLost[0], received_blocks[0].packets_lost);
472 EXPECT_EQ(kSequenceNumbers[0],
473 received_blocks[0].extended_highest_sequence_number);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000474
475 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700476 rb2.SetMediaSsrc(kReceiverMainSsrc);
477 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
478 rb2.SetFractionLost(kFracLost[1]);
479 rb2.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000480 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700481 rr2.SetSenderSsrc(kSenderSsrc2);
482 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -0700483
484 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
485 EXPECT_CALL(bandwidth_observer_,
486 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
487 InjectRtcpPacket(rr2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000488
489 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700490 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000491 ASSERT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700492 EXPECT_THAT(
493 received_blocks,
494 UnorderedElementsAre(
495 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
496 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc),
497 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
498 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
499 Field(&RTCPReportBlock::extended_highest_sequence_number,
500 kSequenceNumbers[0])),
501 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
502 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc2),
503 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
504 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
505 Field(&RTCPReportBlock::extended_highest_sequence_number,
506 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000507}
508
509TEST_F(RtcpReceiverTest, GetRtt) {
danilchap28b03eb2016-10-05 06:59:44 -0700510 const uint32_t kSentCompactNtp = 0x1234;
511 const uint32_t kDelayCompactNtp = 0x222;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000512 // No report block received.
Erik Språng6b8d3552015-09-24 15:06:57 +0200513 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700514 -1, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000515
516 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700517 rb.SetMediaSsrc(kReceiverMainSsrc);
danilchap28b03eb2016-10-05 06:59:44 -0700518 rb.SetLastSr(kSentCompactNtp);
519 rb.SetDelayLastSr(kDelayCompactNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700520
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000521 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700522 rr.SetSenderSsrc(kSenderSsrc);
523 rr.AddReportBlock(rb);
danilchap1e714ae2016-09-05 09:57:22 -0700524 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000525
danilchap1e714ae2016-09-05 09:57:22 -0700526 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
527 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
528 InjectRtcpPacket(rr);
529
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200530 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700531 EXPECT_EQ(
532 0, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000533}
534
danilchap1e714ae2016-09-05 09:57:22 -0700535// Ij packets are ignored.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000536TEST_F(RtcpReceiverTest, InjectIjWithNoItem) {
danilchapf8506cb2015-11-13 07:33:20 -0800537 rtcp::ExtendedJitterReport ij;
danilchap1e714ae2016-09-05 09:57:22 -0700538 InjectRtcpPacket(ij);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000539}
540
danilchap1e714ae2016-09-05 09:57:22 -0700541// App packets are ignored.
542TEST_F(RtcpReceiverTest, InjectApp) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000543 rtcp::App app;
danilchap822a16f2016-09-27 09:27:47 -0700544 app.SetSubType(30);
545 app.SetName(0x17a177e);
danilchap1e714ae2016-09-05 09:57:22 -0700546 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
danilchap822a16f2016-09-27 09:27:47 -0700547 app.SetData(kData, sizeof(kData));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000548
danilchap1e714ae2016-09-05 09:57:22 -0700549 InjectRtcpPacket(app);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000550}
551
552TEST_F(RtcpReceiverTest, InjectSdesWithOneChunk) {
danilchap1e714ae2016-09-05 09:57:22 -0700553 const char kCname[] = "alice@host";
554 MockRtcpCallbackImpl callback;
555 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000556 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700557 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000558
danilchap1e714ae2016-09-05 09:57:22 -0700559 EXPECT_CALL(callback, CNameChanged(StrEq(kCname), kSenderSsrc));
560 InjectRtcpPacket(sdes);
561
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000562 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700563 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
564 EXPECT_EQ(0, strncmp(cName, kCname, RTCP_CNAME_SIZE));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000565}
566
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000567TEST_F(RtcpReceiverTest, InjectByePacket_RemovesCname) {
danilchap1e714ae2016-09-05 09:57:22 -0700568 const char kCname[] = "alice@host";
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000569 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700570 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000571
danilchap1e714ae2016-09-05 09:57:22 -0700572 InjectRtcpPacket(sdes);
573
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000574 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700575 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000576
577 // Verify that BYE removes the CNAME.
578 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700579 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700580
581 InjectRtcpPacket(bye);
582
583 EXPECT_EQ(-1, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000584}
585
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000586TEST_F(RtcpReceiverTest, InjectByePacket_RemovesReportBlocks) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000587 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700588 rb1.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000589 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700590 rb2.SetMediaSsrc(kReceiverExtraSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000591 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700592 rr.SetSenderSsrc(kSenderSsrc);
593 rr.AddReportBlock(rb1);
594 rr.AddReportBlock(rb2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000595
danilchap1e714ae2016-09-05 09:57:22 -0700596 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
597 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
598 InjectRtcpPacket(rr);
599
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000600 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700601 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000602 EXPECT_EQ(2u, received_blocks.size());
603
604 // Verify that BYE removes the report blocks.
605 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700606 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700607
608 InjectRtcpPacket(bye);
609
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000610 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700611 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000612 EXPECT_TRUE(received_blocks.empty());
613
danilchap1e714ae2016-09-05 09:57:22 -0700614 // Inject packet again.
615 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
616 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
617 InjectRtcpPacket(rr);
618
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000619 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700620 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000621 EXPECT_EQ(2u, received_blocks.size());
622}
623
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200624TEST_F(RtcpReceiverTest, InjectByePacketRemovesReferenceTimeInfo) {
625 rtcp::ExtendedReports xr;
626 xr.SetSenderSsrc(kSenderSsrc);
627 rtcp::Rrtr rrtr;
628 rrtr.SetNtp(NtpTime(0x10203, 0x40506));
629 xr.SetRrtr(rrtr);
630 InjectRtcpPacket(xr);
631
632 rtcp::Bye bye;
633 bye.SetSenderSsrc(kSenderSsrc);
634 InjectRtcpPacket(bye);
635
636 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
637}
638
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000639TEST_F(RtcpReceiverTest, InjectPliPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000640 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700641 pli.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700642
643 EXPECT_CALL(
644 packet_type_counter_observer_,
645 RtcpPacketTypesCounterUpdated(
646 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 1)));
647 EXPECT_CALL(intra_frame_observer_,
648 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
649 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000650}
651
652TEST_F(RtcpReceiverTest, PliPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000653 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700654 pli.SetMediaSsrc(kNotToUsSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700655
656 EXPECT_CALL(
657 packet_type_counter_observer_,
658 RtcpPacketTypesCounterUpdated(
659 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 0)));
660 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
661 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000662}
663
664TEST_F(RtcpReceiverTest, InjectFirPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000665 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700666 fir.AddRequestTo(kReceiverMainSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700667
668 EXPECT_CALL(
669 packet_type_counter_observer_,
670 RtcpPacketTypesCounterUpdated(
671 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::fir_packets, 1)));
672 EXPECT_CALL(intra_frame_observer_,
673 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
674 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000675}
676
677TEST_F(RtcpReceiverTest, FirPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000678 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700679 fir.AddRequestTo(kNotToUsSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700680
681 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
682 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000683}
684
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100685TEST_F(RtcpReceiverTest, ExtendedReportsPacketWithZeroReportBlocksIgnored) {
686 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700687 xr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700688
689 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000690}
691
danilchap1e714ae2016-09-05 09:57:22 -0700692// VOiP reports are ignored.
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100693TEST_F(RtcpReceiverTest, InjectExtendedReportsVoipPacket) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000694 const uint8_t kLossRate = 123;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000695 rtcp::VoipMetric voip_metric;
danilchap822a16f2016-09-27 09:27:47 -0700696 voip_metric.SetMediaSsrc(kReceiverMainSsrc);
danilchap91941ae2015-12-15 07:06:36 -0800697 RTCPVoIPMetric metric;
698 metric.lossRate = kLossRate;
danilchap822a16f2016-09-27 09:27:47 -0700699 voip_metric.SetVoipMetric(metric);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100700 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700701 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700702 xr.SetVoipMetric(voip_metric);
danilchap1e714ae2016-09-05 09:57:22 -0700703
704 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000705}
706
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100707TEST_F(RtcpReceiverTest, ExtendedReportsVoipPacketNotToUsIgnored) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000708 rtcp::VoipMetric voip_metric;
danilchap822a16f2016-09-27 09:27:47 -0700709 voip_metric.SetMediaSsrc(kNotToUsSsrc);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100710 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700711 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700712 xr.SetVoipMetric(voip_metric);
danilchap1e714ae2016-09-05 09:57:22 -0700713
714 InjectRtcpPacket(xr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000715}
716
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100717TEST_F(RtcpReceiverTest, InjectExtendedReportsReceiverReferenceTimePacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700718 const NtpTime kNtp(0x10203, 0x40506);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000719 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700720 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100721 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700722 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700723 xr.SetRrtr(rrtr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000724
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200725 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
726 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
727 EXPECT_THAT(last_xr_rtis, IsEmpty());
danilchap1e714ae2016-09-05 09:57:22 -0700728
729 InjectRtcpPacket(xr);
730
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200731 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
732 ASSERT_THAT(last_xr_rtis, SizeIs(1));
733 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
734 EXPECT_EQ(CompactNtp(kNtp), last_xr_rtis[0].last_rr);
735 EXPECT_EQ(0U, last_xr_rtis[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000736}
737
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100738TEST_F(RtcpReceiverTest, ExtendedReportsDlrrPacketNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700739 // Allow calculate rtt using dlrr/rrtr, simulating media receiver side.
740 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000741
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100742 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700743 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700744 xr.AddDlrrItem(ReceiveTimeInfo(kNotToUsSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700745
746 InjectRtcpPacket(xr);
747
748 int64_t rtt_ms = 0;
749 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000750}
751
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100752TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithSubBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700753 const uint32_t kLastRR = 0x12345;
754 const uint32_t kDelay = 0x23456;
755 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
756 int64_t rtt_ms = 0;
757 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000758
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100759 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700760 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700761 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
danilchap1e714ae2016-09-05 09:57:22 -0700762
763 InjectRtcpPacket(xr);
764
danilchap37953762017-02-09 11:15:25 -0800765 uint32_t compact_ntp_now = CompactNtp(system_clock_.CurrentNtpTime());
danilchap1e714ae2016-09-05 09:57:22 -0700766 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
767 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
768 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000769}
770
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100771TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithMultipleSubBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700772 const uint32_t kLastRR = 0x12345;
773 const uint32_t kDelay = 0x56789;
774 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000775
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100776 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700777 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700778 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
779 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 1, 0x12345, 0x67890));
780 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 2, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700781
782 InjectRtcpPacket(xr);
783
danilchap37953762017-02-09 11:15:25 -0800784 uint32_t compact_ntp_now = CompactNtp(system_clock_.CurrentNtpTime());
danilchap1e714ae2016-09-05 09:57:22 -0700785 int64_t rtt_ms = 0;
786 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
787 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
788 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000789}
790
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100791TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithMultipleReportBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700792 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000793
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000794 rtcp::Rrtr rrtr;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000795 rtcp::VoipMetric metric;
danilchap822a16f2016-09-27 09:27:47 -0700796 metric.SetMediaSsrc(kReceiverMainSsrc);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100797 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700798 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700799 xr.SetRrtr(rrtr);
800 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
801 xr.SetVoipMetric(metric);
danilchap1e714ae2016-09-05 09:57:22 -0700802
803 InjectRtcpPacket(xr);
804
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 int64_t rtt_ms = 0;
809 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000810}
811
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100812TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithUnknownReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700813 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000814
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000815 rtcp::Rrtr rrtr;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000816 rtcp::VoipMetric metric;
danilchap822a16f2016-09-27 09:27:47 -0700817 metric.SetMediaSsrc(kReceiverMainSsrc);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100818 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700819 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700820 xr.SetRrtr(rrtr);
821 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
822 xr.SetVoipMetric(metric);
danilchap1e714ae2016-09-05 09:57:22 -0700823
danilchap69e59e62016-02-17 03:11:42 -0800824 rtc::Buffer packet = xr.Build();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000825 // Modify the DLRR block to have an unsupported block type, from 5 to 6.
danilchap1e714ae2016-09-05 09:57:22 -0700826 ASSERT_EQ(5, packet.data()[20]);
827 packet.data()[20] = 6;
828 InjectRtcpPacket(packet);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000829
danilchap1e714ae2016-09-05 09:57:22 -0700830 // Validate Rrtr was received and processed.
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200831 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
832 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
833 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700834 // Validate Dlrr report wasn't processed.
835 int64_t rtt_ms = 0;
836 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000837}
838
danilchap1e714ae2016-09-05 09:57:22 -0700839TEST_F(RtcpReceiverTest, TestExtendedReportsRrRttInitiallyFalse) {
840 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
841
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000842 int64_t rtt_ms;
danilchap1e714ae2016-09-05 09:57:22 -0700843 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000844}
845
danilchap1e714ae2016-09-05 09:57:22 -0700846TEST_F(RtcpReceiverTest, RttCalculatedAfterExtendedReportsDlrr) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100847 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100848 const int64_t kRttMs = rand.Rand(1, 9 * 3600 * 1000);
849 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
850 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700851 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
danilchap37953762017-02-09 11:15:25 -0800852 NtpTime now = system_clock_.CurrentNtpTime();
Danil Chapovalova094fd12016-02-22 18:59:36 +0100853 uint32_t sent_ntp = CompactNtp(now);
854 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
855
Danil Chapovalova094fd12016-02-22 18:59:36 +0100856 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700857 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700858 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700859
860 InjectRtcpPacket(xr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100861
862 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700863 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100864 EXPECT_NEAR(kRttMs, rtt_ms, 1);
865}
866
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100867TEST_F(RtcpReceiverTest, XrDlrrCalculatesNegativeRttAsOne) {
868 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100869 const int64_t kRttMs = rand.Rand(-3600 * 1000, -1);
870 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
871 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
danilchap37953762017-02-09 11:15:25 -0800872 NtpTime now = system_clock_.CurrentNtpTime();
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100873 uint32_t sent_ntp = CompactNtp(now);
874 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
danilchap1e714ae2016-09-05 09:57:22 -0700875 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100876
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100877 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700878 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700879 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700880
881 InjectRtcpPacket(xr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100882
883 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700884 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100885 EXPECT_EQ(1, rtt_ms);
886}
887
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200888TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfoInitiallyEmpty) {
889 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000890}
891
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200892TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfo) {
Danil Chapovalovfc47ed62015-12-07 14:46:35 +0100893 const NtpTime kNtp(0x10203, 0x40506);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100894 const uint32_t kNtpMid = CompactNtp(kNtp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000895
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000896 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700897 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100898 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700899 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700900 xr.SetRrtr(rrtr);
danilchap1e714ae2016-09-05 09:57:22 -0700901
902 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000903
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000904 system_clock_.AdvanceTimeMilliseconds(1000);
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200905
906 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
907 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
908 ASSERT_THAT(last_xr_rtis, SizeIs(1));
909 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
910 EXPECT_EQ(kNtpMid, last_xr_rtis[0].last_rr);
911 EXPECT_EQ(65536U, last_xr_rtis[0].delay_since_last_rr);
912}
913
914TEST_F(RtcpReceiverTest,
915 ReceivedRrtrFromSameSsrcUpdatesReceivedReferenceTimeInfo) {
916 const NtpTime kNtp1(0x10203, 0x40506);
917 const NtpTime kNtp2(0x11223, 0x44556);
918 const int64_t kDelayMs = 2000;
919
920 rtcp::ExtendedReports xr;
921 xr.SetSenderSsrc(kSenderSsrc);
922 rtcp::Rrtr rrtr1;
923 rrtr1.SetNtp(kNtp1);
924 xr.SetRrtr(rrtr1);
925 InjectRtcpPacket(xr);
926 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
927 rtcp::Rrtr rrtr2;
928 rrtr2.SetNtp(kNtp2);
929 xr.SetRrtr(rrtr2);
930 InjectRtcpPacket(xr);
931 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
932
933 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
934 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
935 ASSERT_THAT(last_xr_rtis, SizeIs(1));
936 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
937 EXPECT_EQ(CompactNtp(kNtp2), last_xr_rtis[0].last_rr);
938 EXPECT_EQ(kDelayMs * 65536 / 1000, last_xr_rtis[0].delay_since_last_rr);
939}
940
941TEST_F(RtcpReceiverTest, StoresLastReceivedRrtrPerSsrc) {
942 const size_t kNumBufferedReports = 1;
943 const size_t kNumReports =
944 rtcp::ExtendedReports::kMaxNumberOfDlrrItems + kNumBufferedReports;
945 for (size_t i = 0; i < kNumReports; ++i) {
946 rtcp::ExtendedReports xr;
947 xr.SetSenderSsrc(i * 100);
948 rtcp::Rrtr rrtr;
949 rrtr.SetNtp(NtpTime(i * 200, i * 300));
950 xr.SetRrtr(rrtr);
951 InjectRtcpPacket(xr);
952 system_clock_.AdvanceTimeMilliseconds(1000);
953 }
954
955 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
956 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
957 ASSERT_THAT(last_xr_rtis,
958 SizeIs(rtcp::ExtendedReports::kMaxNumberOfDlrrItems));
959 for (size_t i = 0; i < rtcp::ExtendedReports::kMaxNumberOfDlrrItems; ++i) {
960 EXPECT_EQ(i * 100, last_xr_rtis[i].ssrc);
961 EXPECT_EQ(CompactNtp(NtpTime(i * 200, i * 300)), last_xr_rtis[i].last_rr);
962 EXPECT_EQ(65536U * (kNumReports - i), last_xr_rtis[i].delay_since_last_rr);
963 }
964
965 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
966 ASSERT_THAT(last_xr_rtis, SizeIs(kNumBufferedReports));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000967}
968
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000969TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000970 const int64_t kRtcpIntervalMs = 1000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000971 const uint16_t kSequenceNumber = 1234;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000972 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000973
974 // No RR received, shouldn't trigger a timeout.
danilchap1e714ae2016-09-05 09:57:22 -0700975 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
976 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000977
978 // Add a RR and advance the clock just enough to not trigger a timeout.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000979 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700980 rb1.SetMediaSsrc(kReceiverMainSsrc);
981 rb1.SetExtHighestSeqNum(kSequenceNumber);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000982 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700983 rr1.SetSenderSsrc(kSenderSsrc);
984 rr1.AddReportBlock(rb1);
danilchap1e714ae2016-09-05 09:57:22 -0700985
986 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
987 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
988 InjectRtcpPacket(rr1);
989
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000990 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs - 1);
danilchap1e714ae2016-09-05 09:57:22 -0700991 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
992 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000993
994 // Add a RR with the same extended max as the previous RR to trigger a
995 // sequence number timeout, but not a RR timeout.
danilchap1e714ae2016-09-05 09:57:22 -0700996 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
997 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
998 InjectRtcpPacket(rr1);
999
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001000 system_clock_.AdvanceTimeMilliseconds(2);
danilchap1e714ae2016-09-05 09:57:22 -07001001 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
1002 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001003
1004 // Advance clock enough to trigger an RR timeout too.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001005 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -07001006 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001007
1008 // We should only get one timeout even though we still haven't received a new
1009 // RR.
danilchap1e714ae2016-09-05 09:57:22 -07001010 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
1011 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001012
1013 // Add a new RR with increase sequence number to reset timers.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001014 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001015 rb2.SetMediaSsrc(kReceiverMainSsrc);
1016 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001017 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001018 rr2.SetSenderSsrc(kSenderSsrc);
1019 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001020
1021 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1022 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1023 InjectRtcpPacket(rr2);
1024
1025 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
1026 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001027
1028 // Verify we can get a timeout again once we've received new RR.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001029 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -07001030 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1031 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1032 InjectRtcpPacket(rr2);
1033
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001034 system_clock_.AdvanceTimeMilliseconds(kRtcpIntervalMs + 1);
danilchap1e714ae2016-09-05 09:57:22 -07001035 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
1036 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
1037
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001038 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -07001039 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001040}
1041
hta@webrtc.org47059b52012-05-02 07:46:22 +00001042TEST_F(RtcpReceiverTest, TmmbrReceivedWithNoIncomingPacket) {
danilchap1e714ae2016-09-05 09:57:22 -07001043 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001044}
1045
1046TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) {
danilchap1e714ae2016-09-05 09:57:22 -07001047 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001048 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001049 tmmbr.SetSenderSsrc(kSenderSsrc);
1050 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001051 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);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001056
danilchap1e714ae2016-09-05 09:57:22 -07001057 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1058 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(SizeIs(1)));
1059 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1060 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1061 InjectRtcpPacket(compound);
1062
1063 std::vector<rtcp::TmmbItem> tmmbr_received = rtcp_receiver_.TmmbrReceived();
1064 ASSERT_EQ(1u, tmmbr_received.size());
1065 EXPECT_EQ(kBitrateBps, tmmbr_received[0].bitrate_bps());
1066 EXPECT_EQ(kSenderSsrc, tmmbr_received[0].ssrc());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001067}
1068
1069TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -07001070 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001071 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001072 tmmbr.SetSenderSsrc(kSenderSsrc);
1073 tmmbr.AddTmmbr(rtcp::TmmbItem(kNotToUsSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001074
1075 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001076 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001077 rtcp::CompoundPacket compound;
1078 compound.Append(&sr);
1079 compound.Append(&tmmbr);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001080
danilchap1e714ae2016-09-05 09:57:22 -07001081 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1082 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1083 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1084 InjectRtcpPacket(compound);
1085
1086 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001087}
1088
1089TEST_F(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001090 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001091 tmmbr.SetSenderSsrc(kSenderSsrc);
1092 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 0, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001093 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001094 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001095 rtcp::CompoundPacket compound;
1096 compound.Append(&sr);
1097 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001098
danilchap1e714ae2016-09-05 09:57:22 -07001099 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1100 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1101 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1102 InjectRtcpPacket(compound);
1103
1104 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001105}
1106
hta@webrtc.org404843e2012-05-02 09:56:45 +00001107TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001108 // Inject 3 packets "from" kSenderSsrc, kSenderSsrc+1, kSenderSsrc+2.
hta@webrtc.org404843e2012-05-02 09:56:45 +00001109 // The times of arrival are starttime + 0, starttime + 5 and starttime + 10.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001110 for (uint32_t ssrc = kSenderSsrc; ssrc < kSenderSsrc + 3; ++ssrc) {
1111 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001112 tmmbr.SetSenderSsrc(ssrc);
1113 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 30000, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001114 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001115 sr.SetSenderSsrc(ssrc);
danilchap7a4116a2016-03-14 08:19:28 -07001116 rtcp::CompoundPacket compound;
1117 compound.Append(&sr);
1118 compound.Append(&tmmbr);
danilchap1e714ae2016-09-05 09:57:22 -07001119
1120 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1121 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(_));
1122 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1123 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_));
1124 InjectRtcpPacket(compound);
1125
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001126 // 5 seconds between each packet.
1127 system_clock_.AdvanceTimeMilliseconds(5000);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001128 }
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001129 // It is now starttime + 15.
danilchap1e714ae2016-09-05 09:57:22 -07001130 std::vector<rtcp::TmmbItem> candidate_set = rtcp_receiver_.TmmbrReceived();
1131 ASSERT_EQ(3u, candidate_set.size());
1132 EXPECT_EQ(30000U, candidate_set[0].bitrate_bps());
1133
hta@webrtc.org404843e2012-05-02 09:56:45 +00001134 // We expect the timeout to be 25 seconds. Advance the clock by 12
1135 // seconds, timing out the first packet.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001136 system_clock_.AdvanceTimeMilliseconds(12000);
danilchap1e714ae2016-09-05 09:57:22 -07001137 candidate_set = rtcp_receiver_.TmmbrReceived();
1138 ASSERT_EQ(2u, candidate_set.size());
danilchap287e5482016-08-16 15:15:39 -07001139 EXPECT_EQ(kSenderSsrc + 1, candidate_set[0].ssrc());
hta@webrtc.org404843e2012-05-02 09:56:45 +00001140}
1141
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001142TEST_F(RtcpReceiverTest, Callbacks) {
danilchap1e714ae2016-09-05 09:57:22 -07001143 MockRtcpCallbackImpl callback;
1144 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001145
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001146 const uint8_t kFractionLoss = 3;
1147 const uint32_t kCumulativeLoss = 7;
1148 const uint32_t kJitter = 9;
1149 const uint16_t kSequenceNumber = 1234;
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001150
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001151 // First packet, all numbers should just propagate.
1152 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -07001153 rb1.SetMediaSsrc(kReceiverMainSsrc);
1154 rb1.SetExtHighestSeqNum(kSequenceNumber);
1155 rb1.SetFractionLost(kFractionLoss);
1156 rb1.SetCumulativeLost(kCumulativeLoss);
1157 rb1.SetJitter(kJitter);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001158
1159 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -07001160 rr1.SetSenderSsrc(kSenderSsrc);
1161 rr1.AddReportBlock(rb1);
srte186d9c32017-08-04 05:03:53 -07001162 EXPECT_CALL(callback,
1163 StatisticsUpdated(
1164 AllOf(Field(&RtcpStatistics::fraction_lost, kFractionLoss),
1165 Field(&RtcpStatistics::packets_lost, kCumulativeLoss),
1166 Field(&RtcpStatistics::extended_highest_sequence_number,
1167 kSequenceNumber),
1168 Field(&RtcpStatistics::jitter, kJitter)),
1169 kReceiverMainSsrc));
danilchap1e714ae2016-09-05 09:57:22 -07001170 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1171 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1172 InjectRtcpPacket(rr1);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001173
danilchap1e714ae2016-09-05 09:57:22 -07001174 rtcp_receiver_.RegisterRtcpStatisticsCallback(nullptr);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001175
danilchap1e714ae2016-09-05 09:57:22 -07001176 // Add arbitrary numbers, callback should not be called.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001177 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001178 rb2.SetMediaSsrc(kReceiverMainSsrc);
1179 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
1180 rb2.SetFractionLost(42);
1181 rb2.SetCumulativeLost(137);
1182 rb2.SetJitter(4711);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001183
1184 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001185 rr2.SetSenderSsrc(kSenderSsrc);
1186 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001187
1188 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1189 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1190 EXPECT_CALL(callback, StatisticsUpdated(_, _)).Times(0);
1191 InjectRtcpPacket(rr2);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001192}
hta@webrtc.org404843e2012-05-02 09:56:45 +00001193
sprang49f9cdb2015-10-01 03:06:57 -07001194TEST_F(RtcpReceiverTest, ReceivesTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001195 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
danilchap1e714ae2016-09-05 09:57:22 -07001201 EXPECT_CALL(
1202 transport_feedback_observer_,
1203 OnTransportFeedback(AllOf(
1204 Property(&rtcp::TransportFeedback::media_ssrc, kReceiverMainSsrc),
1205 Property(&rtcp::TransportFeedback::sender_ssrc, kSenderSsrc))));
1206 InjectRtcpPacket(packet);
sprang49f9cdb2015-10-01 03:06:57 -07001207}
1208
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001209TEST_F(RtcpReceiverTest, ReceivesRemb) {
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001210 const uint32_t kBitrateBps = 500000;
1211 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001212 remb.SetSenderSsrc(kSenderSsrc);
1213 remb.SetBitrateBps(kBitrateBps);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001214
danilchap1e714ae2016-09-05 09:57:22 -07001215 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1216 InjectRtcpPacket(remb);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001217}
1218
sprang49f9cdb2015-10-01 03:06:57 -07001219TEST_F(RtcpReceiverTest, HandlesInvalidTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001220 // Send a compound packet with a TransportFeedback followed by something else.
1221 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001222 packet.SetMediaSsrc(kReceiverMainSsrc);
1223 packet.SetSenderSsrc(kSenderSsrc);
1224 packet.SetBase(1, 1000);
1225 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001226
1227 static uint32_t kBitrateBps = 50000;
1228 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001229 remb.SetSenderSsrc(kSenderSsrc);
1230 remb.SetBitrateBps(kBitrateBps);
danilchap7a4116a2016-03-14 08:19:28 -07001231 rtcp::CompoundPacket compound;
1232 compound.Append(&packet);
1233 compound.Append(&remb);
1234 rtc::Buffer built_packet = compound.Build();
sprang49f9cdb2015-10-01 03:06:57 -07001235
1236 // Modify the TransportFeedback packet so that it is invalid.
1237 const size_t kStatusCountOffset = 14;
Yves Gerey665174f2018-06-19 15:03:05 +02001238 ByteWriter<uint16_t>::WriteBigEndian(&built_packet.data()[kStatusCountOffset],
1239 42);
sprang49f9cdb2015-10-01 03:06:57 -07001240
danilchap1e714ae2016-09-05 09:57:22 -07001241 // Stress no transport feedback is expected.
1242 EXPECT_CALL(transport_feedback_observer_, OnTransportFeedback(_)).Times(0);
1243 // But remb should be processed and cause a callback
1244 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1245 InjectRtcpPacket(built_packet);
sprang49f9cdb2015-10-01 03:06:57 -07001246}
1247
danilchap1e714ae2016-09-05 09:57:22 -07001248TEST_F(RtcpReceiverTest, Nack) {
1249 const uint16_t kNackList1[] = {1, 2, 3, 5};
danilchap142f0192016-10-20 08:22:42 -07001250 const uint16_t kNackList23[] = {5, 7, 30, 40, 41, 58, 59, 61, 63};
1251 const size_t kNackListLength2 = 4;
1252 const size_t kNackListLength3 = arraysize(kNackList23) - kNackListLength2;
danilchap1e714ae2016-09-05 09:57:22 -07001253 std::set<uint16_t> nack_set;
1254 nack_set.insert(std::begin(kNackList1), std::end(kNackList1));
danilchap142f0192016-10-20 08:22:42 -07001255 nack_set.insert(std::begin(kNackList23), std::end(kNackList23));
danilchap1e714ae2016-09-05 09:57:22 -07001256
danilchap142f0192016-10-20 08:22:42 -07001257 rtcp::Nack nack1;
1258 nack1.SetSenderSsrc(kSenderSsrc);
1259 nack1.SetMediaSsrc(kReceiverMainSsrc);
1260 nack1.SetPacketIds(kNackList1, arraysize(kNackList1));
danilchap1e714ae2016-09-05 09:57:22 -07001261
1262 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList1)));
danilchap1e714ae2016-09-05 09:57:22 -07001263 EXPECT_CALL(packet_type_counter_observer_,
1264 RtcpPacketTypesCounterUpdated(
1265 kReceiverMainSsrc,
1266 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
danilchap142f0192016-10-20 08:22:42 -07001267 arraysize(kNackList1)),
1268 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1269 arraysize(kNackList1)))));
1270 InjectRtcpPacket(nack1);
1271
1272 rtcp::Nack nack2;
1273 nack2.SetSenderSsrc(kSenderSsrc);
1274 nack2.SetMediaSsrc(kReceiverMainSsrc);
1275 nack2.SetPacketIds(kNackList23, kNackListLength2);
1276
1277 rtcp::Nack nack3;
1278 nack3.SetSenderSsrc(kSenderSsrc);
1279 nack3.SetMediaSsrc(kReceiverMainSsrc);
1280 nack3.SetPacketIds(kNackList23 + kNackListLength2, kNackListLength3);
1281
1282 rtcp::CompoundPacket two_nacks;
1283 two_nacks.Append(&nack2);
1284 two_nacks.Append(&nack3);
1285
1286 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList23)));
1287 EXPECT_CALL(packet_type_counter_observer_,
1288 RtcpPacketTypesCounterUpdated(
1289 kReceiverMainSsrc,
1290 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
1291 arraysize(kNackList1) + arraysize(kNackList23)),
danilchap1e714ae2016-09-05 09:57:22 -07001292 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1293 nack_set.size()))));
danilchap142f0192016-10-20 08:22:42 -07001294 InjectRtcpPacket(two_nacks);
danilchap1e714ae2016-09-05 09:57:22 -07001295}
1296
1297TEST_F(RtcpReceiverTest, NackNotForUsIgnored) {
1298 const uint16_t kNackList1[] = {1, 2, 3, 5};
1299 const size_t kNackListLength1 = std::end(kNackList1) - std::begin(kNackList1);
1300
1301 rtcp::Nack nack;
danilchap822a16f2016-09-27 09:27:47 -07001302 nack.SetSenderSsrc(kSenderSsrc);
1303 nack.SetMediaSsrc(kNotToUsSsrc);
1304 nack.SetPacketIds(kNackList1, kNackListLength1);
danilchap1e714ae2016-09-05 09:57:22 -07001305
1306 EXPECT_CALL(packet_type_counter_observer_,
1307 RtcpPacketTypesCounterUpdated(
1308 _, Field(&RtcpPacketTypeCounter::nack_requests, 0)));
1309 InjectRtcpPacket(nack);
1310}
1311
1312TEST_F(RtcpReceiverTest, ForceSenderReport) {
1313 rtcp::RapidResyncRequest rr;
danilchap822a16f2016-09-27 09:27:47 -07001314 rr.SetSenderSsrc(kSenderSsrc);
1315 rr.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -07001316
1317 EXPECT_CALL(rtp_rtcp_impl_, OnRequestSendReport());
1318 InjectRtcpPacket(rr);
1319}
hta@webrtc.org47059b52012-05-02 07:46:22 +00001320
spranga790d832016-12-02 07:29:44 -08001321TEST_F(RtcpReceiverTest, ReceivesTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001322 VideoBitrateAllocation expected_allocation;
spranga790d832016-12-02 07:29:44 -08001323 expected_allocation.SetBitrate(0, 0, 10000);
1324 expected_allocation.SetBitrate(0, 1, 20000);
1325 expected_allocation.SetBitrate(1, 0, 40000);
1326 expected_allocation.SetBitrate(1, 1, 80000);
1327
1328 rtcp::TargetBitrate bitrate;
1329 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1330 bitrate.AddTargetBitrate(0, 1, expected_allocation.GetBitrate(0, 1) / 1000);
1331 bitrate.AddTargetBitrate(1, 0, expected_allocation.GetBitrate(1, 0) / 1000);
1332 bitrate.AddTargetBitrate(1, 1, expected_allocation.GetBitrate(1, 1) / 1000);
1333
1334 rtcp::ExtendedReports xr;
1335 xr.SetTargetBitrate(bitrate);
1336
sprangb32aaf92017-08-28 05:49:12 -07001337 // Wrong sender ssrc, target bitrate should be discarded.
1338 xr.SetSenderSsrc(kSenderSsrc + 1);
1339 EXPECT_CALL(bitrate_allocation_observer_,
1340 OnBitrateAllocationUpdated(expected_allocation))
1341 .Times(0);
1342 InjectRtcpPacket(xr);
1343
1344 // Set correct ssrc, callback should be called once.
1345 xr.SetSenderSsrc(kSenderSsrc);
spranga790d832016-12-02 07:29:44 -08001346 EXPECT_CALL(bitrate_allocation_observer_,
1347 OnBitrateAllocationUpdated(expected_allocation));
1348 InjectRtcpPacket(xr);
1349}
1350
sprang6d314c72016-12-06 06:08:53 -08001351TEST_F(RtcpReceiverTest, HandlesIncorrectTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001352 VideoBitrateAllocation expected_allocation;
sprang6d314c72016-12-06 06:08:53 -08001353 expected_allocation.SetBitrate(0, 0, 10000);
1354
1355 rtcp::TargetBitrate bitrate;
1356 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1357 bitrate.AddTargetBitrate(0, kMaxTemporalStreams, 20000);
1358 bitrate.AddTargetBitrate(kMaxSpatialLayers, 0, 40000);
1359
1360 rtcp::ExtendedReports xr;
1361 xr.SetTargetBitrate(bitrate);
sprangb32aaf92017-08-28 05:49:12 -07001362 xr.SetSenderSsrc(kSenderSsrc);
sprang6d314c72016-12-06 06:08:53 -08001363
1364 EXPECT_CALL(bitrate_allocation_observer_,
1365 OnBitrateAllocationUpdated(expected_allocation));
1366 InjectRtcpPacket(xr);
1367}
1368
hta@webrtc.org47059b52012-05-02 07:46:22 +00001369} // namespace webrtc