blob: e1483a42f28b910f158c3323da89e7758da74a0b [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"
Sebastian Janssonef9daee2018-02-22 14:49:02 +010016#include "modules/rtp_rtcp/mocks/mock_rtcp_bandwidth_observer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "modules/rtp_rtcp/source/byte_io.h"
18#include "modules/rtp_rtcp/source/rtcp_packet.h"
19#include "modules/rtp_rtcp/source/rtcp_packet/app.h"
20#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
21#include "modules/rtp_rtcp/source/rtcp_packet/compound_packet.h"
22#include "modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.h"
23#include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
24#include "modules/rtp_rtcp/source/rtcp_packet/fir.h"
25#include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
26#include "modules/rtp_rtcp/source/rtcp_packet/pli.h"
27#include "modules/rtp_rtcp/source/rtcp_packet/rapid_resync_request.h"
28#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
29#include "modules/rtp_rtcp/source/rtcp_packet/remb.h"
30#include "modules/rtp_rtcp/source/rtcp_packet/sdes.h"
31#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
32#include "modules/rtp_rtcp/source/rtcp_packet/tmmbr.h"
33#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
34#include "modules/rtp_rtcp/source/rtcp_receiver.h"
35#include "modules/rtp_rtcp/source/time_util.h"
36#include "rtc_base/arraysize.h"
37#include "rtc_base/random.h"
38#include "system_wrappers/include/ntp_time.h"
39#include "test/gmock.h"
40#include "test/gtest.h"
hta@webrtc.org47059b52012-05-02 07:46:22 +000041
42namespace webrtc {
danilchap1e714ae2016-09-05 09:57:22 -070043namespace {
hta@webrtc.org47059b52012-05-02 07:46:22 +000044
danilchap1e714ae2016-09-05 09:57:22 -070045using ::testing::_;
46using ::testing::AllOf;
47using ::testing::ElementsAreArray;
48using ::testing::Field;
49using ::testing::IsEmpty;
50using ::testing::NiceMock;
51using ::testing::Property;
52using ::testing::SizeIs;
53using ::testing::StrEq;
54using ::testing::StrictMock;
55using ::testing::UnorderedElementsAre;
danilchap80ac24d2016-10-31 08:40:47 -070056using rtcp::ReceiveTimeInfo;
hta@webrtc.org47059b52012-05-02 07:46:22 +000057
danilchap1e714ae2016-09-05 09:57:22 -070058class MockRtcpPacketTypeCounterObserver : public RtcpPacketTypeCounterObserver {
hta@webrtc.org47059b52012-05-02 07:46:22 +000059 public:
danilchap1e714ae2016-09-05 09:57:22 -070060 MOCK_METHOD2(RtcpPacketTypesCounterUpdated,
61 void(uint32_t, const RtcpPacketTypeCounter&));
hta@webrtc.org47059b52012-05-02 07:46:22 +000062};
63
danilchap1e714ae2016-09-05 09:57:22 -070064class MockRtcpIntraFrameObserver : public RtcpIntraFrameObserver {
65 public:
66 MOCK_METHOD1(OnReceivedIntraFrameRequest, void(uint32_t));
danilchap1e714ae2016-09-05 09:57:22 -070067};
68
Elad Alon0a8562e2019-04-09 11:55:13 +020069class MockRtcpLossNotificationObserver : public RtcpLossNotificationObserver {
70 public:
71 ~MockRtcpLossNotificationObserver() override = default;
72 MOCK_METHOD4(OnReceivedLossNotification,
73 void(uint32_t ssrc,
74 uint16_t seq_num_of_last_decodable,
75 uint16_t seq_num_of_last_received,
76 bool decodability_flag));
77};
78
danilchap1e714ae2016-09-05 09:57:22 -070079class MockRtcpCallbackImpl : public RtcpStatisticsCallback {
80 public:
81 MOCK_METHOD2(StatisticsUpdated, void(const RtcpStatistics&, uint32_t));
82 MOCK_METHOD2(CNameChanged, void(const char*, uint32_t));
83};
84
85class MockTransportFeedbackObserver : public TransportFeedbackObserver {
86 public:
elad.alond12a8e12017-03-23 11:04:48 -070087 MOCK_METHOD3(AddPacket, void(uint32_t, uint16_t, size_t));
88 MOCK_METHOD4(AddPacket,
89 void(uint32_t, uint16_t, size_t, const PacedPacketInfo&));
danilchap1e714ae2016-09-05 09:57:22 -070090 MOCK_METHOD1(OnTransportFeedback, void(const rtcp::TransportFeedback&));
elad.alonf9490002017-03-06 05:32:21 -080091 MOCK_CONST_METHOD0(GetTransportFeedbackVector, std::vector<PacketFeedback>());
danilchap1e714ae2016-09-05 09:57:22 -070092};
93
danilchap1e714ae2016-09-05 09:57:22 -070094class MockModuleRtpRtcp : public RTCPReceiver::ModuleRtpRtcp {
95 public:
96 MOCK_METHOD1(SetTmmbn, void(std::vector<rtcp::TmmbItem>));
97 MOCK_METHOD0(OnRequestSendReport, void());
98 MOCK_METHOD1(OnReceivedNack, void(const std::vector<uint16_t>&));
99 MOCK_METHOD1(OnReceivedRtcpReportBlocks, void(const ReportBlockList&));
100};
101
spranga790d832016-12-02 07:29:44 -0800102class MockVideoBitrateAllocationObserver
103 : public VideoBitrateAllocationObserver {
104 public:
105 MOCK_METHOD1(OnBitrateAllocationUpdated,
Erik Språng566124a2018-04-23 12:32:22 +0200106 void(const VideoBitrateAllocation& allocation));
spranga790d832016-12-02 07:29:44 -0800107};
108
danilchap1e714ae2016-09-05 09:57:22 -0700109// SSRC of remote peer, that sends rtcp packet to the rtcp receiver under test.
110constexpr uint32_t kSenderSsrc = 0x10203;
111// SSRCs of local peer, that rtcp packet addressed to.
112constexpr uint32_t kReceiverMainSsrc = 0x123456;
113// RtcpReceiver can accept several ssrc, e.g. regular and rtx streams.
114constexpr uint32_t kReceiverExtraSsrc = 0x1234567;
115// SSRCs to ignore (i.e. not configured in RtcpReceiver).
116constexpr uint32_t kNotToUsSsrc = 0x654321;
117constexpr uint32_t kUnknownSenderSsrc = 0x54321;
118
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800119constexpr int64_t kRtcpIntervalMs = 1000;
120
danilchap1e714ae2016-09-05 09:57:22 -0700121} // namespace
122
hta@webrtc.org47059b52012-05-02 07:46:22 +0000123class RtcpReceiverTest : public ::testing::Test {
124 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000125 RtcpReceiverTest()
danilchap1e714ae2016-09-05 09:57:22 -0700126 : system_clock_(1335900000),
127 rtcp_receiver_(&system_clock_,
128 false,
129 &packet_type_counter_observer_,
130 &bandwidth_observer_,
131 &intra_frame_observer_,
Elad Alon0a8562e2019-04-09 11:55:13 +0200132 &rtcp_loss_notification_observer_,
danilchap1e714ae2016-09-05 09:57:22 -0700133 &transport_feedback_observer_,
spranga790d832016-12-02 07:29:44 -0800134 &bitrate_allocation_observer_,
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800135 kRtcpIntervalMs,
danilchap1e714ae2016-09-05 09:57:22 -0700136 &rtp_rtcp_impl_) {}
137 void SetUp() {
138 std::set<uint32_t> ssrcs = {kReceiverMainSsrc, kReceiverExtraSsrc};
danilchap1e714ae2016-09-05 09:57:22 -0700139 rtcp_receiver_.SetSsrcs(kReceiverMainSsrc, ssrcs);
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000140
danilchap1e714ae2016-09-05 09:57:22 -0700141 rtcp_receiver_.SetRemoteSSRC(kSenderSsrc);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000142 }
Erik Språng737336d2016-07-29 12:59:36 +0200143
danilchap1e714ae2016-09-05 09:57:22 -0700144 void InjectRtcpPacket(rtc::ArrayView<const uint8_t> raw) {
145 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
hta@webrtc.org47059b52012-05-02 07:46:22 +0000146 }
147
danilchap1e714ae2016-09-05 09:57:22 -0700148 void InjectRtcpPacket(const rtcp::RtcpPacket& packet) {
149 rtc::Buffer raw = packet.Build();
150 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
151 }
152
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000153 SimulatedClock system_clock_;
danilchap1e714ae2016-09-05 09:57:22 -0700154 // Callbacks to packet_type_counter_observer are frequent but most of the time
155 // are not interesting.
156 NiceMock<MockRtcpPacketTypeCounterObserver> packet_type_counter_observer_;
157 StrictMock<MockRtcpBandwidthObserver> bandwidth_observer_;
158 StrictMock<MockRtcpIntraFrameObserver> intra_frame_observer_;
Elad Alon0a8562e2019-04-09 11:55:13 +0200159 StrictMock<MockRtcpLossNotificationObserver> rtcp_loss_notification_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700160 StrictMock<MockTransportFeedbackObserver> transport_feedback_observer_;
spranga790d832016-12-02 07:29:44 -0800161 StrictMock<MockVideoBitrateAllocationObserver> bitrate_allocation_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700162 StrictMock<MockModuleRtpRtcp> rtp_rtcp_impl_;
hta@webrtc.org47059b52012-05-02 07:46:22 +0000163
danilchap1e714ae2016-09-05 09:57:22 -0700164 RTCPReceiver rtcp_receiver_;
165};
hta@webrtc.org47059b52012-05-02 07:46:22 +0000166
167TEST_F(RtcpReceiverTest, BrokenPacketIsIgnored) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000168 const uint8_t bad_packet[] = {0, 0, 0, 0};
danilchap1e714ae2016-09-05 09:57:22 -0700169 EXPECT_CALL(packet_type_counter_observer_,
170 RtcpPacketTypesCounterUpdated(_, _))
171 .Times(0);
172 InjectRtcpPacket(bad_packet);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000173}
174
danilchap50da1d32016-03-10 13:13:52 -0800175TEST_F(RtcpReceiverTest, InvalidFeedbackPacketIsIgnored) {
176 // Too short feedback packet.
danilchap1e714ae2016-09-05 09:57:22 -0700177 const uint8_t bad_packet[] = {0x81, rtcp::Rtpfb::kPacketType, 0, 0};
178
179 // TODO(danilchap): Add expectation RtcpPacketTypesCounterUpdated
180 // is not called once parser would be adjusted to avoid that callback on
181 // semi-valid packets.
182 InjectRtcpPacket(bad_packet);
danilchap50da1d32016-03-10 13:13:52 -0800183}
184
hta@webrtc.org47059b52012-05-02 07:46:22 +0000185TEST_F(RtcpReceiverTest, InjectSrPacket) {
danilchapa04d9c32017-07-25 04:03:39 -0700186 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
danilchap1e714ae2016-09-05 09:57:22 -0700187
188 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000189 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700190 sr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700191
192 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
193 EXPECT_CALL(bandwidth_observer_,
194 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
195 InjectRtcpPacket(sr);
196
danilchapa04d9c32017-07-25 04:03:39 -0700197 EXPECT_TRUE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
hta@webrtc.org47059b52012-05-02 07:46:22 +0000198}
199
danilchap1e714ae2016-09-05 09:57:22 -0700200TEST_F(RtcpReceiverTest, InjectSrPacketFromUnknownSender) {
201 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000202 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700203 sr.SetSenderSsrc(kUnknownSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700204
205 // The parser will handle report blocks in Sender Report from other than his
206 // expected peer.
207 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
208 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, now));
209 InjectRtcpPacket(sr);
210
211 // But will not flag that he's gotten sender information.
danilchapa04d9c32017-07-25 04:03:39 -0700212 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000213}
214
Danil Chapovalova094fd12016-02-22 18:59:36 +0100215TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesRTT) {
216 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100217 const int64_t kRttMs = r.Rand(1, 9 * 3600 * 1000);
218 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
219 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100220
Danil Chapovalova094fd12016-02-22 18:59:36 +0100221 int64_t rtt_ms = 0;
222 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700223 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100224
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200225 uint32_t sent_ntp =
226 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100227 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
228
229 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700230 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100231 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700232 block.SetMediaSsrc(kReceiverMainSsrc);
233 block.SetLastSr(sent_ntp);
234 block.SetDelayLastSr(kDelayNtp);
235 sr.AddReportBlock(block);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100236
danilchap1e714ae2016-09-05 09:57:22 -0700237 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
238 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
239 InjectRtcpPacket(sr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100240
241 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700242 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100243 EXPECT_NEAR(kRttMs, rtt_ms, 1);
244}
245
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100246TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesNegativeRTTAsOne) {
247 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100248 const int64_t kRttMs = r.Rand(-3600 * 1000, -1);
249 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
250 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
251
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100252 int64_t rtt_ms = 0;
253 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700254 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100255
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200256 uint32_t sent_ntp =
257 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100258 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
259
260 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700261 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100262 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700263 block.SetMediaSsrc(kReceiverMainSsrc);
264 block.SetLastSr(sent_ntp);
265 block.SetDelayLastSr(kDelayNtp);
266 sr.AddReportBlock(block);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100267
danilchap1e714ae2016-09-05 09:57:22 -0700268 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
269 EXPECT_CALL(bandwidth_observer_,
270 OnReceivedRtcpReceiverReport(SizeIs(1), _, _));
271 InjectRtcpPacket(sr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100272
273 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700274 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100275 EXPECT_EQ(1, rtt_ms);
276}
277
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100278TEST_F(
279 RtcpReceiverTest,
280 TwoReportBlocksWithLastOneWithoutLastSrCalculatesRttForBandwidthObserver) {
281 const int64_t kRttMs = 120;
282 const uint32_t kDelayNtp = 123000;
283 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
284
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200285 uint32_t sent_ntp =
286 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100287 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
288
289 rtcp::SenderReport sr;
290 sr.SetSenderSsrc(kSenderSsrc);
291 rtcp::ReportBlock block;
292 block.SetMediaSsrc(kReceiverMainSsrc);
293 block.SetLastSr(sent_ntp);
294 block.SetDelayLastSr(kDelayNtp);
295 sr.AddReportBlock(block);
296 block.SetMediaSsrc(kReceiverExtraSsrc);
297 block.SetLastSr(0);
298 sr.AddReportBlock(block);
299
300 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
301 EXPECT_CALL(bandwidth_observer_,
302 OnReceivedRtcpReceiverReport(SizeIs(2), kRttMs, _));
303 InjectRtcpPacket(sr);
304}
305
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000306TEST_F(RtcpReceiverTest, InjectRrPacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700307 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000308 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700309 rr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700310
311 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
312 EXPECT_CALL(bandwidth_observer_,
313 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
314 InjectRtcpPacket(rr);
315
danilchap1e714ae2016-09-05 09:57:22 -0700316 std::vector<RTCPReportBlock> report_blocks;
317 rtcp_receiver_.StatisticsReceived(&report_blocks);
318 EXPECT_TRUE(report_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000319}
320
321TEST_F(RtcpReceiverTest, InjectRrPacketWithReportBlockNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700322 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000323 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700324 rb.SetMediaSsrc(kNotToUsSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000325 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700326 rr.SetSenderSsrc(kSenderSsrc);
327 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000328
danilchap1e714ae2016-09-05 09:57:22 -0700329 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
330 EXPECT_CALL(bandwidth_observer_,
331 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
332 InjectRtcpPacket(rr);
333
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200334 EXPECT_EQ(0, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000335 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700336 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000337 EXPECT_TRUE(received_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000338}
339
340TEST_F(RtcpReceiverTest, InjectRrPacketWithOneReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700341 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000342
343 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700344 rb.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000345 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700346 rr.SetSenderSsrc(kSenderSsrc);
347 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000348
danilchap1e714ae2016-09-05 09:57:22 -0700349 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
350 EXPECT_CALL(bandwidth_observer_,
351 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
352 InjectRtcpPacket(rr);
353
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200354 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
355 std::vector<RTCPReportBlock> received_blocks;
356 rtcp_receiver_.StatisticsReceived(&received_blocks);
357 EXPECT_EQ(1u, received_blocks.size());
358}
359
360TEST_F(RtcpReceiverTest, InjectSrPacketWithOneReportBlock) {
361 int64_t now = system_clock_.TimeInMilliseconds();
362
363 rtcp::ReportBlock rb;
364 rb.SetMediaSsrc(kReceiverMainSsrc);
365 rtcp::SenderReport sr;
366 sr.SetSenderSsrc(kSenderSsrc);
367 sr.AddReportBlock(rb);
368
369 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
370 EXPECT_CALL(bandwidth_observer_,
371 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
372 InjectRtcpPacket(sr);
373
374 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000375 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700376 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000377 EXPECT_EQ(1u, received_blocks.size());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000378}
379
380TEST_F(RtcpReceiverTest, InjectRrPacketWithTwoReportBlocks) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000381 const uint16_t kSequenceNumbers[] = {10, 12423};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000382 const uint32_t kCumLost[] = {13, 555};
383 const uint8_t kFracLost[] = {20, 11};
danilchap1e714ae2016-09-05 09:57:22 -0700384 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000385
386 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700387 rb1.SetMediaSsrc(kReceiverMainSsrc);
388 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
389 rb1.SetFractionLost(10);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000390
391 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700392 rb2.SetMediaSsrc(kReceiverExtraSsrc);
393 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
394 rb2.SetFractionLost(0);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000395
396 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700397 rr1.SetSenderSsrc(kSenderSsrc);
398 rr1.AddReportBlock(rb1);
399 rr1.AddReportBlock(rb2);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000400
danilchap1e714ae2016-09-05 09:57:22 -0700401 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
402 EXPECT_CALL(bandwidth_observer_,
403 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
404 InjectRtcpPacket(rr1);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000405
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200406 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700407 std::vector<RTCPReportBlock> received_blocks;
408 rtcp_receiver_.StatisticsReceived(&received_blocks);
409 EXPECT_THAT(received_blocks,
srte3e69e5c2017-08-09 06:13:45 -0700410 UnorderedElementsAre(Field(&RTCPReportBlock::fraction_lost, 0),
411 Field(&RTCPReportBlock::fraction_lost, 10)));
danilchap1e714ae2016-09-05 09:57:22 -0700412
413 // Insert next receiver report with same ssrc but new values.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000414 rtcp::ReportBlock rb3;
danilchap822a16f2016-09-27 09:27:47 -0700415 rb3.SetMediaSsrc(kReceiverMainSsrc);
416 rb3.SetExtHighestSeqNum(kSequenceNumbers[0]);
417 rb3.SetFractionLost(kFracLost[0]);
418 rb3.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000419
420 rtcp::ReportBlock rb4;
danilchap822a16f2016-09-27 09:27:47 -0700421 rb4.SetMediaSsrc(kReceiverExtraSsrc);
422 rb4.SetExtHighestSeqNum(kSequenceNumbers[1]);
423 rb4.SetFractionLost(kFracLost[1]);
424 rb4.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000425
426 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700427 rr2.SetSenderSsrc(kSenderSsrc);
428 rr2.AddReportBlock(rb3);
429 rr2.AddReportBlock(rb4);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000430
danilchap1e714ae2016-09-05 09:57:22 -0700431 // Advance time to make 1st sent time and 2nd sent time different.
432 system_clock_.AdvanceTimeMilliseconds(500);
433 now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000434
danilchap1e714ae2016-09-05 09:57:22 -0700435 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
436 EXPECT_CALL(bandwidth_observer_,
437 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
438 InjectRtcpPacket(rr2);
439
440 received_blocks.clear();
441 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000442 EXPECT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700443 EXPECT_THAT(
444 received_blocks,
445 UnorderedElementsAre(
446 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
447 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
448 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
449 Field(&RTCPReportBlock::extended_highest_sequence_number,
450 kSequenceNumbers[0])),
451 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverExtraSsrc),
452 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
453 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
454 Field(&RTCPReportBlock::extended_highest_sequence_number,
455 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000456}
457
458TEST_F(RtcpReceiverTest, InjectRrPacketsFromTwoRemoteSsrcs) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000459 const uint32_t kSenderSsrc2 = 0x20304;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000460 const uint16_t kSequenceNumbers[] = {10, 12423};
Sebastian Jansson9701e0c2018-08-09 11:21:11 +0200461 const int32_t kCumLost[] = {13, 555};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000462 const uint8_t kFracLost[] = {20, 11};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000463
464 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700465 rb1.SetMediaSsrc(kReceiverMainSsrc);
466 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
467 rb1.SetFractionLost(kFracLost[0]);
468 rb1.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000469 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700470 rr1.SetSenderSsrc(kSenderSsrc);
471 rr1.AddReportBlock(rb1);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000472
danilchap1e714ae2016-09-05 09:57:22 -0700473 int64_t now = system_clock_.TimeInMilliseconds();
474
475 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
476 EXPECT_CALL(bandwidth_observer_,
477 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
478 InjectRtcpPacket(rr1);
479
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200480 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000481
482 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700483 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000484 EXPECT_EQ(1u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700485 EXPECT_EQ(kSenderSsrc, received_blocks[0].sender_ssrc);
486 EXPECT_EQ(kReceiverMainSsrc, received_blocks[0].source_ssrc);
487 EXPECT_EQ(kFracLost[0], received_blocks[0].fraction_lost);
488 EXPECT_EQ(kCumLost[0], received_blocks[0].packets_lost);
489 EXPECT_EQ(kSequenceNumbers[0],
490 received_blocks[0].extended_highest_sequence_number);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000491
492 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700493 rb2.SetMediaSsrc(kReceiverMainSsrc);
494 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
495 rb2.SetFractionLost(kFracLost[1]);
496 rb2.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000497 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700498 rr2.SetSenderSsrc(kSenderSsrc2);
499 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -0700500
501 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
502 EXPECT_CALL(bandwidth_observer_,
503 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
504 InjectRtcpPacket(rr2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000505
506 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700507 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000508 ASSERT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700509 EXPECT_THAT(
510 received_blocks,
511 UnorderedElementsAre(
512 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
513 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc),
514 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
515 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
516 Field(&RTCPReportBlock::extended_highest_sequence_number,
517 kSequenceNumbers[0])),
518 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
519 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc2),
520 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
521 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
522 Field(&RTCPReportBlock::extended_highest_sequence_number,
523 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000524}
525
526TEST_F(RtcpReceiverTest, GetRtt) {
danilchap28b03eb2016-10-05 06:59:44 -0700527 const uint32_t kSentCompactNtp = 0x1234;
528 const uint32_t kDelayCompactNtp = 0x222;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000529 // No report block received.
Erik Språng6b8d3552015-09-24 15:06:57 +0200530 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700531 -1, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000532
533 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700534 rb.SetMediaSsrc(kReceiverMainSsrc);
danilchap28b03eb2016-10-05 06:59:44 -0700535 rb.SetLastSr(kSentCompactNtp);
536 rb.SetDelayLastSr(kDelayCompactNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700537
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000538 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700539 rr.SetSenderSsrc(kSenderSsrc);
540 rr.AddReportBlock(rb);
danilchap1e714ae2016-09-05 09:57:22 -0700541 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000542
danilchap1e714ae2016-09-05 09:57:22 -0700543 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
544 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
545 InjectRtcpPacket(rr);
546
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200547 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700548 EXPECT_EQ(
549 0, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000550}
551
danilchap1e714ae2016-09-05 09:57:22 -0700552// Ij packets are ignored.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000553TEST_F(RtcpReceiverTest, InjectIjWithNoItem) {
danilchapf8506cb2015-11-13 07:33:20 -0800554 rtcp::ExtendedJitterReport ij;
danilchap1e714ae2016-09-05 09:57:22 -0700555 InjectRtcpPacket(ij);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000556}
557
danilchap1e714ae2016-09-05 09:57:22 -0700558// App packets are ignored.
559TEST_F(RtcpReceiverTest, InjectApp) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000560 rtcp::App app;
danilchap822a16f2016-09-27 09:27:47 -0700561 app.SetSubType(30);
562 app.SetName(0x17a177e);
danilchap1e714ae2016-09-05 09:57:22 -0700563 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
danilchap822a16f2016-09-27 09:27:47 -0700564 app.SetData(kData, sizeof(kData));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000565
danilchap1e714ae2016-09-05 09:57:22 -0700566 InjectRtcpPacket(app);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000567}
568
569TEST_F(RtcpReceiverTest, InjectSdesWithOneChunk) {
danilchap1e714ae2016-09-05 09:57:22 -0700570 const char kCname[] = "alice@host";
571 MockRtcpCallbackImpl callback;
572 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000573 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700574 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000575
danilchap1e714ae2016-09-05 09:57:22 -0700576 EXPECT_CALL(callback, CNameChanged(StrEq(kCname), kSenderSsrc));
577 InjectRtcpPacket(sdes);
578
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000579 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700580 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
581 EXPECT_EQ(0, strncmp(cName, kCname, RTCP_CNAME_SIZE));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000582}
583
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000584TEST_F(RtcpReceiverTest, InjectByePacket_RemovesCname) {
danilchap1e714ae2016-09-05 09:57:22 -0700585 const char kCname[] = "alice@host";
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000586 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700587 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000588
danilchap1e714ae2016-09-05 09:57:22 -0700589 InjectRtcpPacket(sdes);
590
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000591 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700592 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000593
594 // Verify that BYE removes the CNAME.
595 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700596 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700597
598 InjectRtcpPacket(bye);
599
600 EXPECT_EQ(-1, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000601}
602
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000603TEST_F(RtcpReceiverTest, InjectByePacket_RemovesReportBlocks) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000604 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700605 rb1.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000606 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700607 rb2.SetMediaSsrc(kReceiverExtraSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000608 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700609 rr.SetSenderSsrc(kSenderSsrc);
610 rr.AddReportBlock(rb1);
611 rr.AddReportBlock(rb2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000612
danilchap1e714ae2016-09-05 09:57:22 -0700613 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
614 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
615 InjectRtcpPacket(rr);
616
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000617 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700618 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000619 EXPECT_EQ(2u, received_blocks.size());
620
621 // Verify that BYE removes the report blocks.
622 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700623 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700624
625 InjectRtcpPacket(bye);
626
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000627 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700628 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000629 EXPECT_TRUE(received_blocks.empty());
630
danilchap1e714ae2016-09-05 09:57:22 -0700631 // Inject packet again.
632 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
633 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
634 InjectRtcpPacket(rr);
635
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000636 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700637 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000638 EXPECT_EQ(2u, received_blocks.size());
639}
640
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200641TEST_F(RtcpReceiverTest, InjectByePacketRemovesReferenceTimeInfo) {
642 rtcp::ExtendedReports xr;
643 xr.SetSenderSsrc(kSenderSsrc);
644 rtcp::Rrtr rrtr;
645 rrtr.SetNtp(NtpTime(0x10203, 0x40506));
646 xr.SetRrtr(rrtr);
647 InjectRtcpPacket(xr);
648
649 rtcp::Bye bye;
650 bye.SetSenderSsrc(kSenderSsrc);
651 InjectRtcpPacket(bye);
652
653 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
654}
655
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000656TEST_F(RtcpReceiverTest, InjectPliPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000657 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700658 pli.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700659
660 EXPECT_CALL(
661 packet_type_counter_observer_,
662 RtcpPacketTypesCounterUpdated(
663 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 1)));
664 EXPECT_CALL(intra_frame_observer_,
665 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
666 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000667}
668
669TEST_F(RtcpReceiverTest, PliPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000670 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700671 pli.SetMediaSsrc(kNotToUsSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700672
673 EXPECT_CALL(
674 packet_type_counter_observer_,
675 RtcpPacketTypesCounterUpdated(
676 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 0)));
677 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
678 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000679}
680
681TEST_F(RtcpReceiverTest, InjectFirPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000682 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700683 fir.AddRequestTo(kReceiverMainSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700684
685 EXPECT_CALL(
686 packet_type_counter_observer_,
687 RtcpPacketTypesCounterUpdated(
688 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::fir_packets, 1)));
689 EXPECT_CALL(intra_frame_observer_,
690 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
691 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000692}
693
694TEST_F(RtcpReceiverTest, FirPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000695 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700696 fir.AddRequestTo(kNotToUsSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700697
698 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
699 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000700}
701
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100702TEST_F(RtcpReceiverTest, ExtendedReportsPacketWithZeroReportBlocksIgnored) {
703 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700704 xr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700705
706 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000707}
708
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100709TEST_F(RtcpReceiverTest, InjectExtendedReportsReceiverReferenceTimePacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700710 const NtpTime kNtp(0x10203, 0x40506);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000711 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700712 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100713 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700714 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700715 xr.SetRrtr(rrtr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000716
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200717 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
718 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
719 EXPECT_THAT(last_xr_rtis, IsEmpty());
danilchap1e714ae2016-09-05 09:57:22 -0700720
721 InjectRtcpPacket(xr);
722
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200723 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
724 ASSERT_THAT(last_xr_rtis, SizeIs(1));
725 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
726 EXPECT_EQ(CompactNtp(kNtp), last_xr_rtis[0].last_rr);
727 EXPECT_EQ(0U, last_xr_rtis[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000728}
729
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100730TEST_F(RtcpReceiverTest, ExtendedReportsDlrrPacketNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700731 // Allow calculate rtt using dlrr/rrtr, simulating media receiver side.
732 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000733
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100734 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700735 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700736 xr.AddDlrrItem(ReceiveTimeInfo(kNotToUsSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700737
738 InjectRtcpPacket(xr);
739
740 int64_t rtt_ms = 0;
741 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000742}
743
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100744TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithSubBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700745 const uint32_t kLastRR = 0x12345;
746 const uint32_t kDelay = 0x23456;
747 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
748 int64_t rtt_ms = 0;
749 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000750
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100751 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700752 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700753 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
danilchap1e714ae2016-09-05 09:57:22 -0700754
755 InjectRtcpPacket(xr);
756
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200757 uint32_t compact_ntp_now =
758 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700759 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
760 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
761 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000762}
763
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100764TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithMultipleSubBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700765 const uint32_t kLastRR = 0x12345;
766 const uint32_t kDelay = 0x56789;
767 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000768
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100769 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700770 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700771 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
772 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 1, 0x12345, 0x67890));
773 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 2, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700774
775 InjectRtcpPacket(xr);
776
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200777 uint32_t compact_ntp_now =
778 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700779 int64_t rtt_ms = 0;
780 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
781 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
782 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000783}
784
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100785TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithMultipleReportBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700786 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000787
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000788 rtcp::Rrtr rrtr;
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100789 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700790 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700791 xr.SetRrtr(rrtr);
792 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700793
794 InjectRtcpPacket(xr);
795
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200796 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
797 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
798 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700799 int64_t rtt_ms = 0;
800 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000801}
802
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100803TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithUnknownReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700804 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000805
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000806 rtcp::Rrtr rrtr;
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100807 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700808 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700809 xr.SetRrtr(rrtr);
810 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700811
danilchap69e59e62016-02-17 03:11:42 -0800812 rtc::Buffer packet = xr.Build();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000813 // Modify the DLRR block to have an unsupported block type, from 5 to 6.
danilchap1e714ae2016-09-05 09:57:22 -0700814 ASSERT_EQ(5, packet.data()[20]);
815 packet.data()[20] = 6;
816 InjectRtcpPacket(packet);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000817
danilchap1e714ae2016-09-05 09:57:22 -0700818 // Validate Rrtr was received and processed.
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200819 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
820 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
821 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700822 // Validate Dlrr report wasn't processed.
823 int64_t rtt_ms = 0;
824 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000825}
826
danilchap1e714ae2016-09-05 09:57:22 -0700827TEST_F(RtcpReceiverTest, TestExtendedReportsRrRttInitiallyFalse) {
828 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
829
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000830 int64_t rtt_ms;
danilchap1e714ae2016-09-05 09:57:22 -0700831 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000832}
833
danilchap1e714ae2016-09-05 09:57:22 -0700834TEST_F(RtcpReceiverTest, RttCalculatedAfterExtendedReportsDlrr) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100835 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100836 const int64_t kRttMs = rand.Rand(1, 9 * 3600 * 1000);
837 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
838 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700839 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200840 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalova094fd12016-02-22 18:59:36 +0100841 uint32_t sent_ntp = CompactNtp(now);
842 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
843
Danil Chapovalova094fd12016-02-22 18:59:36 +0100844 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700845 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700846 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700847
848 InjectRtcpPacket(xr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100849
850 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700851 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100852 EXPECT_NEAR(kRttMs, rtt_ms, 1);
853}
854
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100855TEST_F(RtcpReceiverTest, XrDlrrCalculatesNegativeRttAsOne) {
856 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100857 const int64_t kRttMs = rand.Rand(-3600 * 1000, -1);
858 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
859 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200860 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100861 uint32_t sent_ntp = CompactNtp(now);
862 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
danilchap1e714ae2016-09-05 09:57:22 -0700863 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100864
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100865 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700866 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700867 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700868
869 InjectRtcpPacket(xr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100870
871 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700872 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100873 EXPECT_EQ(1, rtt_ms);
874}
875
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200876TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfoInitiallyEmpty) {
877 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000878}
879
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200880TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfo) {
Danil Chapovalovfc47ed62015-12-07 14:46:35 +0100881 const NtpTime kNtp(0x10203, 0x40506);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100882 const uint32_t kNtpMid = CompactNtp(kNtp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000883
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000884 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700885 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100886 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700887 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700888 xr.SetRrtr(rrtr);
danilchap1e714ae2016-09-05 09:57:22 -0700889
890 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000891
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000892 system_clock_.AdvanceTimeMilliseconds(1000);
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200893
894 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
895 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
896 ASSERT_THAT(last_xr_rtis, SizeIs(1));
897 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
898 EXPECT_EQ(kNtpMid, last_xr_rtis[0].last_rr);
899 EXPECT_EQ(65536U, last_xr_rtis[0].delay_since_last_rr);
900}
901
902TEST_F(RtcpReceiverTest,
903 ReceivedRrtrFromSameSsrcUpdatesReceivedReferenceTimeInfo) {
904 const NtpTime kNtp1(0x10203, 0x40506);
905 const NtpTime kNtp2(0x11223, 0x44556);
906 const int64_t kDelayMs = 2000;
907
908 rtcp::ExtendedReports xr;
909 xr.SetSenderSsrc(kSenderSsrc);
910 rtcp::Rrtr rrtr1;
911 rrtr1.SetNtp(kNtp1);
912 xr.SetRrtr(rrtr1);
913 InjectRtcpPacket(xr);
914 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
915 rtcp::Rrtr rrtr2;
916 rrtr2.SetNtp(kNtp2);
917 xr.SetRrtr(rrtr2);
918 InjectRtcpPacket(xr);
919 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
920
921 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
922 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
923 ASSERT_THAT(last_xr_rtis, SizeIs(1));
924 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
925 EXPECT_EQ(CompactNtp(kNtp2), last_xr_rtis[0].last_rr);
926 EXPECT_EQ(kDelayMs * 65536 / 1000, last_xr_rtis[0].delay_since_last_rr);
927}
928
929TEST_F(RtcpReceiverTest, StoresLastReceivedRrtrPerSsrc) {
930 const size_t kNumBufferedReports = 1;
931 const size_t kNumReports =
932 rtcp::ExtendedReports::kMaxNumberOfDlrrItems + kNumBufferedReports;
933 for (size_t i = 0; i < kNumReports; ++i) {
934 rtcp::ExtendedReports xr;
935 xr.SetSenderSsrc(i * 100);
936 rtcp::Rrtr rrtr;
937 rrtr.SetNtp(NtpTime(i * 200, i * 300));
938 xr.SetRrtr(rrtr);
939 InjectRtcpPacket(xr);
940 system_clock_.AdvanceTimeMilliseconds(1000);
941 }
942
943 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
944 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
945 ASSERT_THAT(last_xr_rtis,
946 SizeIs(rtcp::ExtendedReports::kMaxNumberOfDlrrItems));
947 for (size_t i = 0; i < rtcp::ExtendedReports::kMaxNumberOfDlrrItems; ++i) {
948 EXPECT_EQ(i * 100, last_xr_rtis[i].ssrc);
949 EXPECT_EQ(CompactNtp(NtpTime(i * 200, i * 300)), last_xr_rtis[i].last_rr);
950 EXPECT_EQ(65536U * (kNumReports - i), last_xr_rtis[i].delay_since_last_rr);
951 }
952
953 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
954 ASSERT_THAT(last_xr_rtis, SizeIs(kNumBufferedReports));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000955}
956
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000957TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000958 const uint16_t kSequenceNumber = 1234;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000959 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000960
961 // No RR received, shouldn't trigger a timeout.
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800962 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
963 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000964
965 // Add a RR and advance the clock just enough to not trigger a timeout.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000966 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700967 rb1.SetMediaSsrc(kReceiverMainSsrc);
968 rb1.SetExtHighestSeqNum(kSequenceNumber);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000969 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700970 rr1.SetSenderSsrc(kSenderSsrc);
971 rr1.AddReportBlock(rb1);
danilchap1e714ae2016-09-05 09:57:22 -0700972
973 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
974 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
975 InjectRtcpPacket(rr1);
976
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000977 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs - 1);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800978 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
979 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000980
981 // Add a RR with the same extended max as the previous RR to trigger a
982 // sequence number timeout, but not a RR timeout.
danilchap1e714ae2016-09-05 09:57:22 -0700983 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
984 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
985 InjectRtcpPacket(rr1);
986
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000987 system_clock_.AdvanceTimeMilliseconds(2);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800988 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
989 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000990
991 // Advance clock enough to trigger an RR timeout too.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000992 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800993 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000994
995 // We should only get one timeout even though we still haven't received a new
996 // RR.
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800997 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
998 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000999
1000 // Add a new RR with increase sequence number to reset timers.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001001 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001002 rb2.SetMediaSsrc(kReceiverMainSsrc);
1003 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001004 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001005 rr2.SetSenderSsrc(kSenderSsrc);
1006 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001007
1008 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1009 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1010 InjectRtcpPacket(rr2);
1011
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001012 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1013 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001014
1015 // Verify we can get a timeout again once we've received new RR.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001016 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -07001017 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1018 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1019 InjectRtcpPacket(rr2);
1020
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001021 system_clock_.AdvanceTimeMilliseconds(kRtcpIntervalMs + 1);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001022 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1023 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
danilchap1e714ae2016-09-05 09:57:22 -07001024
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001025 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001026 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001027}
1028
hta@webrtc.org47059b52012-05-02 07:46:22 +00001029TEST_F(RtcpReceiverTest, TmmbrReceivedWithNoIncomingPacket) {
danilchap1e714ae2016-09-05 09:57:22 -07001030 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001031}
1032
1033TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) {
danilchap1e714ae2016-09-05 09:57:22 -07001034 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001035 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001036 tmmbr.SetSenderSsrc(kSenderSsrc);
1037 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001038 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001039 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001040 rtcp::CompoundPacket compound;
1041 compound.Append(&sr);
1042 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001043
danilchap1e714ae2016-09-05 09:57:22 -07001044 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1045 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(SizeIs(1)));
1046 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1047 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1048 InjectRtcpPacket(compound);
1049
1050 std::vector<rtcp::TmmbItem> tmmbr_received = rtcp_receiver_.TmmbrReceived();
1051 ASSERT_EQ(1u, tmmbr_received.size());
1052 EXPECT_EQ(kBitrateBps, tmmbr_received[0].bitrate_bps());
1053 EXPECT_EQ(kSenderSsrc, tmmbr_received[0].ssrc());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001054}
1055
1056TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -07001057 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001058 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001059 tmmbr.SetSenderSsrc(kSenderSsrc);
1060 tmmbr.AddTmmbr(rtcp::TmmbItem(kNotToUsSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001061
1062 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001063 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001064 rtcp::CompoundPacket compound;
1065 compound.Append(&sr);
1066 compound.Append(&tmmbr);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001067
danilchap1e714ae2016-09-05 09:57:22 -07001068 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1069 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1070 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1071 InjectRtcpPacket(compound);
1072
1073 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001074}
1075
1076TEST_F(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001077 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001078 tmmbr.SetSenderSsrc(kSenderSsrc);
1079 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 0, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001080 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001081 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001082 rtcp::CompoundPacket compound;
1083 compound.Append(&sr);
1084 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001085
danilchap1e714ae2016-09-05 09:57:22 -07001086 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1087 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1088 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1089 InjectRtcpPacket(compound);
1090
1091 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001092}
1093
hta@webrtc.org404843e2012-05-02 09:56:45 +00001094TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001095 // Inject 3 packets "from" kSenderSsrc, kSenderSsrc+1, kSenderSsrc+2.
hta@webrtc.org404843e2012-05-02 09:56:45 +00001096 // The times of arrival are starttime + 0, starttime + 5 and starttime + 10.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001097 for (uint32_t ssrc = kSenderSsrc; ssrc < kSenderSsrc + 3; ++ssrc) {
1098 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001099 tmmbr.SetSenderSsrc(ssrc);
1100 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 30000, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001101 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001102 sr.SetSenderSsrc(ssrc);
danilchap7a4116a2016-03-14 08:19:28 -07001103 rtcp::CompoundPacket compound;
1104 compound.Append(&sr);
1105 compound.Append(&tmmbr);
danilchap1e714ae2016-09-05 09:57:22 -07001106
1107 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1108 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(_));
1109 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1110 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_));
1111 InjectRtcpPacket(compound);
1112
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001113 // 5 seconds between each packet.
1114 system_clock_.AdvanceTimeMilliseconds(5000);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001115 }
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001116 // It is now starttime + 15.
danilchap1e714ae2016-09-05 09:57:22 -07001117 std::vector<rtcp::TmmbItem> candidate_set = rtcp_receiver_.TmmbrReceived();
1118 ASSERT_EQ(3u, candidate_set.size());
1119 EXPECT_EQ(30000U, candidate_set[0].bitrate_bps());
1120
hta@webrtc.org404843e2012-05-02 09:56:45 +00001121 // We expect the timeout to be 25 seconds. Advance the clock by 12
1122 // seconds, timing out the first packet.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001123 system_clock_.AdvanceTimeMilliseconds(12000);
danilchap1e714ae2016-09-05 09:57:22 -07001124 candidate_set = rtcp_receiver_.TmmbrReceived();
1125 ASSERT_EQ(2u, candidate_set.size());
danilchap287e5482016-08-16 15:15:39 -07001126 EXPECT_EQ(kSenderSsrc + 1, candidate_set[0].ssrc());
hta@webrtc.org404843e2012-05-02 09:56:45 +00001127}
1128
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001129TEST_F(RtcpReceiverTest, Callbacks) {
danilchap1e714ae2016-09-05 09:57:22 -07001130 MockRtcpCallbackImpl callback;
1131 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001132
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001133 const uint8_t kFractionLoss = 3;
1134 const uint32_t kCumulativeLoss = 7;
1135 const uint32_t kJitter = 9;
1136 const uint16_t kSequenceNumber = 1234;
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001137
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001138 // First packet, all numbers should just propagate.
1139 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -07001140 rb1.SetMediaSsrc(kReceiverMainSsrc);
1141 rb1.SetExtHighestSeqNum(kSequenceNumber);
1142 rb1.SetFractionLost(kFractionLoss);
1143 rb1.SetCumulativeLost(kCumulativeLoss);
1144 rb1.SetJitter(kJitter);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001145
1146 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -07001147 rr1.SetSenderSsrc(kSenderSsrc);
1148 rr1.AddReportBlock(rb1);
srte186d9c32017-08-04 05:03:53 -07001149 EXPECT_CALL(callback,
1150 StatisticsUpdated(
1151 AllOf(Field(&RtcpStatistics::fraction_lost, kFractionLoss),
1152 Field(&RtcpStatistics::packets_lost, kCumulativeLoss),
1153 Field(&RtcpStatistics::extended_highest_sequence_number,
1154 kSequenceNumber),
1155 Field(&RtcpStatistics::jitter, kJitter)),
1156 kReceiverMainSsrc));
danilchap1e714ae2016-09-05 09:57:22 -07001157 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1158 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1159 InjectRtcpPacket(rr1);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001160
danilchap1e714ae2016-09-05 09:57:22 -07001161 rtcp_receiver_.RegisterRtcpStatisticsCallback(nullptr);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001162
danilchap1e714ae2016-09-05 09:57:22 -07001163 // Add arbitrary numbers, callback should not be called.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001164 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001165 rb2.SetMediaSsrc(kReceiverMainSsrc);
1166 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
1167 rb2.SetFractionLost(42);
1168 rb2.SetCumulativeLost(137);
1169 rb2.SetJitter(4711);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001170
1171 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001172 rr2.SetSenderSsrc(kSenderSsrc);
1173 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001174
1175 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1176 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1177 EXPECT_CALL(callback, StatisticsUpdated(_, _)).Times(0);
1178 InjectRtcpPacket(rr2);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001179}
hta@webrtc.org404843e2012-05-02 09:56:45 +00001180
sprang49f9cdb2015-10-01 03:06:57 -07001181TEST_F(RtcpReceiverTest, ReceivesTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001182 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001183 packet.SetMediaSsrc(kReceiverMainSsrc);
1184 packet.SetSenderSsrc(kSenderSsrc);
1185 packet.SetBase(1, 1000);
1186 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001187
danilchap1e714ae2016-09-05 09:57:22 -07001188 EXPECT_CALL(
1189 transport_feedback_observer_,
1190 OnTransportFeedback(AllOf(
1191 Property(&rtcp::TransportFeedback::media_ssrc, kReceiverMainSsrc),
1192 Property(&rtcp::TransportFeedback::sender_ssrc, kSenderSsrc))));
1193 InjectRtcpPacket(packet);
sprang49f9cdb2015-10-01 03:06:57 -07001194}
1195
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001196TEST_F(RtcpReceiverTest, ReceivesRemb) {
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001197 const uint32_t kBitrateBps = 500000;
1198 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001199 remb.SetSenderSsrc(kSenderSsrc);
1200 remb.SetBitrateBps(kBitrateBps);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001201
danilchap1e714ae2016-09-05 09:57:22 -07001202 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1203 InjectRtcpPacket(remb);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001204}
1205
sprang49f9cdb2015-10-01 03:06:57 -07001206TEST_F(RtcpReceiverTest, HandlesInvalidTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001207 // Send a compound packet with a TransportFeedback followed by something else.
1208 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001209 packet.SetMediaSsrc(kReceiverMainSsrc);
1210 packet.SetSenderSsrc(kSenderSsrc);
1211 packet.SetBase(1, 1000);
1212 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001213
1214 static uint32_t kBitrateBps = 50000;
1215 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001216 remb.SetSenderSsrc(kSenderSsrc);
1217 remb.SetBitrateBps(kBitrateBps);
danilchap7a4116a2016-03-14 08:19:28 -07001218 rtcp::CompoundPacket compound;
1219 compound.Append(&packet);
1220 compound.Append(&remb);
1221 rtc::Buffer built_packet = compound.Build();
sprang49f9cdb2015-10-01 03:06:57 -07001222
1223 // Modify the TransportFeedback packet so that it is invalid.
1224 const size_t kStatusCountOffset = 14;
Yves Gerey665174f2018-06-19 15:03:05 +02001225 ByteWriter<uint16_t>::WriteBigEndian(&built_packet.data()[kStatusCountOffset],
1226 42);
sprang49f9cdb2015-10-01 03:06:57 -07001227
danilchap1e714ae2016-09-05 09:57:22 -07001228 // Stress no transport feedback is expected.
1229 EXPECT_CALL(transport_feedback_observer_, OnTransportFeedback(_)).Times(0);
1230 // But remb should be processed and cause a callback
1231 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1232 InjectRtcpPacket(built_packet);
sprang49f9cdb2015-10-01 03:06:57 -07001233}
1234
danilchap1e714ae2016-09-05 09:57:22 -07001235TEST_F(RtcpReceiverTest, Nack) {
1236 const uint16_t kNackList1[] = {1, 2, 3, 5};
danilchap142f0192016-10-20 08:22:42 -07001237 const uint16_t kNackList23[] = {5, 7, 30, 40, 41, 58, 59, 61, 63};
1238 const size_t kNackListLength2 = 4;
1239 const size_t kNackListLength3 = arraysize(kNackList23) - kNackListLength2;
danilchap1e714ae2016-09-05 09:57:22 -07001240 std::set<uint16_t> nack_set;
1241 nack_set.insert(std::begin(kNackList1), std::end(kNackList1));
danilchap142f0192016-10-20 08:22:42 -07001242 nack_set.insert(std::begin(kNackList23), std::end(kNackList23));
danilchap1e714ae2016-09-05 09:57:22 -07001243
danilchap142f0192016-10-20 08:22:42 -07001244 rtcp::Nack nack1;
1245 nack1.SetSenderSsrc(kSenderSsrc);
1246 nack1.SetMediaSsrc(kReceiverMainSsrc);
1247 nack1.SetPacketIds(kNackList1, arraysize(kNackList1));
danilchap1e714ae2016-09-05 09:57:22 -07001248
1249 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList1)));
danilchap1e714ae2016-09-05 09:57:22 -07001250 EXPECT_CALL(packet_type_counter_observer_,
1251 RtcpPacketTypesCounterUpdated(
1252 kReceiverMainSsrc,
1253 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
danilchap142f0192016-10-20 08:22:42 -07001254 arraysize(kNackList1)),
1255 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1256 arraysize(kNackList1)))));
1257 InjectRtcpPacket(nack1);
1258
1259 rtcp::Nack nack2;
1260 nack2.SetSenderSsrc(kSenderSsrc);
1261 nack2.SetMediaSsrc(kReceiverMainSsrc);
1262 nack2.SetPacketIds(kNackList23, kNackListLength2);
1263
1264 rtcp::Nack nack3;
1265 nack3.SetSenderSsrc(kSenderSsrc);
1266 nack3.SetMediaSsrc(kReceiverMainSsrc);
1267 nack3.SetPacketIds(kNackList23 + kNackListLength2, kNackListLength3);
1268
1269 rtcp::CompoundPacket two_nacks;
1270 two_nacks.Append(&nack2);
1271 two_nacks.Append(&nack3);
1272
1273 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList23)));
1274 EXPECT_CALL(packet_type_counter_observer_,
1275 RtcpPacketTypesCounterUpdated(
1276 kReceiverMainSsrc,
1277 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
1278 arraysize(kNackList1) + arraysize(kNackList23)),
danilchap1e714ae2016-09-05 09:57:22 -07001279 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1280 nack_set.size()))));
danilchap142f0192016-10-20 08:22:42 -07001281 InjectRtcpPacket(two_nacks);
danilchap1e714ae2016-09-05 09:57:22 -07001282}
1283
1284TEST_F(RtcpReceiverTest, NackNotForUsIgnored) {
1285 const uint16_t kNackList1[] = {1, 2, 3, 5};
1286 const size_t kNackListLength1 = std::end(kNackList1) - std::begin(kNackList1);
1287
1288 rtcp::Nack nack;
danilchap822a16f2016-09-27 09:27:47 -07001289 nack.SetSenderSsrc(kSenderSsrc);
1290 nack.SetMediaSsrc(kNotToUsSsrc);
1291 nack.SetPacketIds(kNackList1, kNackListLength1);
danilchap1e714ae2016-09-05 09:57:22 -07001292
1293 EXPECT_CALL(packet_type_counter_observer_,
1294 RtcpPacketTypesCounterUpdated(
1295 _, Field(&RtcpPacketTypeCounter::nack_requests, 0)));
1296 InjectRtcpPacket(nack);
1297}
1298
1299TEST_F(RtcpReceiverTest, ForceSenderReport) {
1300 rtcp::RapidResyncRequest rr;
danilchap822a16f2016-09-27 09:27:47 -07001301 rr.SetSenderSsrc(kSenderSsrc);
1302 rr.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -07001303
1304 EXPECT_CALL(rtp_rtcp_impl_, OnRequestSendReport());
1305 InjectRtcpPacket(rr);
1306}
hta@webrtc.org47059b52012-05-02 07:46:22 +00001307
spranga790d832016-12-02 07:29:44 -08001308TEST_F(RtcpReceiverTest, ReceivesTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001309 VideoBitrateAllocation expected_allocation;
spranga790d832016-12-02 07:29:44 -08001310 expected_allocation.SetBitrate(0, 0, 10000);
1311 expected_allocation.SetBitrate(0, 1, 20000);
1312 expected_allocation.SetBitrate(1, 0, 40000);
1313 expected_allocation.SetBitrate(1, 1, 80000);
1314
1315 rtcp::TargetBitrate bitrate;
1316 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1317 bitrate.AddTargetBitrate(0, 1, expected_allocation.GetBitrate(0, 1) / 1000);
1318 bitrate.AddTargetBitrate(1, 0, expected_allocation.GetBitrate(1, 0) / 1000);
1319 bitrate.AddTargetBitrate(1, 1, expected_allocation.GetBitrate(1, 1) / 1000);
1320
1321 rtcp::ExtendedReports xr;
1322 xr.SetTargetBitrate(bitrate);
1323
sprangb32aaf92017-08-28 05:49:12 -07001324 // Wrong sender ssrc, target bitrate should be discarded.
1325 xr.SetSenderSsrc(kSenderSsrc + 1);
1326 EXPECT_CALL(bitrate_allocation_observer_,
1327 OnBitrateAllocationUpdated(expected_allocation))
1328 .Times(0);
1329 InjectRtcpPacket(xr);
1330
1331 // Set correct ssrc, callback should be called once.
1332 xr.SetSenderSsrc(kSenderSsrc);
spranga790d832016-12-02 07:29:44 -08001333 EXPECT_CALL(bitrate_allocation_observer_,
1334 OnBitrateAllocationUpdated(expected_allocation));
1335 InjectRtcpPacket(xr);
1336}
1337
sprang6d314c72016-12-06 06:08:53 -08001338TEST_F(RtcpReceiverTest, HandlesIncorrectTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001339 VideoBitrateAllocation expected_allocation;
sprang6d314c72016-12-06 06:08:53 -08001340 expected_allocation.SetBitrate(0, 0, 10000);
1341
1342 rtcp::TargetBitrate bitrate;
1343 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1344 bitrate.AddTargetBitrate(0, kMaxTemporalStreams, 20000);
1345 bitrate.AddTargetBitrate(kMaxSpatialLayers, 0, 40000);
1346
1347 rtcp::ExtendedReports xr;
1348 xr.SetTargetBitrate(bitrate);
sprangb32aaf92017-08-28 05:49:12 -07001349 xr.SetSenderSsrc(kSenderSsrc);
sprang6d314c72016-12-06 06:08:53 -08001350
1351 EXPECT_CALL(bitrate_allocation_observer_,
1352 OnBitrateAllocationUpdated(expected_allocation));
1353 InjectRtcpPacket(xr);
1354}
1355
hta@webrtc.org47059b52012-05-02 07:46:22 +00001356} // namespace webrtc