blob: 85337a9bbb3b0606e4234e2d572374a4a47c3e67 [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"
Mirko Bonadei71207422017-09-15 13:58:09 +020014#include "common_types.h" // NOLINT(build/include)
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "common_video/include/video_bitrate_allocator.h"
16#include "modules/rtp_rtcp/source/byte_io.h"
17#include "modules/rtp_rtcp/source/rtcp_packet.h"
18#include "modules/rtp_rtcp/source/rtcp_packet/app.h"
19#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
20#include "modules/rtp_rtcp/source/rtcp_packet/compound_packet.h"
21#include "modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.h"
22#include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
23#include "modules/rtp_rtcp/source/rtcp_packet/fir.h"
24#include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
25#include "modules/rtp_rtcp/source/rtcp_packet/pli.h"
26#include "modules/rtp_rtcp/source/rtcp_packet/rapid_resync_request.h"
27#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
28#include "modules/rtp_rtcp/source/rtcp_packet/remb.h"
29#include "modules/rtp_rtcp/source/rtcp_packet/sdes.h"
30#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
31#include "modules/rtp_rtcp/source/rtcp_packet/tmmbr.h"
32#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
33#include "modules/rtp_rtcp/source/rtcp_receiver.h"
34#include "modules/rtp_rtcp/source/time_util.h"
35#include "rtc_base/arraysize.h"
36#include "rtc_base/random.h"
37#include "system_wrappers/include/ntp_time.h"
38#include "test/gmock.h"
39#include "test/gtest.h"
hta@webrtc.org47059b52012-05-02 07:46:22 +000040
41namespace webrtc {
danilchap1e714ae2016-09-05 09:57:22 -070042namespace {
hta@webrtc.org47059b52012-05-02 07:46:22 +000043
danilchap1e714ae2016-09-05 09:57:22 -070044using ::testing::_;
45using ::testing::AllOf;
46using ::testing::ElementsAreArray;
47using ::testing::Field;
48using ::testing::IsEmpty;
49using ::testing::NiceMock;
50using ::testing::Property;
51using ::testing::SizeIs;
52using ::testing::StrEq;
53using ::testing::StrictMock;
54using ::testing::UnorderedElementsAre;
danilchap80ac24d2016-10-31 08:40:47 -070055using rtcp::ReceiveTimeInfo;
hta@webrtc.org47059b52012-05-02 07:46:22 +000056
danilchap1e714ae2016-09-05 09:57:22 -070057class MockRtcpPacketTypeCounterObserver : public RtcpPacketTypeCounterObserver {
hta@webrtc.org47059b52012-05-02 07:46:22 +000058 public:
danilchap1e714ae2016-09-05 09:57:22 -070059 MOCK_METHOD2(RtcpPacketTypesCounterUpdated,
60 void(uint32_t, const RtcpPacketTypeCounter&));
hta@webrtc.org47059b52012-05-02 07:46:22 +000061};
62
danilchap1e714ae2016-09-05 09:57:22 -070063class MockRtcpIntraFrameObserver : public RtcpIntraFrameObserver {
64 public:
65 MOCK_METHOD1(OnReceivedIntraFrameRequest, void(uint32_t));
danilchap1e714ae2016-09-05 09:57:22 -070066};
67
68class MockRtcpCallbackImpl : public RtcpStatisticsCallback {
69 public:
70 MOCK_METHOD2(StatisticsUpdated, void(const RtcpStatistics&, uint32_t));
71 MOCK_METHOD2(CNameChanged, void(const char*, uint32_t));
72};
73
74class MockTransportFeedbackObserver : public TransportFeedbackObserver {
75 public:
elad.alond12a8e12017-03-23 11:04:48 -070076 MOCK_METHOD3(AddPacket, void(uint32_t, uint16_t, size_t));
77 MOCK_METHOD4(AddPacket,
78 void(uint32_t, uint16_t, size_t, const PacedPacketInfo&));
danilchap1e714ae2016-09-05 09:57:22 -070079 MOCK_METHOD1(OnTransportFeedback, void(const rtcp::TransportFeedback&));
elad.alonf9490002017-03-06 05:32:21 -080080 MOCK_CONST_METHOD0(GetTransportFeedbackVector, std::vector<PacketFeedback>());
danilchap1e714ae2016-09-05 09:57:22 -070081};
82
83class MockRtcpBandwidthObserver : public RtcpBandwidthObserver {
84 public:
85 MOCK_METHOD1(OnReceivedEstimatedBitrate, void(uint32_t));
86 MOCK_METHOD3(OnReceivedRtcpReceiverReport,
87 void(const ReportBlockList&, int64_t, int64_t));
88};
89
90class MockModuleRtpRtcp : public RTCPReceiver::ModuleRtpRtcp {
91 public:
92 MOCK_METHOD1(SetTmmbn, void(std::vector<rtcp::TmmbItem>));
93 MOCK_METHOD0(OnRequestSendReport, void());
94 MOCK_METHOD1(OnReceivedNack, void(const std::vector<uint16_t>&));
95 MOCK_METHOD1(OnReceivedRtcpReportBlocks, void(const ReportBlockList&));
96};
97
spranga790d832016-12-02 07:29:44 -080098class MockVideoBitrateAllocationObserver
99 : public VideoBitrateAllocationObserver {
100 public:
101 MOCK_METHOD1(OnBitrateAllocationUpdated,
102 void(const BitrateAllocation& allocation));
103};
104
danilchap1e714ae2016-09-05 09:57:22 -0700105// SSRC of remote peer, that sends rtcp packet to the rtcp receiver under test.
106constexpr uint32_t kSenderSsrc = 0x10203;
107// SSRCs of local peer, that rtcp packet addressed to.
108constexpr uint32_t kReceiverMainSsrc = 0x123456;
109// RtcpReceiver can accept several ssrc, e.g. regular and rtx streams.
110constexpr uint32_t kReceiverExtraSsrc = 0x1234567;
111// SSRCs to ignore (i.e. not configured in RtcpReceiver).
112constexpr uint32_t kNotToUsSsrc = 0x654321;
113constexpr uint32_t kUnknownSenderSsrc = 0x54321;
114
115} // namespace
116
hta@webrtc.org47059b52012-05-02 07:46:22 +0000117class RtcpReceiverTest : public ::testing::Test {
118 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000119 RtcpReceiverTest()
danilchap1e714ae2016-09-05 09:57:22 -0700120 : system_clock_(1335900000),
121 rtcp_receiver_(&system_clock_,
122 false,
123 &packet_type_counter_observer_,
124 &bandwidth_observer_,
125 &intra_frame_observer_,
126 &transport_feedback_observer_,
spranga790d832016-12-02 07:29:44 -0800127 &bitrate_allocation_observer_,
danilchap1e714ae2016-09-05 09:57:22 -0700128 &rtp_rtcp_impl_) {}
129 void SetUp() {
130 std::set<uint32_t> ssrcs = {kReceiverMainSsrc, kReceiverExtraSsrc};
danilchap1e714ae2016-09-05 09:57:22 -0700131 rtcp_receiver_.SetSsrcs(kReceiverMainSsrc, ssrcs);
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000132
danilchap1e714ae2016-09-05 09:57:22 -0700133 rtcp_receiver_.SetRemoteSSRC(kSenderSsrc);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000134 }
Erik Språng737336d2016-07-29 12:59:36 +0200135
danilchap1e714ae2016-09-05 09:57:22 -0700136 void InjectRtcpPacket(rtc::ArrayView<const uint8_t> raw) {
137 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
hta@webrtc.org47059b52012-05-02 07:46:22 +0000138 }
139
danilchap1e714ae2016-09-05 09:57:22 -0700140 void InjectRtcpPacket(const rtcp::RtcpPacket& packet) {
141 rtc::Buffer raw = packet.Build();
142 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
143 }
144
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000145 SimulatedClock system_clock_;
danilchap1e714ae2016-09-05 09:57:22 -0700146 // Callbacks to packet_type_counter_observer are frequent but most of the time
147 // are not interesting.
148 NiceMock<MockRtcpPacketTypeCounterObserver> packet_type_counter_observer_;
149 StrictMock<MockRtcpBandwidthObserver> bandwidth_observer_;
150 StrictMock<MockRtcpIntraFrameObserver> intra_frame_observer_;
151 StrictMock<MockTransportFeedbackObserver> transport_feedback_observer_;
spranga790d832016-12-02 07:29:44 -0800152 StrictMock<MockVideoBitrateAllocationObserver> bitrate_allocation_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700153 StrictMock<MockModuleRtpRtcp> rtp_rtcp_impl_;
hta@webrtc.org47059b52012-05-02 07:46:22 +0000154
danilchap1e714ae2016-09-05 09:57:22 -0700155 RTCPReceiver rtcp_receiver_;
156};
hta@webrtc.org47059b52012-05-02 07:46:22 +0000157
158TEST_F(RtcpReceiverTest, BrokenPacketIsIgnored) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000159 const uint8_t bad_packet[] = {0, 0, 0, 0};
danilchap1e714ae2016-09-05 09:57:22 -0700160 EXPECT_CALL(packet_type_counter_observer_,
161 RtcpPacketTypesCounterUpdated(_, _))
162 .Times(0);
163 InjectRtcpPacket(bad_packet);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000164}
165
danilchap50da1d32016-03-10 13:13:52 -0800166TEST_F(RtcpReceiverTest, InvalidFeedbackPacketIsIgnored) {
167 // Too short feedback packet.
danilchap1e714ae2016-09-05 09:57:22 -0700168 const uint8_t bad_packet[] = {0x81, rtcp::Rtpfb::kPacketType, 0, 0};
169
170 // TODO(danilchap): Add expectation RtcpPacketTypesCounterUpdated
171 // is not called once parser would be adjusted to avoid that callback on
172 // semi-valid packets.
173 InjectRtcpPacket(bad_packet);
danilchap50da1d32016-03-10 13:13:52 -0800174}
175
hta@webrtc.org47059b52012-05-02 07:46:22 +0000176TEST_F(RtcpReceiverTest, InjectSrPacket) {
danilchapa04d9c32017-07-25 04:03:39 -0700177 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
danilchap1e714ae2016-09-05 09:57:22 -0700178
179 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000180 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700181 sr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700182
183 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
184 EXPECT_CALL(bandwidth_observer_,
185 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
186 InjectRtcpPacket(sr);
187
danilchapa04d9c32017-07-25 04:03:39 -0700188 EXPECT_TRUE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
hta@webrtc.org47059b52012-05-02 07:46:22 +0000189}
190
danilchap1e714ae2016-09-05 09:57:22 -0700191TEST_F(RtcpReceiverTest, InjectSrPacketFromUnknownSender) {
192 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000193 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700194 sr.SetSenderSsrc(kUnknownSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700195
196 // The parser will handle report blocks in Sender Report from other than his
197 // expected peer.
198 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
199 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, now));
200 InjectRtcpPacket(sr);
201
202 // But will not flag that he's gotten sender information.
danilchapa04d9c32017-07-25 04:03:39 -0700203 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000204}
205
Danil Chapovalova094fd12016-02-22 18:59:36 +0100206TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesRTT) {
207 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100208 const int64_t kRttMs = r.Rand(1, 9 * 3600 * 1000);
209 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
210 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100211
Danil Chapovalova094fd12016-02-22 18:59:36 +0100212 int64_t rtt_ms = 0;
213 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700214 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100215
danilchap37953762017-02-09 11:15:25 -0800216 uint32_t sent_ntp = CompactNtp(system_clock_.CurrentNtpTime());
Danil Chapovalova094fd12016-02-22 18:59:36 +0100217 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
218
219 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700220 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100221 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700222 block.SetMediaSsrc(kReceiverMainSsrc);
223 block.SetLastSr(sent_ntp);
224 block.SetDelayLastSr(kDelayNtp);
225 sr.AddReportBlock(block);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100226
danilchap1e714ae2016-09-05 09:57:22 -0700227 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
228 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
229 InjectRtcpPacket(sr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100230
231 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700232 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100233 EXPECT_NEAR(kRttMs, rtt_ms, 1);
234}
235
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100236TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesNegativeRTTAsOne) {
237 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100238 const int64_t kRttMs = r.Rand(-3600 * 1000, -1);
239 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
240 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
241
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100242 int64_t rtt_ms = 0;
243 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700244 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100245
danilchap37953762017-02-09 11:15:25 -0800246 uint32_t sent_ntp = CompactNtp(system_clock_.CurrentNtpTime());
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100247 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
248
249 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700250 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100251 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700252 block.SetMediaSsrc(kReceiverMainSsrc);
253 block.SetLastSr(sent_ntp);
254 block.SetDelayLastSr(kDelayNtp);
255 sr.AddReportBlock(block);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100256
danilchap1e714ae2016-09-05 09:57:22 -0700257 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
258 EXPECT_CALL(bandwidth_observer_,
259 OnReceivedRtcpReceiverReport(SizeIs(1), _, _));
260 InjectRtcpPacket(sr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100261
262 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700263 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100264 EXPECT_EQ(1, rtt_ms);
265}
266
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100267TEST_F(
268 RtcpReceiverTest,
269 TwoReportBlocksWithLastOneWithoutLastSrCalculatesRttForBandwidthObserver) {
270 const int64_t kRttMs = 120;
271 const uint32_t kDelayNtp = 123000;
272 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
273
274 uint32_t sent_ntp = CompactNtp(system_clock_.CurrentNtpTime());
275 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
276
277 rtcp::SenderReport sr;
278 sr.SetSenderSsrc(kSenderSsrc);
279 rtcp::ReportBlock block;
280 block.SetMediaSsrc(kReceiverMainSsrc);
281 block.SetLastSr(sent_ntp);
282 block.SetDelayLastSr(kDelayNtp);
283 sr.AddReportBlock(block);
284 block.SetMediaSsrc(kReceiverExtraSsrc);
285 block.SetLastSr(0);
286 sr.AddReportBlock(block);
287
288 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
289 EXPECT_CALL(bandwidth_observer_,
290 OnReceivedRtcpReceiverReport(SizeIs(2), kRttMs, _));
291 InjectRtcpPacket(sr);
292}
293
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000294TEST_F(RtcpReceiverTest, InjectRrPacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700295 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000296 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700297 rr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700298
299 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
300 EXPECT_CALL(bandwidth_observer_,
301 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
302 InjectRtcpPacket(rr);
303
danilchap1e714ae2016-09-05 09:57:22 -0700304 std::vector<RTCPReportBlock> report_blocks;
305 rtcp_receiver_.StatisticsReceived(&report_blocks);
306 EXPECT_TRUE(report_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000307}
308
309TEST_F(RtcpReceiverTest, InjectRrPacketWithReportBlockNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700310 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000311 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700312 rb.SetMediaSsrc(kNotToUsSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000313 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700314 rr.SetSenderSsrc(kSenderSsrc);
315 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000316
danilchap1e714ae2016-09-05 09:57:22 -0700317 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
318 EXPECT_CALL(bandwidth_observer_,
319 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
320 InjectRtcpPacket(rr);
321
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200322 EXPECT_EQ(0, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000323 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700324 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000325 EXPECT_TRUE(received_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000326}
327
328TEST_F(RtcpReceiverTest, InjectRrPacketWithOneReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700329 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000330
331 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700332 rb.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000333 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700334 rr.SetSenderSsrc(kSenderSsrc);
335 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000336
danilchap1e714ae2016-09-05 09:57:22 -0700337 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
338 EXPECT_CALL(bandwidth_observer_,
339 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
340 InjectRtcpPacket(rr);
341
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200342 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
343 std::vector<RTCPReportBlock> received_blocks;
344 rtcp_receiver_.StatisticsReceived(&received_blocks);
345 EXPECT_EQ(1u, received_blocks.size());
346}
347
348TEST_F(RtcpReceiverTest, InjectSrPacketWithOneReportBlock) {
349 int64_t now = system_clock_.TimeInMilliseconds();
350
351 rtcp::ReportBlock rb;
352 rb.SetMediaSsrc(kReceiverMainSsrc);
353 rtcp::SenderReport sr;
354 sr.SetSenderSsrc(kSenderSsrc);
355 sr.AddReportBlock(rb);
356
357 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
358 EXPECT_CALL(bandwidth_observer_,
359 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
360 InjectRtcpPacket(sr);
361
362 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000363 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700364 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000365 EXPECT_EQ(1u, received_blocks.size());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000366}
367
368TEST_F(RtcpReceiverTest, InjectRrPacketWithTwoReportBlocks) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000369 const uint16_t kSequenceNumbers[] = {10, 12423};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000370 const uint32_t kCumLost[] = {13, 555};
371 const uint8_t kFracLost[] = {20, 11};
danilchap1e714ae2016-09-05 09:57:22 -0700372 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000373
374 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700375 rb1.SetMediaSsrc(kReceiverMainSsrc);
376 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
377 rb1.SetFractionLost(10);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000378
379 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700380 rb2.SetMediaSsrc(kReceiverExtraSsrc);
381 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
382 rb2.SetFractionLost(0);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000383
384 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700385 rr1.SetSenderSsrc(kSenderSsrc);
386 rr1.AddReportBlock(rb1);
387 rr1.AddReportBlock(rb2);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000388
danilchap1e714ae2016-09-05 09:57:22 -0700389 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
390 EXPECT_CALL(bandwidth_observer_,
391 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
392 InjectRtcpPacket(rr1);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000393
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200394 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700395 std::vector<RTCPReportBlock> received_blocks;
396 rtcp_receiver_.StatisticsReceived(&received_blocks);
397 EXPECT_THAT(received_blocks,
srte3e69e5c2017-08-09 06:13:45 -0700398 UnorderedElementsAre(Field(&RTCPReportBlock::fraction_lost, 0),
399 Field(&RTCPReportBlock::fraction_lost, 10)));
danilchap1e714ae2016-09-05 09:57:22 -0700400
401 // Insert next receiver report with same ssrc but new values.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000402 rtcp::ReportBlock rb3;
danilchap822a16f2016-09-27 09:27:47 -0700403 rb3.SetMediaSsrc(kReceiverMainSsrc);
404 rb3.SetExtHighestSeqNum(kSequenceNumbers[0]);
405 rb3.SetFractionLost(kFracLost[0]);
406 rb3.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000407
408 rtcp::ReportBlock rb4;
danilchap822a16f2016-09-27 09:27:47 -0700409 rb4.SetMediaSsrc(kReceiverExtraSsrc);
410 rb4.SetExtHighestSeqNum(kSequenceNumbers[1]);
411 rb4.SetFractionLost(kFracLost[1]);
412 rb4.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000413
414 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700415 rr2.SetSenderSsrc(kSenderSsrc);
416 rr2.AddReportBlock(rb3);
417 rr2.AddReportBlock(rb4);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000418
danilchap1e714ae2016-09-05 09:57:22 -0700419 // Advance time to make 1st sent time and 2nd sent time different.
420 system_clock_.AdvanceTimeMilliseconds(500);
421 now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000422
danilchap1e714ae2016-09-05 09:57:22 -0700423 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
424 EXPECT_CALL(bandwidth_observer_,
425 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
426 InjectRtcpPacket(rr2);
427
428 received_blocks.clear();
429 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000430 EXPECT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700431 EXPECT_THAT(
432 received_blocks,
433 UnorderedElementsAre(
434 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
435 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
436 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
437 Field(&RTCPReportBlock::extended_highest_sequence_number,
438 kSequenceNumbers[0])),
439 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverExtraSsrc),
440 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
441 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
442 Field(&RTCPReportBlock::extended_highest_sequence_number,
443 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000444}
445
446TEST_F(RtcpReceiverTest, InjectRrPacketsFromTwoRemoteSsrcs) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000447 const uint32_t kSenderSsrc2 = 0x20304;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000448 const uint16_t kSequenceNumbers[] = {10, 12423};
449 const uint32_t kCumLost[] = {13, 555};
450 const uint8_t kFracLost[] = {20, 11};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000451
452 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700453 rb1.SetMediaSsrc(kReceiverMainSsrc);
454 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
455 rb1.SetFractionLost(kFracLost[0]);
456 rb1.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000457 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700458 rr1.SetSenderSsrc(kSenderSsrc);
459 rr1.AddReportBlock(rb1);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000460
danilchap1e714ae2016-09-05 09:57:22 -0700461 int64_t now = system_clock_.TimeInMilliseconds();
462
463 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
464 EXPECT_CALL(bandwidth_observer_,
465 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
466 InjectRtcpPacket(rr1);
467
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200468 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000469
470 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700471 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000472 EXPECT_EQ(1u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700473 EXPECT_EQ(kSenderSsrc, received_blocks[0].sender_ssrc);
474 EXPECT_EQ(kReceiverMainSsrc, received_blocks[0].source_ssrc);
475 EXPECT_EQ(kFracLost[0], received_blocks[0].fraction_lost);
476 EXPECT_EQ(kCumLost[0], received_blocks[0].packets_lost);
477 EXPECT_EQ(kSequenceNumbers[0],
478 received_blocks[0].extended_highest_sequence_number);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000479
480 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700481 rb2.SetMediaSsrc(kReceiverMainSsrc);
482 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
483 rb2.SetFractionLost(kFracLost[1]);
484 rb2.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000485 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700486 rr2.SetSenderSsrc(kSenderSsrc2);
487 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -0700488
489 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
490 EXPECT_CALL(bandwidth_observer_,
491 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
492 InjectRtcpPacket(rr2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000493
494 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700495 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000496 ASSERT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700497 EXPECT_THAT(
498 received_blocks,
499 UnorderedElementsAre(
500 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
501 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc),
502 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
503 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
504 Field(&RTCPReportBlock::extended_highest_sequence_number,
505 kSequenceNumbers[0])),
506 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
507 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc2),
508 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
509 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
510 Field(&RTCPReportBlock::extended_highest_sequence_number,
511 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000512}
513
514TEST_F(RtcpReceiverTest, GetRtt) {
danilchap28b03eb2016-10-05 06:59:44 -0700515 const uint32_t kSentCompactNtp = 0x1234;
516 const uint32_t kDelayCompactNtp = 0x222;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000517 // No report block received.
Erik Språng6b8d3552015-09-24 15:06:57 +0200518 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700519 -1, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000520
521 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700522 rb.SetMediaSsrc(kReceiverMainSsrc);
danilchap28b03eb2016-10-05 06:59:44 -0700523 rb.SetLastSr(kSentCompactNtp);
524 rb.SetDelayLastSr(kDelayCompactNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700525
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000526 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700527 rr.SetSenderSsrc(kSenderSsrc);
528 rr.AddReportBlock(rb);
danilchap1e714ae2016-09-05 09:57:22 -0700529 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000530
danilchap1e714ae2016-09-05 09:57:22 -0700531 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
532 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
533 InjectRtcpPacket(rr);
534
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200535 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700536 EXPECT_EQ(
537 0, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000538}
539
danilchap1e714ae2016-09-05 09:57:22 -0700540// Ij packets are ignored.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000541TEST_F(RtcpReceiverTest, InjectIjWithNoItem) {
danilchapf8506cb2015-11-13 07:33:20 -0800542 rtcp::ExtendedJitterReport ij;
danilchap1e714ae2016-09-05 09:57:22 -0700543 InjectRtcpPacket(ij);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000544}
545
danilchap1e714ae2016-09-05 09:57:22 -0700546// App packets are ignored.
547TEST_F(RtcpReceiverTest, InjectApp) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000548 rtcp::App app;
danilchap822a16f2016-09-27 09:27:47 -0700549 app.SetSubType(30);
550 app.SetName(0x17a177e);
danilchap1e714ae2016-09-05 09:57:22 -0700551 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
danilchap822a16f2016-09-27 09:27:47 -0700552 app.SetData(kData, sizeof(kData));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000553
danilchap1e714ae2016-09-05 09:57:22 -0700554 InjectRtcpPacket(app);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000555}
556
557TEST_F(RtcpReceiverTest, InjectSdesWithOneChunk) {
danilchap1e714ae2016-09-05 09:57:22 -0700558 const char kCname[] = "alice@host";
559 MockRtcpCallbackImpl callback;
560 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000561 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700562 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000563
danilchap1e714ae2016-09-05 09:57:22 -0700564 EXPECT_CALL(callback, CNameChanged(StrEq(kCname), kSenderSsrc));
565 InjectRtcpPacket(sdes);
566
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000567 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700568 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
569 EXPECT_EQ(0, strncmp(cName, kCname, RTCP_CNAME_SIZE));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000570}
571
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000572TEST_F(RtcpReceiverTest, InjectByePacket_RemovesCname) {
danilchap1e714ae2016-09-05 09:57:22 -0700573 const char kCname[] = "alice@host";
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000574 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700575 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000576
danilchap1e714ae2016-09-05 09:57:22 -0700577 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));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000581
582 // Verify that BYE removes the CNAME.
583 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700584 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700585
586 InjectRtcpPacket(bye);
587
588 EXPECT_EQ(-1, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000589}
590
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000591TEST_F(RtcpReceiverTest, InjectByePacket_RemovesReportBlocks) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000592 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700593 rb1.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000594 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700595 rb2.SetMediaSsrc(kReceiverExtraSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000596 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700597 rr.SetSenderSsrc(kSenderSsrc);
598 rr.AddReportBlock(rb1);
599 rr.AddReportBlock(rb2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000600
danilchap1e714ae2016-09-05 09:57:22 -0700601 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
602 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
603 InjectRtcpPacket(rr);
604
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000605 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700606 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000607 EXPECT_EQ(2u, received_blocks.size());
608
609 // Verify that BYE removes the report blocks.
610 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700611 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700612
613 InjectRtcpPacket(bye);
614
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000615 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700616 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000617 EXPECT_TRUE(received_blocks.empty());
618
danilchap1e714ae2016-09-05 09:57:22 -0700619 // Inject packet again.
620 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
621 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
622 InjectRtcpPacket(rr);
623
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000624 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700625 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000626 EXPECT_EQ(2u, received_blocks.size());
627}
628
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000629TEST_F(RtcpReceiverTest, InjectPliPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000630 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700631 pli.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700632
633 EXPECT_CALL(
634 packet_type_counter_observer_,
635 RtcpPacketTypesCounterUpdated(
636 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 1)));
637 EXPECT_CALL(intra_frame_observer_,
638 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
639 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000640}
641
642TEST_F(RtcpReceiverTest, PliPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000643 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700644 pli.SetMediaSsrc(kNotToUsSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700645
646 EXPECT_CALL(
647 packet_type_counter_observer_,
648 RtcpPacketTypesCounterUpdated(
649 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 0)));
650 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
651 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000652}
653
654TEST_F(RtcpReceiverTest, InjectFirPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000655 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700656 fir.AddRequestTo(kReceiverMainSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700657
658 EXPECT_CALL(
659 packet_type_counter_observer_,
660 RtcpPacketTypesCounterUpdated(
661 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::fir_packets, 1)));
662 EXPECT_CALL(intra_frame_observer_,
663 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
664 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000665}
666
667TEST_F(RtcpReceiverTest, FirPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000668 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700669 fir.AddRequestTo(kNotToUsSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700670
671 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
672 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000673}
674
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100675TEST_F(RtcpReceiverTest, ExtendedReportsPacketWithZeroReportBlocksIgnored) {
676 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700677 xr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700678
679 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000680}
681
danilchap1e714ae2016-09-05 09:57:22 -0700682// VOiP reports are ignored.
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100683TEST_F(RtcpReceiverTest, InjectExtendedReportsVoipPacket) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000684 const uint8_t kLossRate = 123;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000685 rtcp::VoipMetric voip_metric;
danilchap822a16f2016-09-27 09:27:47 -0700686 voip_metric.SetMediaSsrc(kReceiverMainSsrc);
danilchap91941ae2015-12-15 07:06:36 -0800687 RTCPVoIPMetric metric;
688 metric.lossRate = kLossRate;
danilchap822a16f2016-09-27 09:27:47 -0700689 voip_metric.SetVoipMetric(metric);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100690 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700691 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700692 xr.SetVoipMetric(voip_metric);
danilchap1e714ae2016-09-05 09:57:22 -0700693
694 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000695}
696
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100697TEST_F(RtcpReceiverTest, ExtendedReportsVoipPacketNotToUsIgnored) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000698 rtcp::VoipMetric voip_metric;
danilchap822a16f2016-09-27 09:27:47 -0700699 voip_metric.SetMediaSsrc(kNotToUsSsrc);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100700 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700701 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700702 xr.SetVoipMetric(voip_metric);
danilchap1e714ae2016-09-05 09:57:22 -0700703
704 InjectRtcpPacket(xr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +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
danilchap80ac24d2016-10-31 08:40:47 -0700715 ReceiveTimeInfo rrtime;
danilchap1e714ae2016-09-05 09:57:22 -0700716 EXPECT_FALSE(rtcp_receiver_.LastReceivedXrReferenceTimeInfo(&rrtime));
717
718 InjectRtcpPacket(xr);
719
720 EXPECT_TRUE(rtcp_receiver_.LastReceivedXrReferenceTimeInfo(&rrtime));
danilchap798896a2016-09-28 02:54:25 -0700721 EXPECT_EQ(rrtime.ssrc, kSenderSsrc);
722 EXPECT_EQ(rrtime.last_rr, CompactNtp(kNtp));
723 EXPECT_EQ(0U, rrtime.delay_since_last_rr);
danilchap1e714ae2016-09-05 09:57:22 -0700724
725 system_clock_.AdvanceTimeMilliseconds(1500);
726 EXPECT_TRUE(rtcp_receiver_.LastReceivedXrReferenceTimeInfo(&rrtime));
danilchap798896a2016-09-28 02:54:25 -0700727 EXPECT_NEAR(1500, CompactNtpRttToMs(rrtime.delay_since_last_rr), 1);
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
danilchap37953762017-02-09 11:15:25 -0800757 uint32_t compact_ntp_now = CompactNtp(system_clock_.CurrentNtpTime());
danilchap1e714ae2016-09-05 09:57:22 -0700758 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
759 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
760 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000761}
762
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100763TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithMultipleSubBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700764 const uint32_t kLastRR = 0x12345;
765 const uint32_t kDelay = 0x56789;
766 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000767
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100768 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700769 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700770 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
771 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 1, 0x12345, 0x67890));
772 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 2, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700773
774 InjectRtcpPacket(xr);
775
danilchap37953762017-02-09 11:15:25 -0800776 uint32_t compact_ntp_now = CompactNtp(system_clock_.CurrentNtpTime());
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;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000787 rtcp::VoipMetric metric;
danilchap822a16f2016-09-27 09:27:47 -0700788 metric.SetMediaSsrc(kReceiverMainSsrc);
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));
793 xr.SetVoipMetric(metric);
danilchap1e714ae2016-09-05 09:57:22 -0700794
795 InjectRtcpPacket(xr);
796
danilchap80ac24d2016-10-31 08:40:47 -0700797 ReceiveTimeInfo rrtime;
danilchap1e714ae2016-09-05 09:57:22 -0700798 EXPECT_TRUE(rtcp_receiver_.LastReceivedXrReferenceTimeInfo(&rrtime));
799 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;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000807 rtcp::VoipMetric metric;
danilchap822a16f2016-09-27 09:27:47 -0700808 metric.SetMediaSsrc(kReceiverMainSsrc);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100809 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700810 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700811 xr.SetRrtr(rrtr);
812 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
813 xr.SetVoipMetric(metric);
danilchap1e714ae2016-09-05 09:57:22 -0700814
danilchap69e59e62016-02-17 03:11:42 -0800815 rtc::Buffer packet = xr.Build();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000816 // Modify the DLRR block to have an unsupported block type, from 5 to 6.
danilchap1e714ae2016-09-05 09:57:22 -0700817 ASSERT_EQ(5, packet.data()[20]);
818 packet.data()[20] = 6;
819 InjectRtcpPacket(packet);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000820
danilchap1e714ae2016-09-05 09:57:22 -0700821 // Validate Rrtr was received and processed.
danilchap80ac24d2016-10-31 08:40:47 -0700822 ReceiveTimeInfo rrtime;
danilchap1e714ae2016-09-05 09:57:22 -0700823 EXPECT_TRUE(rtcp_receiver_.LastReceivedXrReferenceTimeInfo(&rrtime));
824 // Validate Dlrr report wasn't processed.
825 int64_t rtt_ms = 0;
826 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000827}
828
danilchap1e714ae2016-09-05 09:57:22 -0700829TEST_F(RtcpReceiverTest, TestExtendedReportsRrRttInitiallyFalse) {
830 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
831
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000832 int64_t rtt_ms;
danilchap1e714ae2016-09-05 09:57:22 -0700833 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000834}
835
danilchap1e714ae2016-09-05 09:57:22 -0700836TEST_F(RtcpReceiverTest, RttCalculatedAfterExtendedReportsDlrr) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100837 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100838 const int64_t kRttMs = rand.Rand(1, 9 * 3600 * 1000);
839 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
840 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700841 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
danilchap37953762017-02-09 11:15:25 -0800842 NtpTime now = system_clock_.CurrentNtpTime();
Danil Chapovalova094fd12016-02-22 18:59:36 +0100843 uint32_t sent_ntp = CompactNtp(now);
844 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
845
Danil Chapovalova094fd12016-02-22 18:59:36 +0100846 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700847 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700848 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700849
850 InjectRtcpPacket(xr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100851
852 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700853 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100854 EXPECT_NEAR(kRttMs, rtt_ms, 1);
855}
856
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100857TEST_F(RtcpReceiverTest, XrDlrrCalculatesNegativeRttAsOne) {
858 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100859 const int64_t kRttMs = rand.Rand(-3600 * 1000, -1);
860 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
861 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
danilchap37953762017-02-09 11:15:25 -0800862 NtpTime now = system_clock_.CurrentNtpTime();
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100863 uint32_t sent_ntp = CompactNtp(now);
864 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
danilchap1e714ae2016-09-05 09:57:22 -0700865 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100866
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100867 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700868 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700869 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700870
871 InjectRtcpPacket(xr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100872
873 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700874 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100875 EXPECT_EQ(1, rtt_ms);
876}
877
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000878TEST_F(RtcpReceiverTest, LastReceivedXrReferenceTimeInfoInitiallyFalse) {
danilchap80ac24d2016-10-31 08:40:47 -0700879 ReceiveTimeInfo info;
danilchap1e714ae2016-09-05 09:57:22 -0700880 EXPECT_FALSE(rtcp_receiver_.LastReceivedXrReferenceTimeInfo(&info));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000881}
882
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100883TEST_F(RtcpReceiverTest, GetLastReceivedExtendedReportsReferenceTimeInfo) {
Danil Chapovalovfc47ed62015-12-07 14:46:35 +0100884 const NtpTime kNtp(0x10203, 0x40506);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100885 const uint32_t kNtpMid = CompactNtp(kNtp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000886
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000887 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700888 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100889 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700890 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700891 xr.SetRrtr(rrtr);
danilchap1e714ae2016-09-05 09:57:22 -0700892
893 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000894
danilchap80ac24d2016-10-31 08:40:47 -0700895 ReceiveTimeInfo info;
danilchap1e714ae2016-09-05 09:57:22 -0700896 EXPECT_TRUE(rtcp_receiver_.LastReceivedXrReferenceTimeInfo(&info));
danilchap798896a2016-09-28 02:54:25 -0700897 EXPECT_EQ(kSenderSsrc, info.ssrc);
898 EXPECT_EQ(kNtpMid, info.last_rr);
899 EXPECT_EQ(0U, info.delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000900
901 system_clock_.AdvanceTimeMilliseconds(1000);
danilchap1e714ae2016-09-05 09:57:22 -0700902 EXPECT_TRUE(rtcp_receiver_.LastReceivedXrReferenceTimeInfo(&info));
danilchap798896a2016-09-28 02:54:25 -0700903 EXPECT_EQ(65536U, info.delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000904}
905
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000906TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000907 const int64_t kRtcpIntervalMs = 1000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000908 const uint16_t kSequenceNumber = 1234;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000909 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000910
911 // No RR received, shouldn't trigger a timeout.
danilchap1e714ae2016-09-05 09:57:22 -0700912 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
913 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000914
915 // Add a RR and advance the clock just enough to not trigger a timeout.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000916 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700917 rb1.SetMediaSsrc(kReceiverMainSsrc);
918 rb1.SetExtHighestSeqNum(kSequenceNumber);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000919 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700920 rr1.SetSenderSsrc(kSenderSsrc);
921 rr1.AddReportBlock(rb1);
danilchap1e714ae2016-09-05 09:57:22 -0700922
923 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
924 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
925 InjectRtcpPacket(rr1);
926
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000927 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs - 1);
danilchap1e714ae2016-09-05 09:57:22 -0700928 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
929 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000930
931 // Add a RR with the same extended max as the previous RR to trigger a
932 // sequence number timeout, but not a RR timeout.
danilchap1e714ae2016-09-05 09:57:22 -0700933 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
934 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
935 InjectRtcpPacket(rr1);
936
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000937 system_clock_.AdvanceTimeMilliseconds(2);
danilchap1e714ae2016-09-05 09:57:22 -0700938 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
939 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000940
941 // Advance clock enough to trigger an RR timeout too.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000942 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -0700943 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000944
945 // We should only get one timeout even though we still haven't received a new
946 // RR.
danilchap1e714ae2016-09-05 09:57:22 -0700947 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
948 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000949
950 // Add a new RR with increase sequence number to reset timers.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000951 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700952 rb2.SetMediaSsrc(kReceiverMainSsrc);
953 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000954 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700955 rr2.SetSenderSsrc(kSenderSsrc);
956 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -0700957
958 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
959 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
960 InjectRtcpPacket(rr2);
961
962 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
963 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000964
965 // Verify we can get a timeout again once we've received new RR.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000966 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -0700967 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
968 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
969 InjectRtcpPacket(rr2);
970
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000971 system_clock_.AdvanceTimeMilliseconds(kRtcpIntervalMs + 1);
danilchap1e714ae2016-09-05 09:57:22 -0700972 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
973 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
974
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000975 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -0700976 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000977}
978
hta@webrtc.org47059b52012-05-02 07:46:22 +0000979TEST_F(RtcpReceiverTest, TmmbrReceivedWithNoIncomingPacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700980 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +0000981}
982
983TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) {
danilchap1e714ae2016-09-05 09:57:22 -0700984 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000985 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -0700986 tmmbr.SetSenderSsrc(kSenderSsrc);
987 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000988 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700989 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -0700990 rtcp::CompoundPacket compound;
991 compound.Append(&sr);
992 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000993
danilchap1e714ae2016-09-05 09:57:22 -0700994 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
995 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(SizeIs(1)));
996 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
997 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
998 InjectRtcpPacket(compound);
999
1000 std::vector<rtcp::TmmbItem> tmmbr_received = rtcp_receiver_.TmmbrReceived();
1001 ASSERT_EQ(1u, tmmbr_received.size());
1002 EXPECT_EQ(kBitrateBps, tmmbr_received[0].bitrate_bps());
1003 EXPECT_EQ(kSenderSsrc, tmmbr_received[0].ssrc());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001004}
1005
1006TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -07001007 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001008 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001009 tmmbr.SetSenderSsrc(kSenderSsrc);
1010 tmmbr.AddTmmbr(rtcp::TmmbItem(kNotToUsSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001011
1012 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001013 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001014 rtcp::CompoundPacket compound;
1015 compound.Append(&sr);
1016 compound.Append(&tmmbr);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001017
danilchap1e714ae2016-09-05 09:57:22 -07001018 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1019 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1020 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1021 InjectRtcpPacket(compound);
1022
1023 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001024}
1025
1026TEST_F(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001027 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001028 tmmbr.SetSenderSsrc(kSenderSsrc);
1029 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 0, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001030 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001031 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001032 rtcp::CompoundPacket compound;
1033 compound.Append(&sr);
1034 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001035
danilchap1e714ae2016-09-05 09:57:22 -07001036 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1037 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1038 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1039 InjectRtcpPacket(compound);
1040
1041 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001042}
1043
hta@webrtc.org404843e2012-05-02 09:56:45 +00001044TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001045 // Inject 3 packets "from" kSenderSsrc, kSenderSsrc+1, kSenderSsrc+2.
hta@webrtc.org404843e2012-05-02 09:56:45 +00001046 // The times of arrival are starttime + 0, starttime + 5 and starttime + 10.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001047 for (uint32_t ssrc = kSenderSsrc; ssrc < kSenderSsrc + 3; ++ssrc) {
1048 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001049 tmmbr.SetSenderSsrc(ssrc);
1050 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 30000, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001051 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001052 sr.SetSenderSsrc(ssrc);
danilchap7a4116a2016-03-14 08:19:28 -07001053 rtcp::CompoundPacket compound;
1054 compound.Append(&sr);
1055 compound.Append(&tmmbr);
danilchap1e714ae2016-09-05 09:57:22 -07001056
1057 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1058 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(_));
1059 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1060 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_));
1061 InjectRtcpPacket(compound);
1062
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001063 // 5 seconds between each packet.
1064 system_clock_.AdvanceTimeMilliseconds(5000);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001065 }
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001066 // It is now starttime + 15.
danilchap1e714ae2016-09-05 09:57:22 -07001067 std::vector<rtcp::TmmbItem> candidate_set = rtcp_receiver_.TmmbrReceived();
1068 ASSERT_EQ(3u, candidate_set.size());
1069 EXPECT_EQ(30000U, candidate_set[0].bitrate_bps());
1070
hta@webrtc.org404843e2012-05-02 09:56:45 +00001071 // We expect the timeout to be 25 seconds. Advance the clock by 12
1072 // seconds, timing out the first packet.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001073 system_clock_.AdvanceTimeMilliseconds(12000);
danilchap1e714ae2016-09-05 09:57:22 -07001074 candidate_set = rtcp_receiver_.TmmbrReceived();
1075 ASSERT_EQ(2u, candidate_set.size());
danilchap287e5482016-08-16 15:15:39 -07001076 EXPECT_EQ(kSenderSsrc + 1, candidate_set[0].ssrc());
hta@webrtc.org404843e2012-05-02 09:56:45 +00001077}
1078
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001079TEST_F(RtcpReceiverTest, Callbacks) {
danilchap1e714ae2016-09-05 09:57:22 -07001080 MockRtcpCallbackImpl callback;
1081 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001082
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001083 const uint8_t kFractionLoss = 3;
1084 const uint32_t kCumulativeLoss = 7;
1085 const uint32_t kJitter = 9;
1086 const uint16_t kSequenceNumber = 1234;
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001087
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001088 // First packet, all numbers should just propagate.
1089 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -07001090 rb1.SetMediaSsrc(kReceiverMainSsrc);
1091 rb1.SetExtHighestSeqNum(kSequenceNumber);
1092 rb1.SetFractionLost(kFractionLoss);
1093 rb1.SetCumulativeLost(kCumulativeLoss);
1094 rb1.SetJitter(kJitter);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001095
1096 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -07001097 rr1.SetSenderSsrc(kSenderSsrc);
1098 rr1.AddReportBlock(rb1);
srte186d9c32017-08-04 05:03:53 -07001099 EXPECT_CALL(callback,
1100 StatisticsUpdated(
1101 AllOf(Field(&RtcpStatistics::fraction_lost, kFractionLoss),
1102 Field(&RtcpStatistics::packets_lost, kCumulativeLoss),
1103 Field(&RtcpStatistics::extended_highest_sequence_number,
1104 kSequenceNumber),
1105 Field(&RtcpStatistics::jitter, kJitter)),
1106 kReceiverMainSsrc));
danilchap1e714ae2016-09-05 09:57:22 -07001107 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1108 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1109 InjectRtcpPacket(rr1);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001110
danilchap1e714ae2016-09-05 09:57:22 -07001111 rtcp_receiver_.RegisterRtcpStatisticsCallback(nullptr);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001112
danilchap1e714ae2016-09-05 09:57:22 -07001113 // Add arbitrary numbers, callback should not be called.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001114 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001115 rb2.SetMediaSsrc(kReceiverMainSsrc);
1116 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
1117 rb2.SetFractionLost(42);
1118 rb2.SetCumulativeLost(137);
1119 rb2.SetJitter(4711);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001120
1121 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001122 rr2.SetSenderSsrc(kSenderSsrc);
1123 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001124
1125 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1126 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1127 EXPECT_CALL(callback, StatisticsUpdated(_, _)).Times(0);
1128 InjectRtcpPacket(rr2);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001129}
hta@webrtc.org404843e2012-05-02 09:56:45 +00001130
sprang49f9cdb2015-10-01 03:06:57 -07001131TEST_F(RtcpReceiverTest, ReceivesTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001132 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001133 packet.SetMediaSsrc(kReceiverMainSsrc);
1134 packet.SetSenderSsrc(kSenderSsrc);
1135 packet.SetBase(1, 1000);
1136 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001137
danilchap1e714ae2016-09-05 09:57:22 -07001138 EXPECT_CALL(
1139 transport_feedback_observer_,
1140 OnTransportFeedback(AllOf(
1141 Property(&rtcp::TransportFeedback::media_ssrc, kReceiverMainSsrc),
1142 Property(&rtcp::TransportFeedback::sender_ssrc, kSenderSsrc))));
1143 InjectRtcpPacket(packet);
sprang49f9cdb2015-10-01 03:06:57 -07001144}
1145
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001146TEST_F(RtcpReceiverTest, ReceivesRemb) {
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001147 const uint32_t kBitrateBps = 500000;
1148 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001149 remb.SetSenderSsrc(kSenderSsrc);
1150 remb.SetBitrateBps(kBitrateBps);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001151
danilchap1e714ae2016-09-05 09:57:22 -07001152 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1153 InjectRtcpPacket(remb);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001154}
1155
sprang49f9cdb2015-10-01 03:06:57 -07001156TEST_F(RtcpReceiverTest, HandlesInvalidTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001157 // Send a compound packet with a TransportFeedback followed by something else.
1158 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001159 packet.SetMediaSsrc(kReceiverMainSsrc);
1160 packet.SetSenderSsrc(kSenderSsrc);
1161 packet.SetBase(1, 1000);
1162 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001163
1164 static uint32_t kBitrateBps = 50000;
1165 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001166 remb.SetSenderSsrc(kSenderSsrc);
1167 remb.SetBitrateBps(kBitrateBps);
danilchap7a4116a2016-03-14 08:19:28 -07001168 rtcp::CompoundPacket compound;
1169 compound.Append(&packet);
1170 compound.Append(&remb);
1171 rtc::Buffer built_packet = compound.Build();
sprang49f9cdb2015-10-01 03:06:57 -07001172
1173 // Modify the TransportFeedback packet so that it is invalid.
1174 const size_t kStatusCountOffset = 14;
1175 ByteWriter<uint16_t>::WriteBigEndian(
danilchap69e59e62016-02-17 03:11:42 -08001176 &built_packet.data()[kStatusCountOffset], 42);
sprang49f9cdb2015-10-01 03:06:57 -07001177
danilchap1e714ae2016-09-05 09:57:22 -07001178 // Stress no transport feedback is expected.
1179 EXPECT_CALL(transport_feedback_observer_, OnTransportFeedback(_)).Times(0);
1180 // But remb should be processed and cause a callback
1181 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1182 InjectRtcpPacket(built_packet);
sprang49f9cdb2015-10-01 03:06:57 -07001183}
1184
danilchap1e714ae2016-09-05 09:57:22 -07001185TEST_F(RtcpReceiverTest, Nack) {
1186 const uint16_t kNackList1[] = {1, 2, 3, 5};
danilchap142f0192016-10-20 08:22:42 -07001187 const uint16_t kNackList23[] = {5, 7, 30, 40, 41, 58, 59, 61, 63};
1188 const size_t kNackListLength2 = 4;
1189 const size_t kNackListLength3 = arraysize(kNackList23) - kNackListLength2;
danilchap1e714ae2016-09-05 09:57:22 -07001190 std::set<uint16_t> nack_set;
1191 nack_set.insert(std::begin(kNackList1), std::end(kNackList1));
danilchap142f0192016-10-20 08:22:42 -07001192 nack_set.insert(std::begin(kNackList23), std::end(kNackList23));
danilchap1e714ae2016-09-05 09:57:22 -07001193
danilchap142f0192016-10-20 08:22:42 -07001194 rtcp::Nack nack1;
1195 nack1.SetSenderSsrc(kSenderSsrc);
1196 nack1.SetMediaSsrc(kReceiverMainSsrc);
1197 nack1.SetPacketIds(kNackList1, arraysize(kNackList1));
danilchap1e714ae2016-09-05 09:57:22 -07001198
1199 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList1)));
danilchap1e714ae2016-09-05 09:57:22 -07001200 EXPECT_CALL(packet_type_counter_observer_,
1201 RtcpPacketTypesCounterUpdated(
1202 kReceiverMainSsrc,
1203 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
danilchap142f0192016-10-20 08:22:42 -07001204 arraysize(kNackList1)),
1205 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1206 arraysize(kNackList1)))));
1207 InjectRtcpPacket(nack1);
1208
1209 rtcp::Nack nack2;
1210 nack2.SetSenderSsrc(kSenderSsrc);
1211 nack2.SetMediaSsrc(kReceiverMainSsrc);
1212 nack2.SetPacketIds(kNackList23, kNackListLength2);
1213
1214 rtcp::Nack nack3;
1215 nack3.SetSenderSsrc(kSenderSsrc);
1216 nack3.SetMediaSsrc(kReceiverMainSsrc);
1217 nack3.SetPacketIds(kNackList23 + kNackListLength2, kNackListLength3);
1218
1219 rtcp::CompoundPacket two_nacks;
1220 two_nacks.Append(&nack2);
1221 two_nacks.Append(&nack3);
1222
1223 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList23)));
1224 EXPECT_CALL(packet_type_counter_observer_,
1225 RtcpPacketTypesCounterUpdated(
1226 kReceiverMainSsrc,
1227 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
1228 arraysize(kNackList1) + arraysize(kNackList23)),
danilchap1e714ae2016-09-05 09:57:22 -07001229 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1230 nack_set.size()))));
danilchap142f0192016-10-20 08:22:42 -07001231 InjectRtcpPacket(two_nacks);
danilchap1e714ae2016-09-05 09:57:22 -07001232}
1233
1234TEST_F(RtcpReceiverTest, NackNotForUsIgnored) {
1235 const uint16_t kNackList1[] = {1, 2, 3, 5};
1236 const size_t kNackListLength1 = std::end(kNackList1) - std::begin(kNackList1);
1237
1238 rtcp::Nack nack;
danilchap822a16f2016-09-27 09:27:47 -07001239 nack.SetSenderSsrc(kSenderSsrc);
1240 nack.SetMediaSsrc(kNotToUsSsrc);
1241 nack.SetPacketIds(kNackList1, kNackListLength1);
danilchap1e714ae2016-09-05 09:57:22 -07001242
1243 EXPECT_CALL(packet_type_counter_observer_,
1244 RtcpPacketTypesCounterUpdated(
1245 _, Field(&RtcpPacketTypeCounter::nack_requests, 0)));
1246 InjectRtcpPacket(nack);
1247}
1248
1249TEST_F(RtcpReceiverTest, ForceSenderReport) {
1250 rtcp::RapidResyncRequest rr;
danilchap822a16f2016-09-27 09:27:47 -07001251 rr.SetSenderSsrc(kSenderSsrc);
1252 rr.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -07001253
1254 EXPECT_CALL(rtp_rtcp_impl_, OnRequestSendReport());
1255 InjectRtcpPacket(rr);
1256}
hta@webrtc.org47059b52012-05-02 07:46:22 +00001257
spranga790d832016-12-02 07:29:44 -08001258TEST_F(RtcpReceiverTest, ReceivesTargetBitrate) {
1259 BitrateAllocation expected_allocation;
1260 expected_allocation.SetBitrate(0, 0, 10000);
1261 expected_allocation.SetBitrate(0, 1, 20000);
1262 expected_allocation.SetBitrate(1, 0, 40000);
1263 expected_allocation.SetBitrate(1, 1, 80000);
1264
1265 rtcp::TargetBitrate bitrate;
1266 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1267 bitrate.AddTargetBitrate(0, 1, expected_allocation.GetBitrate(0, 1) / 1000);
1268 bitrate.AddTargetBitrate(1, 0, expected_allocation.GetBitrate(1, 0) / 1000);
1269 bitrate.AddTargetBitrate(1, 1, expected_allocation.GetBitrate(1, 1) / 1000);
1270
1271 rtcp::ExtendedReports xr;
1272 xr.SetTargetBitrate(bitrate);
1273
sprangb32aaf92017-08-28 05:49:12 -07001274 // Wrong sender ssrc, target bitrate should be discarded.
1275 xr.SetSenderSsrc(kSenderSsrc + 1);
1276 EXPECT_CALL(bitrate_allocation_observer_,
1277 OnBitrateAllocationUpdated(expected_allocation))
1278 .Times(0);
1279 InjectRtcpPacket(xr);
1280
1281 // Set correct ssrc, callback should be called once.
1282 xr.SetSenderSsrc(kSenderSsrc);
spranga790d832016-12-02 07:29:44 -08001283 EXPECT_CALL(bitrate_allocation_observer_,
1284 OnBitrateAllocationUpdated(expected_allocation));
1285 InjectRtcpPacket(xr);
1286}
1287
sprang6d314c72016-12-06 06:08:53 -08001288TEST_F(RtcpReceiverTest, HandlesIncorrectTargetBitrate) {
1289 BitrateAllocation expected_allocation;
1290 expected_allocation.SetBitrate(0, 0, 10000);
1291
1292 rtcp::TargetBitrate bitrate;
1293 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1294 bitrate.AddTargetBitrate(0, kMaxTemporalStreams, 20000);
1295 bitrate.AddTargetBitrate(kMaxSpatialLayers, 0, 40000);
1296
1297 rtcp::ExtendedReports xr;
1298 xr.SetTargetBitrate(bitrate);
sprangb32aaf92017-08-28 05:49:12 -07001299 xr.SetSenderSsrc(kSenderSsrc);
sprang6d314c72016-12-06 06:08:53 -08001300
1301 EXPECT_CALL(bitrate_allocation_observer_,
1302 OnBitrateAllocationUpdated(expected_allocation));
1303 InjectRtcpPacket(xr);
1304}
1305
hta@webrtc.org47059b52012-05-02 07:46:22 +00001306} // namespace webrtc