blob: 332495d677a9716011179d914c2453b933bd8896 [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:
Erik Språng30a276b2019-04-23 12:00:11 +020087 MOCK_METHOD1(OnAddPacket, void(const RtpPacketSendInfo&));
danilchap1e714ae2016-09-05 09:57:22 -070088 MOCK_METHOD1(OnTransportFeedback, void(const rtcp::TransportFeedback&));
elad.alonf9490002017-03-06 05:32:21 -080089 MOCK_CONST_METHOD0(GetTransportFeedbackVector, std::vector<PacketFeedback>());
danilchap1e714ae2016-09-05 09:57:22 -070090};
91
danilchap1e714ae2016-09-05 09:57:22 -070092class MockModuleRtpRtcp : public RTCPReceiver::ModuleRtpRtcp {
93 public:
94 MOCK_METHOD1(SetTmmbn, void(std::vector<rtcp::TmmbItem>));
95 MOCK_METHOD0(OnRequestSendReport, void());
96 MOCK_METHOD1(OnReceivedNack, void(const std::vector<uint16_t>&));
97 MOCK_METHOD1(OnReceivedRtcpReportBlocks, void(const ReportBlockList&));
98};
99
spranga790d832016-12-02 07:29:44 -0800100class MockVideoBitrateAllocationObserver
101 : public VideoBitrateAllocationObserver {
102 public:
103 MOCK_METHOD1(OnBitrateAllocationUpdated,
Erik Språng566124a2018-04-23 12:32:22 +0200104 void(const VideoBitrateAllocation& allocation));
spranga790d832016-12-02 07:29:44 -0800105};
106
danilchap1e714ae2016-09-05 09:57:22 -0700107// SSRC of remote peer, that sends rtcp packet to the rtcp receiver under test.
108constexpr uint32_t kSenderSsrc = 0x10203;
109// SSRCs of local peer, that rtcp packet addressed to.
110constexpr uint32_t kReceiverMainSsrc = 0x123456;
111// RtcpReceiver can accept several ssrc, e.g. regular and rtx streams.
112constexpr uint32_t kReceiverExtraSsrc = 0x1234567;
113// SSRCs to ignore (i.e. not configured in RtcpReceiver).
114constexpr uint32_t kNotToUsSsrc = 0x654321;
115constexpr uint32_t kUnknownSenderSsrc = 0x54321;
116
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800117constexpr int64_t kRtcpIntervalMs = 1000;
118
danilchap1e714ae2016-09-05 09:57:22 -0700119} // namespace
120
hta@webrtc.org47059b52012-05-02 07:46:22 +0000121class RtcpReceiverTest : public ::testing::Test {
122 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000123 RtcpReceiverTest()
danilchap1e714ae2016-09-05 09:57:22 -0700124 : system_clock_(1335900000),
125 rtcp_receiver_(&system_clock_,
126 false,
127 &packet_type_counter_observer_,
128 &bandwidth_observer_,
129 &intra_frame_observer_,
Elad Alon0a8562e2019-04-09 11:55:13 +0200130 &rtcp_loss_notification_observer_,
danilchap1e714ae2016-09-05 09:57:22 -0700131 &transport_feedback_observer_,
spranga790d832016-12-02 07:29:44 -0800132 &bitrate_allocation_observer_,
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800133 kRtcpIntervalMs,
danilchap1e714ae2016-09-05 09:57:22 -0700134 &rtp_rtcp_impl_) {}
135 void SetUp() {
136 std::set<uint32_t> ssrcs = {kReceiverMainSsrc, kReceiverExtraSsrc};
danilchap1e714ae2016-09-05 09:57:22 -0700137 rtcp_receiver_.SetSsrcs(kReceiverMainSsrc, ssrcs);
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000138
danilchap1e714ae2016-09-05 09:57:22 -0700139 rtcp_receiver_.SetRemoteSSRC(kSenderSsrc);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000140 }
Erik Språng737336d2016-07-29 12:59:36 +0200141
danilchap1e714ae2016-09-05 09:57:22 -0700142 void InjectRtcpPacket(rtc::ArrayView<const uint8_t> raw) {
143 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
hta@webrtc.org47059b52012-05-02 07:46:22 +0000144 }
145
danilchap1e714ae2016-09-05 09:57:22 -0700146 void InjectRtcpPacket(const rtcp::RtcpPacket& packet) {
147 rtc::Buffer raw = packet.Build();
148 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
149 }
150
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000151 SimulatedClock system_clock_;
danilchap1e714ae2016-09-05 09:57:22 -0700152 // Callbacks to packet_type_counter_observer are frequent but most of the time
153 // are not interesting.
154 NiceMock<MockRtcpPacketTypeCounterObserver> packet_type_counter_observer_;
155 StrictMock<MockRtcpBandwidthObserver> bandwidth_observer_;
156 StrictMock<MockRtcpIntraFrameObserver> intra_frame_observer_;
Elad Alon0a8562e2019-04-09 11:55:13 +0200157 StrictMock<MockRtcpLossNotificationObserver> rtcp_loss_notification_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700158 StrictMock<MockTransportFeedbackObserver> transport_feedback_observer_;
spranga790d832016-12-02 07:29:44 -0800159 StrictMock<MockVideoBitrateAllocationObserver> bitrate_allocation_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700160 StrictMock<MockModuleRtpRtcp> rtp_rtcp_impl_;
hta@webrtc.org47059b52012-05-02 07:46:22 +0000161
danilchap1e714ae2016-09-05 09:57:22 -0700162 RTCPReceiver rtcp_receiver_;
163};
hta@webrtc.org47059b52012-05-02 07:46:22 +0000164
165TEST_F(RtcpReceiverTest, BrokenPacketIsIgnored) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000166 const uint8_t bad_packet[] = {0, 0, 0, 0};
danilchap1e714ae2016-09-05 09:57:22 -0700167 EXPECT_CALL(packet_type_counter_observer_,
168 RtcpPacketTypesCounterUpdated(_, _))
169 .Times(0);
170 InjectRtcpPacket(bad_packet);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000171}
172
danilchap50da1d32016-03-10 13:13:52 -0800173TEST_F(RtcpReceiverTest, InvalidFeedbackPacketIsIgnored) {
174 // Too short feedback packet.
danilchap1e714ae2016-09-05 09:57:22 -0700175 const uint8_t bad_packet[] = {0x81, rtcp::Rtpfb::kPacketType, 0, 0};
176
177 // TODO(danilchap): Add expectation RtcpPacketTypesCounterUpdated
178 // is not called once parser would be adjusted to avoid that callback on
179 // semi-valid packets.
180 InjectRtcpPacket(bad_packet);
danilchap50da1d32016-03-10 13:13:52 -0800181}
182
hta@webrtc.org47059b52012-05-02 07:46:22 +0000183TEST_F(RtcpReceiverTest, InjectSrPacket) {
danilchapa04d9c32017-07-25 04:03:39 -0700184 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
danilchap1e714ae2016-09-05 09:57:22 -0700185
186 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000187 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700188 sr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700189
190 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
191 EXPECT_CALL(bandwidth_observer_,
192 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
193 InjectRtcpPacket(sr);
194
danilchapa04d9c32017-07-25 04:03:39 -0700195 EXPECT_TRUE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
hta@webrtc.org47059b52012-05-02 07:46:22 +0000196}
197
danilchap1e714ae2016-09-05 09:57:22 -0700198TEST_F(RtcpReceiverTest, InjectSrPacketFromUnknownSender) {
199 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000200 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700201 sr.SetSenderSsrc(kUnknownSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700202
203 // The parser will handle report blocks in Sender Report from other than his
204 // expected peer.
205 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
206 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, now));
207 InjectRtcpPacket(sr);
208
209 // But will not flag that he's gotten sender information.
danilchapa04d9c32017-07-25 04:03:39 -0700210 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000211}
212
Danil Chapovalova094fd12016-02-22 18:59:36 +0100213TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesRTT) {
214 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100215 const int64_t kRttMs = r.Rand(1, 9 * 3600 * 1000);
216 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
217 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100218
Danil Chapovalova094fd12016-02-22 18:59:36 +0100219 int64_t rtt_ms = 0;
220 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700221 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100222
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200223 uint32_t sent_ntp =
224 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100225 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
226
227 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700228 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100229 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700230 block.SetMediaSsrc(kReceiverMainSsrc);
231 block.SetLastSr(sent_ntp);
232 block.SetDelayLastSr(kDelayNtp);
233 sr.AddReportBlock(block);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100234
danilchap1e714ae2016-09-05 09:57:22 -0700235 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
236 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
237 InjectRtcpPacket(sr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100238
239 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700240 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100241 EXPECT_NEAR(kRttMs, rtt_ms, 1);
242}
243
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100244TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesNegativeRTTAsOne) {
245 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100246 const int64_t kRttMs = r.Rand(-3600 * 1000, -1);
247 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
248 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
249
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100250 int64_t rtt_ms = 0;
251 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700252 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100253
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200254 uint32_t sent_ntp =
255 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100256 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
257
258 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700259 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100260 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700261 block.SetMediaSsrc(kReceiverMainSsrc);
262 block.SetLastSr(sent_ntp);
263 block.SetDelayLastSr(kDelayNtp);
264 sr.AddReportBlock(block);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100265
danilchap1e714ae2016-09-05 09:57:22 -0700266 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
267 EXPECT_CALL(bandwidth_observer_,
268 OnReceivedRtcpReceiverReport(SizeIs(1), _, _));
269 InjectRtcpPacket(sr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100270
271 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700272 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100273 EXPECT_EQ(1, rtt_ms);
274}
275
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100276TEST_F(
277 RtcpReceiverTest,
278 TwoReportBlocksWithLastOneWithoutLastSrCalculatesRttForBandwidthObserver) {
279 const int64_t kRttMs = 120;
280 const uint32_t kDelayNtp = 123000;
281 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
282
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200283 uint32_t sent_ntp =
284 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100285 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
286
287 rtcp::SenderReport sr;
288 sr.SetSenderSsrc(kSenderSsrc);
289 rtcp::ReportBlock block;
290 block.SetMediaSsrc(kReceiverMainSsrc);
291 block.SetLastSr(sent_ntp);
292 block.SetDelayLastSr(kDelayNtp);
293 sr.AddReportBlock(block);
294 block.SetMediaSsrc(kReceiverExtraSsrc);
295 block.SetLastSr(0);
296 sr.AddReportBlock(block);
297
298 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
299 EXPECT_CALL(bandwidth_observer_,
300 OnReceivedRtcpReceiverReport(SizeIs(2), kRttMs, _));
301 InjectRtcpPacket(sr);
302}
303
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000304TEST_F(RtcpReceiverTest, InjectRrPacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700305 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000306 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700307 rr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700308
309 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
310 EXPECT_CALL(bandwidth_observer_,
311 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
312 InjectRtcpPacket(rr);
313
danilchap1e714ae2016-09-05 09:57:22 -0700314 std::vector<RTCPReportBlock> report_blocks;
315 rtcp_receiver_.StatisticsReceived(&report_blocks);
316 EXPECT_TRUE(report_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000317}
318
319TEST_F(RtcpReceiverTest, InjectRrPacketWithReportBlockNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700320 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000321 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700322 rb.SetMediaSsrc(kNotToUsSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000323 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700324 rr.SetSenderSsrc(kSenderSsrc);
325 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000326
danilchap1e714ae2016-09-05 09:57:22 -0700327 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
328 EXPECT_CALL(bandwidth_observer_,
329 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
330 InjectRtcpPacket(rr);
331
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200332 EXPECT_EQ(0, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000333 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700334 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000335 EXPECT_TRUE(received_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000336}
337
338TEST_F(RtcpReceiverTest, InjectRrPacketWithOneReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700339 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000340
341 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700342 rb.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000343 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700344 rr.SetSenderSsrc(kSenderSsrc);
345 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000346
danilchap1e714ae2016-09-05 09:57:22 -0700347 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
348 EXPECT_CALL(bandwidth_observer_,
349 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
350 InjectRtcpPacket(rr);
351
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200352 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
353 std::vector<RTCPReportBlock> received_blocks;
354 rtcp_receiver_.StatisticsReceived(&received_blocks);
355 EXPECT_EQ(1u, received_blocks.size());
356}
357
358TEST_F(RtcpReceiverTest, InjectSrPacketWithOneReportBlock) {
359 int64_t now = system_clock_.TimeInMilliseconds();
360
361 rtcp::ReportBlock rb;
362 rb.SetMediaSsrc(kReceiverMainSsrc);
363 rtcp::SenderReport sr;
364 sr.SetSenderSsrc(kSenderSsrc);
365 sr.AddReportBlock(rb);
366
367 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
368 EXPECT_CALL(bandwidth_observer_,
369 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
370 InjectRtcpPacket(sr);
371
372 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000373 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700374 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000375 EXPECT_EQ(1u, received_blocks.size());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000376}
377
378TEST_F(RtcpReceiverTest, InjectRrPacketWithTwoReportBlocks) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000379 const uint16_t kSequenceNumbers[] = {10, 12423};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000380 const uint32_t kCumLost[] = {13, 555};
381 const uint8_t kFracLost[] = {20, 11};
danilchap1e714ae2016-09-05 09:57:22 -0700382 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000383
384 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700385 rb1.SetMediaSsrc(kReceiverMainSsrc);
386 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
387 rb1.SetFractionLost(10);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000388
389 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700390 rb2.SetMediaSsrc(kReceiverExtraSsrc);
391 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
392 rb2.SetFractionLost(0);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000393
394 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700395 rr1.SetSenderSsrc(kSenderSsrc);
396 rr1.AddReportBlock(rb1);
397 rr1.AddReportBlock(rb2);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000398
danilchap1e714ae2016-09-05 09:57:22 -0700399 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
400 EXPECT_CALL(bandwidth_observer_,
401 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
402 InjectRtcpPacket(rr1);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000403
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200404 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700405 std::vector<RTCPReportBlock> received_blocks;
406 rtcp_receiver_.StatisticsReceived(&received_blocks);
407 EXPECT_THAT(received_blocks,
srte3e69e5c2017-08-09 06:13:45 -0700408 UnorderedElementsAre(Field(&RTCPReportBlock::fraction_lost, 0),
409 Field(&RTCPReportBlock::fraction_lost, 10)));
danilchap1e714ae2016-09-05 09:57:22 -0700410
411 // Insert next receiver report with same ssrc but new values.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000412 rtcp::ReportBlock rb3;
danilchap822a16f2016-09-27 09:27:47 -0700413 rb3.SetMediaSsrc(kReceiverMainSsrc);
414 rb3.SetExtHighestSeqNum(kSequenceNumbers[0]);
415 rb3.SetFractionLost(kFracLost[0]);
416 rb3.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000417
418 rtcp::ReportBlock rb4;
danilchap822a16f2016-09-27 09:27:47 -0700419 rb4.SetMediaSsrc(kReceiverExtraSsrc);
420 rb4.SetExtHighestSeqNum(kSequenceNumbers[1]);
421 rb4.SetFractionLost(kFracLost[1]);
422 rb4.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000423
424 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700425 rr2.SetSenderSsrc(kSenderSsrc);
426 rr2.AddReportBlock(rb3);
427 rr2.AddReportBlock(rb4);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000428
danilchap1e714ae2016-09-05 09:57:22 -0700429 // Advance time to make 1st sent time and 2nd sent time different.
430 system_clock_.AdvanceTimeMilliseconds(500);
431 now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000432
danilchap1e714ae2016-09-05 09:57:22 -0700433 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
434 EXPECT_CALL(bandwidth_observer_,
435 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
436 InjectRtcpPacket(rr2);
437
438 received_blocks.clear();
439 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000440 EXPECT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700441 EXPECT_THAT(
442 received_blocks,
443 UnorderedElementsAre(
444 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
445 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
446 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
447 Field(&RTCPReportBlock::extended_highest_sequence_number,
448 kSequenceNumbers[0])),
449 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverExtraSsrc),
450 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
451 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
452 Field(&RTCPReportBlock::extended_highest_sequence_number,
453 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000454}
455
456TEST_F(RtcpReceiverTest, InjectRrPacketsFromTwoRemoteSsrcs) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000457 const uint32_t kSenderSsrc2 = 0x20304;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000458 const uint16_t kSequenceNumbers[] = {10, 12423};
Sebastian Jansson9701e0c2018-08-09 11:21:11 +0200459 const int32_t kCumLost[] = {13, 555};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000460 const uint8_t kFracLost[] = {20, 11};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000461
462 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700463 rb1.SetMediaSsrc(kReceiverMainSsrc);
464 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
465 rb1.SetFractionLost(kFracLost[0]);
466 rb1.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000467 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700468 rr1.SetSenderSsrc(kSenderSsrc);
469 rr1.AddReportBlock(rb1);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000470
danilchap1e714ae2016-09-05 09:57:22 -0700471 int64_t now = system_clock_.TimeInMilliseconds();
472
473 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
474 EXPECT_CALL(bandwidth_observer_,
475 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
476 InjectRtcpPacket(rr1);
477
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200478 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000479
480 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700481 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000482 EXPECT_EQ(1u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700483 EXPECT_EQ(kSenderSsrc, received_blocks[0].sender_ssrc);
484 EXPECT_EQ(kReceiverMainSsrc, received_blocks[0].source_ssrc);
485 EXPECT_EQ(kFracLost[0], received_blocks[0].fraction_lost);
486 EXPECT_EQ(kCumLost[0], received_blocks[0].packets_lost);
487 EXPECT_EQ(kSequenceNumbers[0],
488 received_blocks[0].extended_highest_sequence_number);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000489
490 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700491 rb2.SetMediaSsrc(kReceiverMainSsrc);
492 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
493 rb2.SetFractionLost(kFracLost[1]);
494 rb2.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000495 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700496 rr2.SetSenderSsrc(kSenderSsrc2);
497 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -0700498
499 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
500 EXPECT_CALL(bandwidth_observer_,
501 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
502 InjectRtcpPacket(rr2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000503
504 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700505 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000506 ASSERT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700507 EXPECT_THAT(
508 received_blocks,
509 UnorderedElementsAre(
510 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
511 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc),
512 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
513 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
514 Field(&RTCPReportBlock::extended_highest_sequence_number,
515 kSequenceNumbers[0])),
516 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
517 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc2),
518 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
519 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
520 Field(&RTCPReportBlock::extended_highest_sequence_number,
521 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000522}
523
524TEST_F(RtcpReceiverTest, GetRtt) {
danilchap28b03eb2016-10-05 06:59:44 -0700525 const uint32_t kSentCompactNtp = 0x1234;
526 const uint32_t kDelayCompactNtp = 0x222;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000527 // No report block received.
Erik Språng6b8d3552015-09-24 15:06:57 +0200528 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700529 -1, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000530
531 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700532 rb.SetMediaSsrc(kReceiverMainSsrc);
danilchap28b03eb2016-10-05 06:59:44 -0700533 rb.SetLastSr(kSentCompactNtp);
534 rb.SetDelayLastSr(kDelayCompactNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700535
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000536 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700537 rr.SetSenderSsrc(kSenderSsrc);
538 rr.AddReportBlock(rb);
danilchap1e714ae2016-09-05 09:57:22 -0700539 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000540
danilchap1e714ae2016-09-05 09:57:22 -0700541 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
542 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
543 InjectRtcpPacket(rr);
544
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200545 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700546 EXPECT_EQ(
547 0, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000548}
549
danilchap1e714ae2016-09-05 09:57:22 -0700550// Ij packets are ignored.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000551TEST_F(RtcpReceiverTest, InjectIjWithNoItem) {
danilchapf8506cb2015-11-13 07:33:20 -0800552 rtcp::ExtendedJitterReport ij;
danilchap1e714ae2016-09-05 09:57:22 -0700553 InjectRtcpPacket(ij);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000554}
555
danilchap1e714ae2016-09-05 09:57:22 -0700556// App packets are ignored.
557TEST_F(RtcpReceiverTest, InjectApp) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000558 rtcp::App app;
danilchap822a16f2016-09-27 09:27:47 -0700559 app.SetSubType(30);
560 app.SetName(0x17a177e);
danilchap1e714ae2016-09-05 09:57:22 -0700561 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
danilchap822a16f2016-09-27 09:27:47 -0700562 app.SetData(kData, sizeof(kData));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000563
danilchap1e714ae2016-09-05 09:57:22 -0700564 InjectRtcpPacket(app);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000565}
566
567TEST_F(RtcpReceiverTest, InjectSdesWithOneChunk) {
danilchap1e714ae2016-09-05 09:57:22 -0700568 const char kCname[] = "alice@host";
569 MockRtcpCallbackImpl callback;
570 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000571 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700572 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000573
danilchap1e714ae2016-09-05 09:57:22 -0700574 EXPECT_CALL(callback, CNameChanged(StrEq(kCname), kSenderSsrc));
575 InjectRtcpPacket(sdes);
576
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000577 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700578 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
579 EXPECT_EQ(0, strncmp(cName, kCname, RTCP_CNAME_SIZE));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000580}
581
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000582TEST_F(RtcpReceiverTest, InjectByePacket_RemovesCname) {
danilchap1e714ae2016-09-05 09:57:22 -0700583 const char kCname[] = "alice@host";
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000584 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700585 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000586
danilchap1e714ae2016-09-05 09:57:22 -0700587 InjectRtcpPacket(sdes);
588
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000589 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700590 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000591
592 // Verify that BYE removes the CNAME.
593 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700594 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700595
596 InjectRtcpPacket(bye);
597
598 EXPECT_EQ(-1, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000599}
600
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000601TEST_F(RtcpReceiverTest, InjectByePacket_RemovesReportBlocks) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000602 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700603 rb1.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000604 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700605 rb2.SetMediaSsrc(kReceiverExtraSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000606 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700607 rr.SetSenderSsrc(kSenderSsrc);
608 rr.AddReportBlock(rb1);
609 rr.AddReportBlock(rb2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000610
danilchap1e714ae2016-09-05 09:57:22 -0700611 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
612 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
613 InjectRtcpPacket(rr);
614
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000615 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700616 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000617 EXPECT_EQ(2u, received_blocks.size());
618
619 // Verify that BYE removes the report blocks.
620 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700621 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700622
623 InjectRtcpPacket(bye);
624
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000625 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700626 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000627 EXPECT_TRUE(received_blocks.empty());
628
danilchap1e714ae2016-09-05 09:57:22 -0700629 // Inject packet again.
630 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
631 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
632 InjectRtcpPacket(rr);
633
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000634 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700635 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000636 EXPECT_EQ(2u, received_blocks.size());
637}
638
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200639TEST_F(RtcpReceiverTest, InjectByePacketRemovesReferenceTimeInfo) {
640 rtcp::ExtendedReports xr;
641 xr.SetSenderSsrc(kSenderSsrc);
642 rtcp::Rrtr rrtr;
643 rrtr.SetNtp(NtpTime(0x10203, 0x40506));
644 xr.SetRrtr(rrtr);
645 InjectRtcpPacket(xr);
646
647 rtcp::Bye bye;
648 bye.SetSenderSsrc(kSenderSsrc);
649 InjectRtcpPacket(bye);
650
651 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
652}
653
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000654TEST_F(RtcpReceiverTest, InjectPliPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000655 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700656 pli.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700657
658 EXPECT_CALL(
659 packet_type_counter_observer_,
660 RtcpPacketTypesCounterUpdated(
661 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 1)));
662 EXPECT_CALL(intra_frame_observer_,
663 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
664 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000665}
666
667TEST_F(RtcpReceiverTest, PliPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000668 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700669 pli.SetMediaSsrc(kNotToUsSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700670
671 EXPECT_CALL(
672 packet_type_counter_observer_,
673 RtcpPacketTypesCounterUpdated(
674 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 0)));
675 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
676 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000677}
678
679TEST_F(RtcpReceiverTest, InjectFirPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000680 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700681 fir.AddRequestTo(kReceiverMainSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700682
683 EXPECT_CALL(
684 packet_type_counter_observer_,
685 RtcpPacketTypesCounterUpdated(
686 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::fir_packets, 1)));
687 EXPECT_CALL(intra_frame_observer_,
688 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
689 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000690}
691
692TEST_F(RtcpReceiverTest, FirPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000693 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700694 fir.AddRequestTo(kNotToUsSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700695
696 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
697 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000698}
699
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100700TEST_F(RtcpReceiverTest, ExtendedReportsPacketWithZeroReportBlocksIgnored) {
701 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700702 xr.SetSenderSsrc(kSenderSsrc);
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, InjectExtendedReportsReceiverReferenceTimePacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700708 const NtpTime kNtp(0x10203, 0x40506);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000709 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700710 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100711 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700712 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700713 xr.SetRrtr(rrtr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000714
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200715 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
716 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
717 EXPECT_THAT(last_xr_rtis, IsEmpty());
danilchap1e714ae2016-09-05 09:57:22 -0700718
719 InjectRtcpPacket(xr);
720
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200721 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
722 ASSERT_THAT(last_xr_rtis, SizeIs(1));
723 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
724 EXPECT_EQ(CompactNtp(kNtp), last_xr_rtis[0].last_rr);
725 EXPECT_EQ(0U, last_xr_rtis[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000726}
727
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100728TEST_F(RtcpReceiverTest, ExtendedReportsDlrrPacketNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700729 // Allow calculate rtt using dlrr/rrtr, simulating media receiver side.
730 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000731
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100732 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700733 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700734 xr.AddDlrrItem(ReceiveTimeInfo(kNotToUsSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700735
736 InjectRtcpPacket(xr);
737
738 int64_t rtt_ms = 0;
739 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000740}
741
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100742TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithSubBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700743 const uint32_t kLastRR = 0x12345;
744 const uint32_t kDelay = 0x23456;
745 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
746 int64_t rtt_ms = 0;
747 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000748
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100749 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700750 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700751 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
danilchap1e714ae2016-09-05 09:57:22 -0700752
753 InjectRtcpPacket(xr);
754
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200755 uint32_t compact_ntp_now =
756 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700757 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
758 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
759 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000760}
761
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100762TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithMultipleSubBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700763 const uint32_t kLastRR = 0x12345;
764 const uint32_t kDelay = 0x56789;
765 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000766
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100767 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700768 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700769 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
770 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 1, 0x12345, 0x67890));
771 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 2, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700772
773 InjectRtcpPacket(xr);
774
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200775 uint32_t compact_ntp_now =
776 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700777 int64_t rtt_ms = 0;
778 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
779 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
780 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000781}
782
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100783TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithMultipleReportBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700784 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000785
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000786 rtcp::Rrtr rrtr;
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100787 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700788 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700789 xr.SetRrtr(rrtr);
790 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700791
792 InjectRtcpPacket(xr);
793
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200794 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
795 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
796 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700797 int64_t rtt_ms = 0;
798 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000799}
800
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100801TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithUnknownReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700802 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000803
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000804 rtcp::Rrtr rrtr;
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100805 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700806 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700807 xr.SetRrtr(rrtr);
808 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700809
danilchap69e59e62016-02-17 03:11:42 -0800810 rtc::Buffer packet = xr.Build();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000811 // Modify the DLRR block to have an unsupported block type, from 5 to 6.
danilchap1e714ae2016-09-05 09:57:22 -0700812 ASSERT_EQ(5, packet.data()[20]);
813 packet.data()[20] = 6;
814 InjectRtcpPacket(packet);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000815
danilchap1e714ae2016-09-05 09:57:22 -0700816 // Validate Rrtr was received and processed.
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200817 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
818 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
819 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700820 // Validate Dlrr report wasn't processed.
821 int64_t rtt_ms = 0;
822 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000823}
824
danilchap1e714ae2016-09-05 09:57:22 -0700825TEST_F(RtcpReceiverTest, TestExtendedReportsRrRttInitiallyFalse) {
826 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
827
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000828 int64_t rtt_ms;
danilchap1e714ae2016-09-05 09:57:22 -0700829 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000830}
831
danilchap1e714ae2016-09-05 09:57:22 -0700832TEST_F(RtcpReceiverTest, RttCalculatedAfterExtendedReportsDlrr) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100833 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100834 const int64_t kRttMs = rand.Rand(1, 9 * 3600 * 1000);
835 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
836 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700837 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200838 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalova094fd12016-02-22 18:59:36 +0100839 uint32_t sent_ntp = CompactNtp(now);
840 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
841
Danil Chapovalova094fd12016-02-22 18:59:36 +0100842 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700843 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700844 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700845
846 InjectRtcpPacket(xr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100847
848 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700849 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100850 EXPECT_NEAR(kRttMs, rtt_ms, 1);
851}
852
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100853TEST_F(RtcpReceiverTest, XrDlrrCalculatesNegativeRttAsOne) {
854 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100855 const int64_t kRttMs = rand.Rand(-3600 * 1000, -1);
856 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
857 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200858 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100859 uint32_t sent_ntp = CompactNtp(now);
860 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
danilchap1e714ae2016-09-05 09:57:22 -0700861 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100862
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100863 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700864 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700865 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700866
867 InjectRtcpPacket(xr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100868
869 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700870 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100871 EXPECT_EQ(1, rtt_ms);
872}
873
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200874TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfoInitiallyEmpty) {
875 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000876}
877
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200878TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfo) {
Danil Chapovalovfc47ed62015-12-07 14:46:35 +0100879 const NtpTime kNtp(0x10203, 0x40506);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100880 const uint32_t kNtpMid = CompactNtp(kNtp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000881
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000882 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700883 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100884 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700885 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700886 xr.SetRrtr(rrtr);
danilchap1e714ae2016-09-05 09:57:22 -0700887
888 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000889
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000890 system_clock_.AdvanceTimeMilliseconds(1000);
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200891
892 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
893 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
894 ASSERT_THAT(last_xr_rtis, SizeIs(1));
895 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
896 EXPECT_EQ(kNtpMid, last_xr_rtis[0].last_rr);
897 EXPECT_EQ(65536U, last_xr_rtis[0].delay_since_last_rr);
898}
899
900TEST_F(RtcpReceiverTest,
901 ReceivedRrtrFromSameSsrcUpdatesReceivedReferenceTimeInfo) {
902 const NtpTime kNtp1(0x10203, 0x40506);
903 const NtpTime kNtp2(0x11223, 0x44556);
904 const int64_t kDelayMs = 2000;
905
906 rtcp::ExtendedReports xr;
907 xr.SetSenderSsrc(kSenderSsrc);
908 rtcp::Rrtr rrtr1;
909 rrtr1.SetNtp(kNtp1);
910 xr.SetRrtr(rrtr1);
911 InjectRtcpPacket(xr);
912 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
913 rtcp::Rrtr rrtr2;
914 rrtr2.SetNtp(kNtp2);
915 xr.SetRrtr(rrtr2);
916 InjectRtcpPacket(xr);
917 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
918
919 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
920 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
921 ASSERT_THAT(last_xr_rtis, SizeIs(1));
922 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
923 EXPECT_EQ(CompactNtp(kNtp2), last_xr_rtis[0].last_rr);
924 EXPECT_EQ(kDelayMs * 65536 / 1000, last_xr_rtis[0].delay_since_last_rr);
925}
926
927TEST_F(RtcpReceiverTest, StoresLastReceivedRrtrPerSsrc) {
928 const size_t kNumBufferedReports = 1;
929 const size_t kNumReports =
930 rtcp::ExtendedReports::kMaxNumberOfDlrrItems + kNumBufferedReports;
931 for (size_t i = 0; i < kNumReports; ++i) {
932 rtcp::ExtendedReports xr;
933 xr.SetSenderSsrc(i * 100);
934 rtcp::Rrtr rrtr;
935 rrtr.SetNtp(NtpTime(i * 200, i * 300));
936 xr.SetRrtr(rrtr);
937 InjectRtcpPacket(xr);
938 system_clock_.AdvanceTimeMilliseconds(1000);
939 }
940
941 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
942 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
943 ASSERT_THAT(last_xr_rtis,
944 SizeIs(rtcp::ExtendedReports::kMaxNumberOfDlrrItems));
945 for (size_t i = 0; i < rtcp::ExtendedReports::kMaxNumberOfDlrrItems; ++i) {
946 EXPECT_EQ(i * 100, last_xr_rtis[i].ssrc);
947 EXPECT_EQ(CompactNtp(NtpTime(i * 200, i * 300)), last_xr_rtis[i].last_rr);
948 EXPECT_EQ(65536U * (kNumReports - i), last_xr_rtis[i].delay_since_last_rr);
949 }
950
951 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
952 ASSERT_THAT(last_xr_rtis, SizeIs(kNumBufferedReports));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000953}
954
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000955TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000956 const uint16_t kSequenceNumber = 1234;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000957 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000958
959 // No RR received, shouldn't trigger a timeout.
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800960 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
961 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000962
963 // Add a RR and advance the clock just enough to not trigger a timeout.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000964 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700965 rb1.SetMediaSsrc(kReceiverMainSsrc);
966 rb1.SetExtHighestSeqNum(kSequenceNumber);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000967 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700968 rr1.SetSenderSsrc(kSenderSsrc);
969 rr1.AddReportBlock(rb1);
danilchap1e714ae2016-09-05 09:57:22 -0700970
971 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
972 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
973 InjectRtcpPacket(rr1);
974
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000975 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs - 1);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800976 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
977 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000978
979 // Add a RR with the same extended max as the previous RR to trigger a
980 // sequence number timeout, but not a RR timeout.
danilchap1e714ae2016-09-05 09:57:22 -0700981 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
982 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
983 InjectRtcpPacket(rr1);
984
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000985 system_clock_.AdvanceTimeMilliseconds(2);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800986 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
987 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000988
989 // Advance clock enough to trigger an RR timeout too.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000990 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800991 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000992
993 // We should only get one timeout even though we still haven't received a new
994 // RR.
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800995 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
996 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000997
998 // Add a new RR with increase sequence number to reset timers.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000999 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001000 rb2.SetMediaSsrc(kReceiverMainSsrc);
1001 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001002 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001003 rr2.SetSenderSsrc(kSenderSsrc);
1004 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001005
1006 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1007 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1008 InjectRtcpPacket(rr2);
1009
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001010 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1011 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001012
1013 // Verify we can get a timeout again once we've received new RR.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001014 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -07001015 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1016 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1017 InjectRtcpPacket(rr2);
1018
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001019 system_clock_.AdvanceTimeMilliseconds(kRtcpIntervalMs + 1);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001020 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1021 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
danilchap1e714ae2016-09-05 09:57:22 -07001022
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001023 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001024 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001025}
1026
hta@webrtc.org47059b52012-05-02 07:46:22 +00001027TEST_F(RtcpReceiverTest, TmmbrReceivedWithNoIncomingPacket) {
danilchap1e714ae2016-09-05 09:57:22 -07001028 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001029}
1030
1031TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) {
danilchap1e714ae2016-09-05 09:57:22 -07001032 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001033 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001034 tmmbr.SetSenderSsrc(kSenderSsrc);
1035 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001036 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001037 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001038 rtcp::CompoundPacket compound;
1039 compound.Append(&sr);
1040 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001041
danilchap1e714ae2016-09-05 09:57:22 -07001042 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1043 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(SizeIs(1)));
1044 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1045 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1046 InjectRtcpPacket(compound);
1047
1048 std::vector<rtcp::TmmbItem> tmmbr_received = rtcp_receiver_.TmmbrReceived();
1049 ASSERT_EQ(1u, tmmbr_received.size());
1050 EXPECT_EQ(kBitrateBps, tmmbr_received[0].bitrate_bps());
1051 EXPECT_EQ(kSenderSsrc, tmmbr_received[0].ssrc());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001052}
1053
1054TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -07001055 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001056 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001057 tmmbr.SetSenderSsrc(kSenderSsrc);
1058 tmmbr.AddTmmbr(rtcp::TmmbItem(kNotToUsSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001059
1060 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001061 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001062 rtcp::CompoundPacket compound;
1063 compound.Append(&sr);
1064 compound.Append(&tmmbr);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001065
danilchap1e714ae2016-09-05 09:57:22 -07001066 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1067 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1068 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1069 InjectRtcpPacket(compound);
1070
1071 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001072}
1073
1074TEST_F(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001075 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001076 tmmbr.SetSenderSsrc(kSenderSsrc);
1077 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 0, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001078 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001079 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001080 rtcp::CompoundPacket compound;
1081 compound.Append(&sr);
1082 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001083
danilchap1e714ae2016-09-05 09:57:22 -07001084 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1085 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1086 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1087 InjectRtcpPacket(compound);
1088
1089 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001090}
1091
hta@webrtc.org404843e2012-05-02 09:56:45 +00001092TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001093 // Inject 3 packets "from" kSenderSsrc, kSenderSsrc+1, kSenderSsrc+2.
hta@webrtc.org404843e2012-05-02 09:56:45 +00001094 // The times of arrival are starttime + 0, starttime + 5 and starttime + 10.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001095 for (uint32_t ssrc = kSenderSsrc; ssrc < kSenderSsrc + 3; ++ssrc) {
1096 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001097 tmmbr.SetSenderSsrc(ssrc);
1098 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 30000, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001099 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001100 sr.SetSenderSsrc(ssrc);
danilchap7a4116a2016-03-14 08:19:28 -07001101 rtcp::CompoundPacket compound;
1102 compound.Append(&sr);
1103 compound.Append(&tmmbr);
danilchap1e714ae2016-09-05 09:57:22 -07001104
1105 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1106 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(_));
1107 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1108 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_));
1109 InjectRtcpPacket(compound);
1110
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001111 // 5 seconds between each packet.
1112 system_clock_.AdvanceTimeMilliseconds(5000);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001113 }
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001114 // It is now starttime + 15.
danilchap1e714ae2016-09-05 09:57:22 -07001115 std::vector<rtcp::TmmbItem> candidate_set = rtcp_receiver_.TmmbrReceived();
1116 ASSERT_EQ(3u, candidate_set.size());
1117 EXPECT_EQ(30000U, candidate_set[0].bitrate_bps());
1118
hta@webrtc.org404843e2012-05-02 09:56:45 +00001119 // We expect the timeout to be 25 seconds. Advance the clock by 12
1120 // seconds, timing out the first packet.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001121 system_clock_.AdvanceTimeMilliseconds(12000);
danilchap1e714ae2016-09-05 09:57:22 -07001122 candidate_set = rtcp_receiver_.TmmbrReceived();
1123 ASSERT_EQ(2u, candidate_set.size());
danilchap287e5482016-08-16 15:15:39 -07001124 EXPECT_EQ(kSenderSsrc + 1, candidate_set[0].ssrc());
hta@webrtc.org404843e2012-05-02 09:56:45 +00001125}
1126
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001127TEST_F(RtcpReceiverTest, Callbacks) {
danilchap1e714ae2016-09-05 09:57:22 -07001128 MockRtcpCallbackImpl callback;
1129 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001130
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001131 const uint8_t kFractionLoss = 3;
1132 const uint32_t kCumulativeLoss = 7;
1133 const uint32_t kJitter = 9;
1134 const uint16_t kSequenceNumber = 1234;
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001135
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001136 // First packet, all numbers should just propagate.
1137 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -07001138 rb1.SetMediaSsrc(kReceiverMainSsrc);
1139 rb1.SetExtHighestSeqNum(kSequenceNumber);
1140 rb1.SetFractionLost(kFractionLoss);
1141 rb1.SetCumulativeLost(kCumulativeLoss);
1142 rb1.SetJitter(kJitter);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001143
1144 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -07001145 rr1.SetSenderSsrc(kSenderSsrc);
1146 rr1.AddReportBlock(rb1);
srte186d9c32017-08-04 05:03:53 -07001147 EXPECT_CALL(callback,
1148 StatisticsUpdated(
1149 AllOf(Field(&RtcpStatistics::fraction_lost, kFractionLoss),
1150 Field(&RtcpStatistics::packets_lost, kCumulativeLoss),
1151 Field(&RtcpStatistics::extended_highest_sequence_number,
1152 kSequenceNumber),
1153 Field(&RtcpStatistics::jitter, kJitter)),
1154 kReceiverMainSsrc));
danilchap1e714ae2016-09-05 09:57:22 -07001155 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1156 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1157 InjectRtcpPacket(rr1);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001158
danilchap1e714ae2016-09-05 09:57:22 -07001159 rtcp_receiver_.RegisterRtcpStatisticsCallback(nullptr);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001160
danilchap1e714ae2016-09-05 09:57:22 -07001161 // Add arbitrary numbers, callback should not be called.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001162 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001163 rb2.SetMediaSsrc(kReceiverMainSsrc);
1164 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
1165 rb2.SetFractionLost(42);
1166 rb2.SetCumulativeLost(137);
1167 rb2.SetJitter(4711);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001168
1169 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001170 rr2.SetSenderSsrc(kSenderSsrc);
1171 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001172
1173 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1174 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1175 EXPECT_CALL(callback, StatisticsUpdated(_, _)).Times(0);
1176 InjectRtcpPacket(rr2);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001177}
hta@webrtc.org404843e2012-05-02 09:56:45 +00001178
sprang49f9cdb2015-10-01 03:06:57 -07001179TEST_F(RtcpReceiverTest, ReceivesTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001180 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001181 packet.SetMediaSsrc(kReceiverMainSsrc);
1182 packet.SetSenderSsrc(kSenderSsrc);
1183 packet.SetBase(1, 1000);
1184 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001185
danilchap1e714ae2016-09-05 09:57:22 -07001186 EXPECT_CALL(
1187 transport_feedback_observer_,
1188 OnTransportFeedback(AllOf(
1189 Property(&rtcp::TransportFeedback::media_ssrc, kReceiverMainSsrc),
1190 Property(&rtcp::TransportFeedback::sender_ssrc, kSenderSsrc))));
1191 InjectRtcpPacket(packet);
sprang49f9cdb2015-10-01 03:06:57 -07001192}
1193
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001194TEST_F(RtcpReceiverTest, ReceivesRemb) {
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001195 const uint32_t kBitrateBps = 500000;
1196 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001197 remb.SetSenderSsrc(kSenderSsrc);
1198 remb.SetBitrateBps(kBitrateBps);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001199
danilchap1e714ae2016-09-05 09:57:22 -07001200 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1201 InjectRtcpPacket(remb);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001202}
1203
sprang49f9cdb2015-10-01 03:06:57 -07001204TEST_F(RtcpReceiverTest, HandlesInvalidTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001205 // Send a compound packet with a TransportFeedback followed by something else.
1206 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001207 packet.SetMediaSsrc(kReceiverMainSsrc);
1208 packet.SetSenderSsrc(kSenderSsrc);
1209 packet.SetBase(1, 1000);
1210 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001211
1212 static uint32_t kBitrateBps = 50000;
1213 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001214 remb.SetSenderSsrc(kSenderSsrc);
1215 remb.SetBitrateBps(kBitrateBps);
danilchap7a4116a2016-03-14 08:19:28 -07001216 rtcp::CompoundPacket compound;
1217 compound.Append(&packet);
1218 compound.Append(&remb);
1219 rtc::Buffer built_packet = compound.Build();
sprang49f9cdb2015-10-01 03:06:57 -07001220
1221 // Modify the TransportFeedback packet so that it is invalid.
1222 const size_t kStatusCountOffset = 14;
Yves Gerey665174f2018-06-19 15:03:05 +02001223 ByteWriter<uint16_t>::WriteBigEndian(&built_packet.data()[kStatusCountOffset],
1224 42);
sprang49f9cdb2015-10-01 03:06:57 -07001225
danilchap1e714ae2016-09-05 09:57:22 -07001226 // Stress no transport feedback is expected.
1227 EXPECT_CALL(transport_feedback_observer_, OnTransportFeedback(_)).Times(0);
1228 // But remb should be processed and cause a callback
1229 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1230 InjectRtcpPacket(built_packet);
sprang49f9cdb2015-10-01 03:06:57 -07001231}
1232
danilchap1e714ae2016-09-05 09:57:22 -07001233TEST_F(RtcpReceiverTest, Nack) {
1234 const uint16_t kNackList1[] = {1, 2, 3, 5};
danilchap142f0192016-10-20 08:22:42 -07001235 const uint16_t kNackList23[] = {5, 7, 30, 40, 41, 58, 59, 61, 63};
1236 const size_t kNackListLength2 = 4;
1237 const size_t kNackListLength3 = arraysize(kNackList23) - kNackListLength2;
danilchap1e714ae2016-09-05 09:57:22 -07001238 std::set<uint16_t> nack_set;
1239 nack_set.insert(std::begin(kNackList1), std::end(kNackList1));
danilchap142f0192016-10-20 08:22:42 -07001240 nack_set.insert(std::begin(kNackList23), std::end(kNackList23));
danilchap1e714ae2016-09-05 09:57:22 -07001241
danilchap142f0192016-10-20 08:22:42 -07001242 rtcp::Nack nack1;
1243 nack1.SetSenderSsrc(kSenderSsrc);
1244 nack1.SetMediaSsrc(kReceiverMainSsrc);
1245 nack1.SetPacketIds(kNackList1, arraysize(kNackList1));
danilchap1e714ae2016-09-05 09:57:22 -07001246
1247 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList1)));
danilchap1e714ae2016-09-05 09:57:22 -07001248 EXPECT_CALL(packet_type_counter_observer_,
1249 RtcpPacketTypesCounterUpdated(
1250 kReceiverMainSsrc,
1251 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
danilchap142f0192016-10-20 08:22:42 -07001252 arraysize(kNackList1)),
1253 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1254 arraysize(kNackList1)))));
1255 InjectRtcpPacket(nack1);
1256
1257 rtcp::Nack nack2;
1258 nack2.SetSenderSsrc(kSenderSsrc);
1259 nack2.SetMediaSsrc(kReceiverMainSsrc);
1260 nack2.SetPacketIds(kNackList23, kNackListLength2);
1261
1262 rtcp::Nack nack3;
1263 nack3.SetSenderSsrc(kSenderSsrc);
1264 nack3.SetMediaSsrc(kReceiverMainSsrc);
1265 nack3.SetPacketIds(kNackList23 + kNackListLength2, kNackListLength3);
1266
1267 rtcp::CompoundPacket two_nacks;
1268 two_nacks.Append(&nack2);
1269 two_nacks.Append(&nack3);
1270
1271 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList23)));
1272 EXPECT_CALL(packet_type_counter_observer_,
1273 RtcpPacketTypesCounterUpdated(
1274 kReceiverMainSsrc,
1275 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
1276 arraysize(kNackList1) + arraysize(kNackList23)),
danilchap1e714ae2016-09-05 09:57:22 -07001277 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1278 nack_set.size()))));
danilchap142f0192016-10-20 08:22:42 -07001279 InjectRtcpPacket(two_nacks);
danilchap1e714ae2016-09-05 09:57:22 -07001280}
1281
1282TEST_F(RtcpReceiverTest, NackNotForUsIgnored) {
1283 const uint16_t kNackList1[] = {1, 2, 3, 5};
1284 const size_t kNackListLength1 = std::end(kNackList1) - std::begin(kNackList1);
1285
1286 rtcp::Nack nack;
danilchap822a16f2016-09-27 09:27:47 -07001287 nack.SetSenderSsrc(kSenderSsrc);
1288 nack.SetMediaSsrc(kNotToUsSsrc);
1289 nack.SetPacketIds(kNackList1, kNackListLength1);
danilchap1e714ae2016-09-05 09:57:22 -07001290
1291 EXPECT_CALL(packet_type_counter_observer_,
1292 RtcpPacketTypesCounterUpdated(
1293 _, Field(&RtcpPacketTypeCounter::nack_requests, 0)));
1294 InjectRtcpPacket(nack);
1295}
1296
1297TEST_F(RtcpReceiverTest, ForceSenderReport) {
1298 rtcp::RapidResyncRequest rr;
danilchap822a16f2016-09-27 09:27:47 -07001299 rr.SetSenderSsrc(kSenderSsrc);
1300 rr.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -07001301
1302 EXPECT_CALL(rtp_rtcp_impl_, OnRequestSendReport());
1303 InjectRtcpPacket(rr);
1304}
hta@webrtc.org47059b52012-05-02 07:46:22 +00001305
spranga790d832016-12-02 07:29:44 -08001306TEST_F(RtcpReceiverTest, ReceivesTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001307 VideoBitrateAllocation expected_allocation;
spranga790d832016-12-02 07:29:44 -08001308 expected_allocation.SetBitrate(0, 0, 10000);
1309 expected_allocation.SetBitrate(0, 1, 20000);
1310 expected_allocation.SetBitrate(1, 0, 40000);
1311 expected_allocation.SetBitrate(1, 1, 80000);
1312
1313 rtcp::TargetBitrate bitrate;
1314 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1315 bitrate.AddTargetBitrate(0, 1, expected_allocation.GetBitrate(0, 1) / 1000);
1316 bitrate.AddTargetBitrate(1, 0, expected_allocation.GetBitrate(1, 0) / 1000);
1317 bitrate.AddTargetBitrate(1, 1, expected_allocation.GetBitrate(1, 1) / 1000);
1318
1319 rtcp::ExtendedReports xr;
1320 xr.SetTargetBitrate(bitrate);
1321
sprangb32aaf92017-08-28 05:49:12 -07001322 // Wrong sender ssrc, target bitrate should be discarded.
1323 xr.SetSenderSsrc(kSenderSsrc + 1);
1324 EXPECT_CALL(bitrate_allocation_observer_,
1325 OnBitrateAllocationUpdated(expected_allocation))
1326 .Times(0);
1327 InjectRtcpPacket(xr);
1328
1329 // Set correct ssrc, callback should be called once.
1330 xr.SetSenderSsrc(kSenderSsrc);
spranga790d832016-12-02 07:29:44 -08001331 EXPECT_CALL(bitrate_allocation_observer_,
1332 OnBitrateAllocationUpdated(expected_allocation));
1333 InjectRtcpPacket(xr);
1334}
1335
sprang6d314c72016-12-06 06:08:53 -08001336TEST_F(RtcpReceiverTest, HandlesIncorrectTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001337 VideoBitrateAllocation expected_allocation;
sprang6d314c72016-12-06 06:08:53 -08001338 expected_allocation.SetBitrate(0, 0, 10000);
1339
1340 rtcp::TargetBitrate bitrate;
1341 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1342 bitrate.AddTargetBitrate(0, kMaxTemporalStreams, 20000);
1343 bitrate.AddTargetBitrate(kMaxSpatialLayers, 0, 40000);
1344
1345 rtcp::ExtendedReports xr;
1346 xr.SetTargetBitrate(bitrate);
sprangb32aaf92017-08-28 05:49:12 -07001347 xr.SetSenderSsrc(kSenderSsrc);
sprang6d314c72016-12-06 06:08:53 -08001348
1349 EXPECT_CALL(bitrate_allocation_observer_,
1350 OnBitrateAllocationUpdated(expected_allocation));
1351 InjectRtcpPacket(xr);
1352}
1353
hta@webrtc.org47059b52012-05-02 07:46:22 +00001354} // namespace webrtc