blob: 10351da4e021ae2f7542a11bc4e97764ea32f558 [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
69class MockRtcpCallbackImpl : public RtcpStatisticsCallback {
70 public:
71 MOCK_METHOD2(StatisticsUpdated, void(const RtcpStatistics&, uint32_t));
72 MOCK_METHOD2(CNameChanged, void(const char*, uint32_t));
73};
74
75class MockTransportFeedbackObserver : public TransportFeedbackObserver {
76 public:
elad.alond12a8e12017-03-23 11:04:48 -070077 MOCK_METHOD3(AddPacket, void(uint32_t, uint16_t, size_t));
78 MOCK_METHOD4(AddPacket,
79 void(uint32_t, uint16_t, size_t, const PacedPacketInfo&));
danilchap1e714ae2016-09-05 09:57:22 -070080 MOCK_METHOD1(OnTransportFeedback, void(const rtcp::TransportFeedback&));
elad.alonf9490002017-03-06 05:32:21 -080081 MOCK_CONST_METHOD0(GetTransportFeedbackVector, std::vector<PacketFeedback>());
danilchap1e714ae2016-09-05 09:57:22 -070082};
83
danilchap1e714ae2016-09-05 09:57:22 -070084class MockModuleRtpRtcp : public RTCPReceiver::ModuleRtpRtcp {
85 public:
86 MOCK_METHOD1(SetTmmbn, void(std::vector<rtcp::TmmbItem>));
87 MOCK_METHOD0(OnRequestSendReport, void());
88 MOCK_METHOD1(OnReceivedNack, void(const std::vector<uint16_t>&));
89 MOCK_METHOD1(OnReceivedRtcpReportBlocks, void(const ReportBlockList&));
90};
91
spranga790d832016-12-02 07:29:44 -080092class MockVideoBitrateAllocationObserver
93 : public VideoBitrateAllocationObserver {
94 public:
95 MOCK_METHOD1(OnBitrateAllocationUpdated,
Erik Språng566124a2018-04-23 12:32:22 +020096 void(const VideoBitrateAllocation& allocation));
spranga790d832016-12-02 07:29:44 -080097};
98
danilchap1e714ae2016-09-05 09:57:22 -070099// SSRC of remote peer, that sends rtcp packet to the rtcp receiver under test.
100constexpr uint32_t kSenderSsrc = 0x10203;
101// SSRCs of local peer, that rtcp packet addressed to.
102constexpr uint32_t kReceiverMainSsrc = 0x123456;
103// RtcpReceiver can accept several ssrc, e.g. regular and rtx streams.
104constexpr uint32_t kReceiverExtraSsrc = 0x1234567;
105// SSRCs to ignore (i.e. not configured in RtcpReceiver).
106constexpr uint32_t kNotToUsSsrc = 0x654321;
107constexpr uint32_t kUnknownSenderSsrc = 0x54321;
108
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800109constexpr int64_t kRtcpIntervalMs = 1000;
110
danilchap1e714ae2016-09-05 09:57:22 -0700111} // namespace
112
hta@webrtc.org47059b52012-05-02 07:46:22 +0000113class RtcpReceiverTest : public ::testing::Test {
114 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000115 RtcpReceiverTest()
danilchap1e714ae2016-09-05 09:57:22 -0700116 : system_clock_(1335900000),
117 rtcp_receiver_(&system_clock_,
118 false,
119 &packet_type_counter_observer_,
120 &bandwidth_observer_,
121 &intra_frame_observer_,
122 &transport_feedback_observer_,
spranga790d832016-12-02 07:29:44 -0800123 &bitrate_allocation_observer_,
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800124 kRtcpIntervalMs,
danilchap1e714ae2016-09-05 09:57:22 -0700125 &rtp_rtcp_impl_) {}
126 void SetUp() {
127 std::set<uint32_t> ssrcs = {kReceiverMainSsrc, kReceiverExtraSsrc};
danilchap1e714ae2016-09-05 09:57:22 -0700128 rtcp_receiver_.SetSsrcs(kReceiverMainSsrc, ssrcs);
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000129
danilchap1e714ae2016-09-05 09:57:22 -0700130 rtcp_receiver_.SetRemoteSSRC(kSenderSsrc);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000131 }
Erik Språng737336d2016-07-29 12:59:36 +0200132
danilchap1e714ae2016-09-05 09:57:22 -0700133 void InjectRtcpPacket(rtc::ArrayView<const uint8_t> raw) {
134 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
hta@webrtc.org47059b52012-05-02 07:46:22 +0000135 }
136
danilchap1e714ae2016-09-05 09:57:22 -0700137 void InjectRtcpPacket(const rtcp::RtcpPacket& packet) {
138 rtc::Buffer raw = packet.Build();
139 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
140 }
141
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000142 SimulatedClock system_clock_;
danilchap1e714ae2016-09-05 09:57:22 -0700143 // Callbacks to packet_type_counter_observer are frequent but most of the time
144 // are not interesting.
145 NiceMock<MockRtcpPacketTypeCounterObserver> packet_type_counter_observer_;
146 StrictMock<MockRtcpBandwidthObserver> bandwidth_observer_;
147 StrictMock<MockRtcpIntraFrameObserver> intra_frame_observer_;
148 StrictMock<MockTransportFeedbackObserver> transport_feedback_observer_;
spranga790d832016-12-02 07:29:44 -0800149 StrictMock<MockVideoBitrateAllocationObserver> bitrate_allocation_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700150 StrictMock<MockModuleRtpRtcp> rtp_rtcp_impl_;
hta@webrtc.org47059b52012-05-02 07:46:22 +0000151
danilchap1e714ae2016-09-05 09:57:22 -0700152 RTCPReceiver rtcp_receiver_;
153};
hta@webrtc.org47059b52012-05-02 07:46:22 +0000154
155TEST_F(RtcpReceiverTest, BrokenPacketIsIgnored) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000156 const uint8_t bad_packet[] = {0, 0, 0, 0};
danilchap1e714ae2016-09-05 09:57:22 -0700157 EXPECT_CALL(packet_type_counter_observer_,
158 RtcpPacketTypesCounterUpdated(_, _))
159 .Times(0);
160 InjectRtcpPacket(bad_packet);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000161}
162
danilchap50da1d32016-03-10 13:13:52 -0800163TEST_F(RtcpReceiverTest, InvalidFeedbackPacketIsIgnored) {
164 // Too short feedback packet.
danilchap1e714ae2016-09-05 09:57:22 -0700165 const uint8_t bad_packet[] = {0x81, rtcp::Rtpfb::kPacketType, 0, 0};
166
167 // TODO(danilchap): Add expectation RtcpPacketTypesCounterUpdated
168 // is not called once parser would be adjusted to avoid that callback on
169 // semi-valid packets.
170 InjectRtcpPacket(bad_packet);
danilchap50da1d32016-03-10 13:13:52 -0800171}
172
hta@webrtc.org47059b52012-05-02 07:46:22 +0000173TEST_F(RtcpReceiverTest, InjectSrPacket) {
danilchapa04d9c32017-07-25 04:03:39 -0700174 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
danilchap1e714ae2016-09-05 09:57:22 -0700175
176 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000177 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700178 sr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700179
180 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
181 EXPECT_CALL(bandwidth_observer_,
182 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
183 InjectRtcpPacket(sr);
184
danilchapa04d9c32017-07-25 04:03:39 -0700185 EXPECT_TRUE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
hta@webrtc.org47059b52012-05-02 07:46:22 +0000186}
187
danilchap1e714ae2016-09-05 09:57:22 -0700188TEST_F(RtcpReceiverTest, InjectSrPacketFromUnknownSender) {
189 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000190 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700191 sr.SetSenderSsrc(kUnknownSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700192
193 // The parser will handle report blocks in Sender Report from other than his
194 // expected peer.
195 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
196 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, now));
197 InjectRtcpPacket(sr);
198
199 // But will not flag that he's gotten sender information.
danilchapa04d9c32017-07-25 04:03:39 -0700200 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000201}
202
Danil Chapovalova094fd12016-02-22 18:59:36 +0100203TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesRTT) {
204 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100205 const int64_t kRttMs = r.Rand(1, 9 * 3600 * 1000);
206 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
207 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100208
Danil Chapovalova094fd12016-02-22 18:59:36 +0100209 int64_t rtt_ms = 0;
210 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700211 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100212
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200213 uint32_t sent_ntp =
214 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100215 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
216
217 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700218 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100219 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700220 block.SetMediaSsrc(kReceiverMainSsrc);
221 block.SetLastSr(sent_ntp);
222 block.SetDelayLastSr(kDelayNtp);
223 sr.AddReportBlock(block);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100224
danilchap1e714ae2016-09-05 09:57:22 -0700225 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
226 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
227 InjectRtcpPacket(sr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100228
229 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700230 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100231 EXPECT_NEAR(kRttMs, rtt_ms, 1);
232}
233
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100234TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesNegativeRTTAsOne) {
235 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100236 const int64_t kRttMs = r.Rand(-3600 * 1000, -1);
237 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
238 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
239
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100240 int64_t rtt_ms = 0;
241 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700242 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100243
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200244 uint32_t sent_ntp =
245 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100246 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
247
248 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700249 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100250 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700251 block.SetMediaSsrc(kReceiverMainSsrc);
252 block.SetLastSr(sent_ntp);
253 block.SetDelayLastSr(kDelayNtp);
254 sr.AddReportBlock(block);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100255
danilchap1e714ae2016-09-05 09:57:22 -0700256 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
257 EXPECT_CALL(bandwidth_observer_,
258 OnReceivedRtcpReceiverReport(SizeIs(1), _, _));
259 InjectRtcpPacket(sr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100260
261 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700262 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100263 EXPECT_EQ(1, rtt_ms);
264}
265
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100266TEST_F(
267 RtcpReceiverTest,
268 TwoReportBlocksWithLastOneWithoutLastSrCalculatesRttForBandwidthObserver) {
269 const int64_t kRttMs = 120;
270 const uint32_t kDelayNtp = 123000;
271 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
272
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200273 uint32_t sent_ntp =
274 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100275 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};
Sebastian Jansson9701e0c2018-08-09 11:21:11 +0200449 const int32_t kCumLost[] = {13, 555};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000450 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
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200629TEST_F(RtcpReceiverTest, InjectByePacketRemovesReferenceTimeInfo) {
630 rtcp::ExtendedReports xr;
631 xr.SetSenderSsrc(kSenderSsrc);
632 rtcp::Rrtr rrtr;
633 rrtr.SetNtp(NtpTime(0x10203, 0x40506));
634 xr.SetRrtr(rrtr);
635 InjectRtcpPacket(xr);
636
637 rtcp::Bye bye;
638 bye.SetSenderSsrc(kSenderSsrc);
639 InjectRtcpPacket(bye);
640
641 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
642}
643
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000644TEST_F(RtcpReceiverTest, InjectPliPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000645 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700646 pli.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700647
648 EXPECT_CALL(
649 packet_type_counter_observer_,
650 RtcpPacketTypesCounterUpdated(
651 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 1)));
652 EXPECT_CALL(intra_frame_observer_,
653 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
654 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000655}
656
657TEST_F(RtcpReceiverTest, PliPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000658 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700659 pli.SetMediaSsrc(kNotToUsSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700660
661 EXPECT_CALL(
662 packet_type_counter_observer_,
663 RtcpPacketTypesCounterUpdated(
664 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 0)));
665 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
666 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000667}
668
669TEST_F(RtcpReceiverTest, InjectFirPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000670 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700671 fir.AddRequestTo(kReceiverMainSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700672
673 EXPECT_CALL(
674 packet_type_counter_observer_,
675 RtcpPacketTypesCounterUpdated(
676 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::fir_packets, 1)));
677 EXPECT_CALL(intra_frame_observer_,
678 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
679 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000680}
681
682TEST_F(RtcpReceiverTest, FirPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000683 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700684 fir.AddRequestTo(kNotToUsSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700685
686 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
687 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000688}
689
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100690TEST_F(RtcpReceiverTest, ExtendedReportsPacketWithZeroReportBlocksIgnored) {
691 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700692 xr.SetSenderSsrc(kSenderSsrc);
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, InjectExtendedReportsReceiverReferenceTimePacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700698 const NtpTime kNtp(0x10203, 0x40506);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000699 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700700 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100701 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700702 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700703 xr.SetRrtr(rrtr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000704
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200705 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
706 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
707 EXPECT_THAT(last_xr_rtis, IsEmpty());
danilchap1e714ae2016-09-05 09:57:22 -0700708
709 InjectRtcpPacket(xr);
710
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200711 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
712 ASSERT_THAT(last_xr_rtis, SizeIs(1));
713 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
714 EXPECT_EQ(CompactNtp(kNtp), last_xr_rtis[0].last_rr);
715 EXPECT_EQ(0U, last_xr_rtis[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000716}
717
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100718TEST_F(RtcpReceiverTest, ExtendedReportsDlrrPacketNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700719 // Allow calculate rtt using dlrr/rrtr, simulating media receiver side.
720 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000721
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100722 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700723 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700724 xr.AddDlrrItem(ReceiveTimeInfo(kNotToUsSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700725
726 InjectRtcpPacket(xr);
727
728 int64_t rtt_ms = 0;
729 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000730}
731
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100732TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithSubBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700733 const uint32_t kLastRR = 0x12345;
734 const uint32_t kDelay = 0x23456;
735 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
736 int64_t rtt_ms = 0;
737 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000738
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100739 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700740 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700741 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
danilchap1e714ae2016-09-05 09:57:22 -0700742
743 InjectRtcpPacket(xr);
744
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200745 uint32_t compact_ntp_now =
746 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700747 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
748 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
749 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000750}
751
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100752TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithMultipleSubBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700753 const uint32_t kLastRR = 0x12345;
754 const uint32_t kDelay = 0x56789;
755 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000756
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100757 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700758 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700759 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
760 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 1, 0x12345, 0x67890));
761 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 2, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700762
763 InjectRtcpPacket(xr);
764
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200765 uint32_t compact_ntp_now =
766 CompactNtp(TimeMicrosToNtp(system_clock_.TimeInMicroseconds()));
danilchap1e714ae2016-09-05 09:57:22 -0700767 int64_t rtt_ms = 0;
768 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
769 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
770 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000771}
772
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100773TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithMultipleReportBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700774 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000775
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000776 rtcp::Rrtr rrtr;
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100777 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700778 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700779 xr.SetRrtr(rrtr);
780 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700781
782 InjectRtcpPacket(xr);
783
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200784 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
785 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
786 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700787 int64_t rtt_ms = 0;
788 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000789}
790
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100791TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithUnknownReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700792 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000793
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000794 rtcp::Rrtr rrtr;
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100795 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700796 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700797 xr.SetRrtr(rrtr);
798 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700799
danilchap69e59e62016-02-17 03:11:42 -0800800 rtc::Buffer packet = xr.Build();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000801 // Modify the DLRR block to have an unsupported block type, from 5 to 6.
danilchap1e714ae2016-09-05 09:57:22 -0700802 ASSERT_EQ(5, packet.data()[20]);
803 packet.data()[20] = 6;
804 InjectRtcpPacket(packet);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000805
danilchap1e714ae2016-09-05 09:57:22 -0700806 // Validate Rrtr was received and processed.
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200807 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
808 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
809 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700810 // Validate Dlrr report wasn't processed.
811 int64_t rtt_ms = 0;
812 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000813}
814
danilchap1e714ae2016-09-05 09:57:22 -0700815TEST_F(RtcpReceiverTest, TestExtendedReportsRrRttInitiallyFalse) {
816 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
817
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000818 int64_t rtt_ms;
danilchap1e714ae2016-09-05 09:57:22 -0700819 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000820}
821
danilchap1e714ae2016-09-05 09:57:22 -0700822TEST_F(RtcpReceiverTest, RttCalculatedAfterExtendedReportsDlrr) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100823 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100824 const int64_t kRttMs = rand.Rand(1, 9 * 3600 * 1000);
825 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
826 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700827 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200828 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalova094fd12016-02-22 18:59:36 +0100829 uint32_t sent_ntp = CompactNtp(now);
830 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
831
Danil Chapovalova094fd12016-02-22 18:59:36 +0100832 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700833 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700834 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700835
836 InjectRtcpPacket(xr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100837
838 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700839 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100840 EXPECT_NEAR(kRttMs, rtt_ms, 1);
841}
842
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100843TEST_F(RtcpReceiverTest, XrDlrrCalculatesNegativeRttAsOne) {
844 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100845 const int64_t kRttMs = rand.Rand(-3600 * 1000, -1);
846 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
847 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Ilya Nikolaevskiy88c2c502018-10-26 16:00:08 +0200848 NtpTime now = TimeMicrosToNtp(system_clock_.TimeInMicroseconds());
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100849 uint32_t sent_ntp = CompactNtp(now);
850 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
danilchap1e714ae2016-09-05 09:57:22 -0700851 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100852
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100853 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700854 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700855 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700856
857 InjectRtcpPacket(xr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100858
859 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700860 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100861 EXPECT_EQ(1, rtt_ms);
862}
863
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200864TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfoInitiallyEmpty) {
865 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000866}
867
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200868TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfo) {
Danil Chapovalovfc47ed62015-12-07 14:46:35 +0100869 const NtpTime kNtp(0x10203, 0x40506);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100870 const uint32_t kNtpMid = CompactNtp(kNtp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000871
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000872 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700873 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100874 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700875 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700876 xr.SetRrtr(rrtr);
danilchap1e714ae2016-09-05 09:57:22 -0700877
878 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000879
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000880 system_clock_.AdvanceTimeMilliseconds(1000);
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200881
882 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
883 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
884 ASSERT_THAT(last_xr_rtis, SizeIs(1));
885 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
886 EXPECT_EQ(kNtpMid, last_xr_rtis[0].last_rr);
887 EXPECT_EQ(65536U, last_xr_rtis[0].delay_since_last_rr);
888}
889
890TEST_F(RtcpReceiverTest,
891 ReceivedRrtrFromSameSsrcUpdatesReceivedReferenceTimeInfo) {
892 const NtpTime kNtp1(0x10203, 0x40506);
893 const NtpTime kNtp2(0x11223, 0x44556);
894 const int64_t kDelayMs = 2000;
895
896 rtcp::ExtendedReports xr;
897 xr.SetSenderSsrc(kSenderSsrc);
898 rtcp::Rrtr rrtr1;
899 rrtr1.SetNtp(kNtp1);
900 xr.SetRrtr(rrtr1);
901 InjectRtcpPacket(xr);
902 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
903 rtcp::Rrtr rrtr2;
904 rrtr2.SetNtp(kNtp2);
905 xr.SetRrtr(rrtr2);
906 InjectRtcpPacket(xr);
907 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
908
909 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
910 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
911 ASSERT_THAT(last_xr_rtis, SizeIs(1));
912 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
913 EXPECT_EQ(CompactNtp(kNtp2), last_xr_rtis[0].last_rr);
914 EXPECT_EQ(kDelayMs * 65536 / 1000, last_xr_rtis[0].delay_since_last_rr);
915}
916
917TEST_F(RtcpReceiverTest, StoresLastReceivedRrtrPerSsrc) {
918 const size_t kNumBufferedReports = 1;
919 const size_t kNumReports =
920 rtcp::ExtendedReports::kMaxNumberOfDlrrItems + kNumBufferedReports;
921 for (size_t i = 0; i < kNumReports; ++i) {
922 rtcp::ExtendedReports xr;
923 xr.SetSenderSsrc(i * 100);
924 rtcp::Rrtr rrtr;
925 rrtr.SetNtp(NtpTime(i * 200, i * 300));
926 xr.SetRrtr(rrtr);
927 InjectRtcpPacket(xr);
928 system_clock_.AdvanceTimeMilliseconds(1000);
929 }
930
931 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
932 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
933 ASSERT_THAT(last_xr_rtis,
934 SizeIs(rtcp::ExtendedReports::kMaxNumberOfDlrrItems));
935 for (size_t i = 0; i < rtcp::ExtendedReports::kMaxNumberOfDlrrItems; ++i) {
936 EXPECT_EQ(i * 100, last_xr_rtis[i].ssrc);
937 EXPECT_EQ(CompactNtp(NtpTime(i * 200, i * 300)), last_xr_rtis[i].last_rr);
938 EXPECT_EQ(65536U * (kNumReports - i), last_xr_rtis[i].delay_since_last_rr);
939 }
940
941 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
942 ASSERT_THAT(last_xr_rtis, SizeIs(kNumBufferedReports));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000943}
944
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000945TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000946 const uint16_t kSequenceNumber = 1234;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000947 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000948
949 // No RR received, shouldn't trigger a timeout.
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800950 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
951 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000952
953 // Add a RR and advance the clock just enough to not trigger a timeout.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000954 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700955 rb1.SetMediaSsrc(kReceiverMainSsrc);
956 rb1.SetExtHighestSeqNum(kSequenceNumber);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000957 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700958 rr1.SetSenderSsrc(kSenderSsrc);
959 rr1.AddReportBlock(rb1);
danilchap1e714ae2016-09-05 09:57:22 -0700960
961 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
962 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
963 InjectRtcpPacket(rr1);
964
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000965 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs - 1);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800966 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
967 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000968
969 // Add a RR with the same extended max as the previous RR to trigger a
970 // sequence number timeout, but not a RR timeout.
danilchap1e714ae2016-09-05 09:57:22 -0700971 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(2);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800976 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
977 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000978
979 // Advance clock enough to trigger an RR timeout too.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000980 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800981 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000982
983 // We should only get one timeout even though we still haven't received a new
984 // RR.
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800985 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
986 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000987
988 // Add a new RR with increase sequence number to reset timers.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000989 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700990 rb2.SetMediaSsrc(kReceiverMainSsrc);
991 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000992 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700993 rr2.SetSenderSsrc(kSenderSsrc);
994 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -0700995
996 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
997 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
998 InjectRtcpPacket(rr2);
999
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001000 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1001 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001002
1003 // Verify we can get a timeout again once we've received new RR.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001004 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -07001005 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1006 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1007 InjectRtcpPacket(rr2);
1008
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001009 system_clock_.AdvanceTimeMilliseconds(kRtcpIntervalMs + 1);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001010 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout());
1011 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout());
danilchap1e714ae2016-09-05 09:57:22 -07001012
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001013 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
Jiawei Ou8b5d9d82018-11-15 16:44:37 -08001014 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout());
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001015}
1016
hta@webrtc.org47059b52012-05-02 07:46:22 +00001017TEST_F(RtcpReceiverTest, TmmbrReceivedWithNoIncomingPacket) {
danilchap1e714ae2016-09-05 09:57:22 -07001018 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001019}
1020
1021TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) {
danilchap1e714ae2016-09-05 09:57:22 -07001022 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001023 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001024 tmmbr.SetSenderSsrc(kSenderSsrc);
1025 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001026 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001027 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001028 rtcp::CompoundPacket compound;
1029 compound.Append(&sr);
1030 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001031
danilchap1e714ae2016-09-05 09:57:22 -07001032 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1033 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(SizeIs(1)));
1034 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1035 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1036 InjectRtcpPacket(compound);
1037
1038 std::vector<rtcp::TmmbItem> tmmbr_received = rtcp_receiver_.TmmbrReceived();
1039 ASSERT_EQ(1u, tmmbr_received.size());
1040 EXPECT_EQ(kBitrateBps, tmmbr_received[0].bitrate_bps());
1041 EXPECT_EQ(kSenderSsrc, tmmbr_received[0].ssrc());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001042}
1043
1044TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -07001045 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001046 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001047 tmmbr.SetSenderSsrc(kSenderSsrc);
1048 tmmbr.AddTmmbr(rtcp::TmmbItem(kNotToUsSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001049
1050 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001051 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001052 rtcp::CompoundPacket compound;
1053 compound.Append(&sr);
1054 compound.Append(&tmmbr);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001055
danilchap1e714ae2016-09-05 09:57:22 -07001056 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1057 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1058 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1059 InjectRtcpPacket(compound);
1060
1061 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001062}
1063
1064TEST_F(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001065 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001066 tmmbr.SetSenderSsrc(kSenderSsrc);
1067 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 0, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001068 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001069 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001070 rtcp::CompoundPacket compound;
1071 compound.Append(&sr);
1072 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001073
danilchap1e714ae2016-09-05 09:57:22 -07001074 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1075 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1076 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1077 InjectRtcpPacket(compound);
1078
1079 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001080}
1081
hta@webrtc.org404843e2012-05-02 09:56:45 +00001082TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001083 // Inject 3 packets "from" kSenderSsrc, kSenderSsrc+1, kSenderSsrc+2.
hta@webrtc.org404843e2012-05-02 09:56:45 +00001084 // The times of arrival are starttime + 0, starttime + 5 and starttime + 10.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001085 for (uint32_t ssrc = kSenderSsrc; ssrc < kSenderSsrc + 3; ++ssrc) {
1086 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001087 tmmbr.SetSenderSsrc(ssrc);
1088 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 30000, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001089 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001090 sr.SetSenderSsrc(ssrc);
danilchap7a4116a2016-03-14 08:19:28 -07001091 rtcp::CompoundPacket compound;
1092 compound.Append(&sr);
1093 compound.Append(&tmmbr);
danilchap1e714ae2016-09-05 09:57:22 -07001094
1095 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1096 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(_));
1097 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1098 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_));
1099 InjectRtcpPacket(compound);
1100
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001101 // 5 seconds between each packet.
1102 system_clock_.AdvanceTimeMilliseconds(5000);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001103 }
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001104 // It is now starttime + 15.
danilchap1e714ae2016-09-05 09:57:22 -07001105 std::vector<rtcp::TmmbItem> candidate_set = rtcp_receiver_.TmmbrReceived();
1106 ASSERT_EQ(3u, candidate_set.size());
1107 EXPECT_EQ(30000U, candidate_set[0].bitrate_bps());
1108
hta@webrtc.org404843e2012-05-02 09:56:45 +00001109 // We expect the timeout to be 25 seconds. Advance the clock by 12
1110 // seconds, timing out the first packet.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001111 system_clock_.AdvanceTimeMilliseconds(12000);
danilchap1e714ae2016-09-05 09:57:22 -07001112 candidate_set = rtcp_receiver_.TmmbrReceived();
1113 ASSERT_EQ(2u, candidate_set.size());
danilchap287e5482016-08-16 15:15:39 -07001114 EXPECT_EQ(kSenderSsrc + 1, candidate_set[0].ssrc());
hta@webrtc.org404843e2012-05-02 09:56:45 +00001115}
1116
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001117TEST_F(RtcpReceiverTest, Callbacks) {
danilchap1e714ae2016-09-05 09:57:22 -07001118 MockRtcpCallbackImpl callback;
1119 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001120
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001121 const uint8_t kFractionLoss = 3;
1122 const uint32_t kCumulativeLoss = 7;
1123 const uint32_t kJitter = 9;
1124 const uint16_t kSequenceNumber = 1234;
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001125
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001126 // First packet, all numbers should just propagate.
1127 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -07001128 rb1.SetMediaSsrc(kReceiverMainSsrc);
1129 rb1.SetExtHighestSeqNum(kSequenceNumber);
1130 rb1.SetFractionLost(kFractionLoss);
1131 rb1.SetCumulativeLost(kCumulativeLoss);
1132 rb1.SetJitter(kJitter);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001133
1134 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -07001135 rr1.SetSenderSsrc(kSenderSsrc);
1136 rr1.AddReportBlock(rb1);
srte186d9c32017-08-04 05:03:53 -07001137 EXPECT_CALL(callback,
1138 StatisticsUpdated(
1139 AllOf(Field(&RtcpStatistics::fraction_lost, kFractionLoss),
1140 Field(&RtcpStatistics::packets_lost, kCumulativeLoss),
1141 Field(&RtcpStatistics::extended_highest_sequence_number,
1142 kSequenceNumber),
1143 Field(&RtcpStatistics::jitter, kJitter)),
1144 kReceiverMainSsrc));
danilchap1e714ae2016-09-05 09:57:22 -07001145 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1146 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1147 InjectRtcpPacket(rr1);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001148
danilchap1e714ae2016-09-05 09:57:22 -07001149 rtcp_receiver_.RegisterRtcpStatisticsCallback(nullptr);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001150
danilchap1e714ae2016-09-05 09:57:22 -07001151 // Add arbitrary numbers, callback should not be called.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001152 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001153 rb2.SetMediaSsrc(kReceiverMainSsrc);
1154 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
1155 rb2.SetFractionLost(42);
1156 rb2.SetCumulativeLost(137);
1157 rb2.SetJitter(4711);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001158
1159 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001160 rr2.SetSenderSsrc(kSenderSsrc);
1161 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001162
1163 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1164 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1165 EXPECT_CALL(callback, StatisticsUpdated(_, _)).Times(0);
1166 InjectRtcpPacket(rr2);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001167}
hta@webrtc.org404843e2012-05-02 09:56:45 +00001168
sprang49f9cdb2015-10-01 03:06:57 -07001169TEST_F(RtcpReceiverTest, ReceivesTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001170 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001171 packet.SetMediaSsrc(kReceiverMainSsrc);
1172 packet.SetSenderSsrc(kSenderSsrc);
1173 packet.SetBase(1, 1000);
1174 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001175
danilchap1e714ae2016-09-05 09:57:22 -07001176 EXPECT_CALL(
1177 transport_feedback_observer_,
1178 OnTransportFeedback(AllOf(
1179 Property(&rtcp::TransportFeedback::media_ssrc, kReceiverMainSsrc),
1180 Property(&rtcp::TransportFeedback::sender_ssrc, kSenderSsrc))));
1181 InjectRtcpPacket(packet);
sprang49f9cdb2015-10-01 03:06:57 -07001182}
1183
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001184TEST_F(RtcpReceiverTest, ReceivesRemb) {
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001185 const uint32_t kBitrateBps = 500000;
1186 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001187 remb.SetSenderSsrc(kSenderSsrc);
1188 remb.SetBitrateBps(kBitrateBps);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001189
danilchap1e714ae2016-09-05 09:57:22 -07001190 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1191 InjectRtcpPacket(remb);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001192}
1193
sprang49f9cdb2015-10-01 03:06:57 -07001194TEST_F(RtcpReceiverTest, HandlesInvalidTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001195 // Send a compound packet with a TransportFeedback followed by something else.
1196 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001197 packet.SetMediaSsrc(kReceiverMainSsrc);
1198 packet.SetSenderSsrc(kSenderSsrc);
1199 packet.SetBase(1, 1000);
1200 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001201
1202 static uint32_t kBitrateBps = 50000;
1203 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001204 remb.SetSenderSsrc(kSenderSsrc);
1205 remb.SetBitrateBps(kBitrateBps);
danilchap7a4116a2016-03-14 08:19:28 -07001206 rtcp::CompoundPacket compound;
1207 compound.Append(&packet);
1208 compound.Append(&remb);
1209 rtc::Buffer built_packet = compound.Build();
sprang49f9cdb2015-10-01 03:06:57 -07001210
1211 // Modify the TransportFeedback packet so that it is invalid.
1212 const size_t kStatusCountOffset = 14;
Yves Gerey665174f2018-06-19 15:03:05 +02001213 ByteWriter<uint16_t>::WriteBigEndian(&built_packet.data()[kStatusCountOffset],
1214 42);
sprang49f9cdb2015-10-01 03:06:57 -07001215
danilchap1e714ae2016-09-05 09:57:22 -07001216 // Stress no transport feedback is expected.
1217 EXPECT_CALL(transport_feedback_observer_, OnTransportFeedback(_)).Times(0);
1218 // But remb should be processed and cause a callback
1219 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1220 InjectRtcpPacket(built_packet);
sprang49f9cdb2015-10-01 03:06:57 -07001221}
1222
danilchap1e714ae2016-09-05 09:57:22 -07001223TEST_F(RtcpReceiverTest, Nack) {
1224 const uint16_t kNackList1[] = {1, 2, 3, 5};
danilchap142f0192016-10-20 08:22:42 -07001225 const uint16_t kNackList23[] = {5, 7, 30, 40, 41, 58, 59, 61, 63};
1226 const size_t kNackListLength2 = 4;
1227 const size_t kNackListLength3 = arraysize(kNackList23) - kNackListLength2;
danilchap1e714ae2016-09-05 09:57:22 -07001228 std::set<uint16_t> nack_set;
1229 nack_set.insert(std::begin(kNackList1), std::end(kNackList1));
danilchap142f0192016-10-20 08:22:42 -07001230 nack_set.insert(std::begin(kNackList23), std::end(kNackList23));
danilchap1e714ae2016-09-05 09:57:22 -07001231
danilchap142f0192016-10-20 08:22:42 -07001232 rtcp::Nack nack1;
1233 nack1.SetSenderSsrc(kSenderSsrc);
1234 nack1.SetMediaSsrc(kReceiverMainSsrc);
1235 nack1.SetPacketIds(kNackList1, arraysize(kNackList1));
danilchap1e714ae2016-09-05 09:57:22 -07001236
1237 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList1)));
danilchap1e714ae2016-09-05 09:57:22 -07001238 EXPECT_CALL(packet_type_counter_observer_,
1239 RtcpPacketTypesCounterUpdated(
1240 kReceiverMainSsrc,
1241 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
danilchap142f0192016-10-20 08:22:42 -07001242 arraysize(kNackList1)),
1243 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1244 arraysize(kNackList1)))));
1245 InjectRtcpPacket(nack1);
1246
1247 rtcp::Nack nack2;
1248 nack2.SetSenderSsrc(kSenderSsrc);
1249 nack2.SetMediaSsrc(kReceiverMainSsrc);
1250 nack2.SetPacketIds(kNackList23, kNackListLength2);
1251
1252 rtcp::Nack nack3;
1253 nack3.SetSenderSsrc(kSenderSsrc);
1254 nack3.SetMediaSsrc(kReceiverMainSsrc);
1255 nack3.SetPacketIds(kNackList23 + kNackListLength2, kNackListLength3);
1256
1257 rtcp::CompoundPacket two_nacks;
1258 two_nacks.Append(&nack2);
1259 two_nacks.Append(&nack3);
1260
1261 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList23)));
1262 EXPECT_CALL(packet_type_counter_observer_,
1263 RtcpPacketTypesCounterUpdated(
1264 kReceiverMainSsrc,
1265 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
1266 arraysize(kNackList1) + arraysize(kNackList23)),
danilchap1e714ae2016-09-05 09:57:22 -07001267 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1268 nack_set.size()))));
danilchap142f0192016-10-20 08:22:42 -07001269 InjectRtcpPacket(two_nacks);
danilchap1e714ae2016-09-05 09:57:22 -07001270}
1271
1272TEST_F(RtcpReceiverTest, NackNotForUsIgnored) {
1273 const uint16_t kNackList1[] = {1, 2, 3, 5};
1274 const size_t kNackListLength1 = std::end(kNackList1) - std::begin(kNackList1);
1275
1276 rtcp::Nack nack;
danilchap822a16f2016-09-27 09:27:47 -07001277 nack.SetSenderSsrc(kSenderSsrc);
1278 nack.SetMediaSsrc(kNotToUsSsrc);
1279 nack.SetPacketIds(kNackList1, kNackListLength1);
danilchap1e714ae2016-09-05 09:57:22 -07001280
1281 EXPECT_CALL(packet_type_counter_observer_,
1282 RtcpPacketTypesCounterUpdated(
1283 _, Field(&RtcpPacketTypeCounter::nack_requests, 0)));
1284 InjectRtcpPacket(nack);
1285}
1286
1287TEST_F(RtcpReceiverTest, ForceSenderReport) {
1288 rtcp::RapidResyncRequest rr;
danilchap822a16f2016-09-27 09:27:47 -07001289 rr.SetSenderSsrc(kSenderSsrc);
1290 rr.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -07001291
1292 EXPECT_CALL(rtp_rtcp_impl_, OnRequestSendReport());
1293 InjectRtcpPacket(rr);
1294}
hta@webrtc.org47059b52012-05-02 07:46:22 +00001295
spranga790d832016-12-02 07:29:44 -08001296TEST_F(RtcpReceiverTest, ReceivesTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001297 VideoBitrateAllocation expected_allocation;
spranga790d832016-12-02 07:29:44 -08001298 expected_allocation.SetBitrate(0, 0, 10000);
1299 expected_allocation.SetBitrate(0, 1, 20000);
1300 expected_allocation.SetBitrate(1, 0, 40000);
1301 expected_allocation.SetBitrate(1, 1, 80000);
1302
1303 rtcp::TargetBitrate bitrate;
1304 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1305 bitrate.AddTargetBitrate(0, 1, expected_allocation.GetBitrate(0, 1) / 1000);
1306 bitrate.AddTargetBitrate(1, 0, expected_allocation.GetBitrate(1, 0) / 1000);
1307 bitrate.AddTargetBitrate(1, 1, expected_allocation.GetBitrate(1, 1) / 1000);
1308
1309 rtcp::ExtendedReports xr;
1310 xr.SetTargetBitrate(bitrate);
1311
sprangb32aaf92017-08-28 05:49:12 -07001312 // Wrong sender ssrc, target bitrate should be discarded.
1313 xr.SetSenderSsrc(kSenderSsrc + 1);
1314 EXPECT_CALL(bitrate_allocation_observer_,
1315 OnBitrateAllocationUpdated(expected_allocation))
1316 .Times(0);
1317 InjectRtcpPacket(xr);
1318
1319 // Set correct ssrc, callback should be called once.
1320 xr.SetSenderSsrc(kSenderSsrc);
spranga790d832016-12-02 07:29:44 -08001321 EXPECT_CALL(bitrate_allocation_observer_,
1322 OnBitrateAllocationUpdated(expected_allocation));
1323 InjectRtcpPacket(xr);
1324}
1325
sprang6d314c72016-12-06 06:08:53 -08001326TEST_F(RtcpReceiverTest, HandlesIncorrectTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001327 VideoBitrateAllocation expected_allocation;
sprang6d314c72016-12-06 06:08:53 -08001328 expected_allocation.SetBitrate(0, 0, 10000);
1329
1330 rtcp::TargetBitrate bitrate;
1331 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1332 bitrate.AddTargetBitrate(0, kMaxTemporalStreams, 20000);
1333 bitrate.AddTargetBitrate(kMaxSpatialLayers, 0, 40000);
1334
1335 rtcp::ExtendedReports xr;
1336 xr.SetTargetBitrate(bitrate);
sprangb32aaf92017-08-28 05:49:12 -07001337 xr.SetSenderSsrc(kSenderSsrc);
sprang6d314c72016-12-06 06:08:53 -08001338
1339 EXPECT_CALL(bitrate_allocation_observer_,
1340 OnBitrateAllocationUpdated(expected_allocation));
1341 InjectRtcpPacket(xr);
1342}
1343
hta@webrtc.org47059b52012-05-02 07:46:22 +00001344} // namespace webrtc