blob: a7cbba1d3905d18386083e3bce2f80c623bd2cc5 [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"
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
109} // namespace
110
hta@webrtc.org47059b52012-05-02 07:46:22 +0000111class RtcpReceiverTest : public ::testing::Test {
112 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000113 RtcpReceiverTest()
danilchap1e714ae2016-09-05 09:57:22 -0700114 : system_clock_(1335900000),
115 rtcp_receiver_(&system_clock_,
116 false,
117 &packet_type_counter_observer_,
118 &bandwidth_observer_,
119 &intra_frame_observer_,
120 &transport_feedback_observer_,
spranga790d832016-12-02 07:29:44 -0800121 &bitrate_allocation_observer_,
danilchap1e714ae2016-09-05 09:57:22 -0700122 &rtp_rtcp_impl_) {}
123 void SetUp() {
124 std::set<uint32_t> ssrcs = {kReceiverMainSsrc, kReceiverExtraSsrc};
danilchap1e714ae2016-09-05 09:57:22 -0700125 rtcp_receiver_.SetSsrcs(kReceiverMainSsrc, ssrcs);
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000126
danilchap1e714ae2016-09-05 09:57:22 -0700127 rtcp_receiver_.SetRemoteSSRC(kSenderSsrc);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000128 }
Erik Språng737336d2016-07-29 12:59:36 +0200129
danilchap1e714ae2016-09-05 09:57:22 -0700130 void InjectRtcpPacket(rtc::ArrayView<const uint8_t> raw) {
131 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
hta@webrtc.org47059b52012-05-02 07:46:22 +0000132 }
133
danilchap1e714ae2016-09-05 09:57:22 -0700134 void InjectRtcpPacket(const rtcp::RtcpPacket& packet) {
135 rtc::Buffer raw = packet.Build();
136 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
137 }
138
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000139 SimulatedClock system_clock_;
danilchap1e714ae2016-09-05 09:57:22 -0700140 // Callbacks to packet_type_counter_observer are frequent but most of the time
141 // are not interesting.
142 NiceMock<MockRtcpPacketTypeCounterObserver> packet_type_counter_observer_;
143 StrictMock<MockRtcpBandwidthObserver> bandwidth_observer_;
144 StrictMock<MockRtcpIntraFrameObserver> intra_frame_observer_;
145 StrictMock<MockTransportFeedbackObserver> transport_feedback_observer_;
spranga790d832016-12-02 07:29:44 -0800146 StrictMock<MockVideoBitrateAllocationObserver> bitrate_allocation_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700147 StrictMock<MockModuleRtpRtcp> rtp_rtcp_impl_;
hta@webrtc.org47059b52012-05-02 07:46:22 +0000148
danilchap1e714ae2016-09-05 09:57:22 -0700149 RTCPReceiver rtcp_receiver_;
150};
hta@webrtc.org47059b52012-05-02 07:46:22 +0000151
152TEST_F(RtcpReceiverTest, BrokenPacketIsIgnored) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000153 const uint8_t bad_packet[] = {0, 0, 0, 0};
danilchap1e714ae2016-09-05 09:57:22 -0700154 EXPECT_CALL(packet_type_counter_observer_,
155 RtcpPacketTypesCounterUpdated(_, _))
156 .Times(0);
157 InjectRtcpPacket(bad_packet);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000158}
159
danilchap50da1d32016-03-10 13:13:52 -0800160TEST_F(RtcpReceiverTest, InvalidFeedbackPacketIsIgnored) {
161 // Too short feedback packet.
danilchap1e714ae2016-09-05 09:57:22 -0700162 const uint8_t bad_packet[] = {0x81, rtcp::Rtpfb::kPacketType, 0, 0};
163
164 // TODO(danilchap): Add expectation RtcpPacketTypesCounterUpdated
165 // is not called once parser would be adjusted to avoid that callback on
166 // semi-valid packets.
167 InjectRtcpPacket(bad_packet);
danilchap50da1d32016-03-10 13:13:52 -0800168}
169
hta@webrtc.org47059b52012-05-02 07:46:22 +0000170TEST_F(RtcpReceiverTest, InjectSrPacket) {
danilchapa04d9c32017-07-25 04:03:39 -0700171 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
danilchap1e714ae2016-09-05 09:57:22 -0700172
173 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000174 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700175 sr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700176
177 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
178 EXPECT_CALL(bandwidth_observer_,
179 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
180 InjectRtcpPacket(sr);
181
danilchapa04d9c32017-07-25 04:03:39 -0700182 EXPECT_TRUE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
hta@webrtc.org47059b52012-05-02 07:46:22 +0000183}
184
danilchap1e714ae2016-09-05 09:57:22 -0700185TEST_F(RtcpReceiverTest, InjectSrPacketFromUnknownSender) {
186 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000187 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700188 sr.SetSenderSsrc(kUnknownSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700189
190 // The parser will handle report blocks in Sender Report from other than his
191 // expected peer.
192 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
193 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, now));
194 InjectRtcpPacket(sr);
195
196 // But will not flag that he's gotten sender information.
danilchapa04d9c32017-07-25 04:03:39 -0700197 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000198}
199
Danil Chapovalova094fd12016-02-22 18:59:36 +0100200TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesRTT) {
201 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100202 const int64_t kRttMs = r.Rand(1, 9 * 3600 * 1000);
203 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
204 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100205
Danil Chapovalova094fd12016-02-22 18:59:36 +0100206 int64_t rtt_ms = 0;
207 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700208 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100209
danilchap37953762017-02-09 11:15:25 -0800210 uint32_t sent_ntp = CompactNtp(system_clock_.CurrentNtpTime());
Danil Chapovalova094fd12016-02-22 18:59:36 +0100211 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
212
213 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700214 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100215 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700216 block.SetMediaSsrc(kReceiverMainSsrc);
217 block.SetLastSr(sent_ntp);
218 block.SetDelayLastSr(kDelayNtp);
219 sr.AddReportBlock(block);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100220
danilchap1e714ae2016-09-05 09:57:22 -0700221 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
222 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
223 InjectRtcpPacket(sr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100224
225 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700226 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100227 EXPECT_NEAR(kRttMs, rtt_ms, 1);
228}
229
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100230TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesNegativeRTTAsOne) {
231 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100232 const int64_t kRttMs = r.Rand(-3600 * 1000, -1);
233 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
234 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
235
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100236 int64_t rtt_ms = 0;
237 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700238 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100239
danilchap37953762017-02-09 11:15:25 -0800240 uint32_t sent_ntp = CompactNtp(system_clock_.CurrentNtpTime());
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100241 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
242
243 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700244 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100245 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700246 block.SetMediaSsrc(kReceiverMainSsrc);
247 block.SetLastSr(sent_ntp);
248 block.SetDelayLastSr(kDelayNtp);
249 sr.AddReportBlock(block);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100250
danilchap1e714ae2016-09-05 09:57:22 -0700251 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
252 EXPECT_CALL(bandwidth_observer_,
253 OnReceivedRtcpReceiverReport(SizeIs(1), _, _));
254 InjectRtcpPacket(sr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100255
256 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700257 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100258 EXPECT_EQ(1, rtt_ms);
259}
260
Danil Chapovalov04164cc2018-01-26 20:01:48 +0100261TEST_F(
262 RtcpReceiverTest,
263 TwoReportBlocksWithLastOneWithoutLastSrCalculatesRttForBandwidthObserver) {
264 const int64_t kRttMs = 120;
265 const uint32_t kDelayNtp = 123000;
266 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
267
268 uint32_t sent_ntp = CompactNtp(system_clock_.CurrentNtpTime());
269 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
270
271 rtcp::SenderReport sr;
272 sr.SetSenderSsrc(kSenderSsrc);
273 rtcp::ReportBlock block;
274 block.SetMediaSsrc(kReceiverMainSsrc);
275 block.SetLastSr(sent_ntp);
276 block.SetDelayLastSr(kDelayNtp);
277 sr.AddReportBlock(block);
278 block.SetMediaSsrc(kReceiverExtraSsrc);
279 block.SetLastSr(0);
280 sr.AddReportBlock(block);
281
282 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
283 EXPECT_CALL(bandwidth_observer_,
284 OnReceivedRtcpReceiverReport(SizeIs(2), kRttMs, _));
285 InjectRtcpPacket(sr);
286}
287
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000288TEST_F(RtcpReceiverTest, InjectRrPacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700289 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000290 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700291 rr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700292
293 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
294 EXPECT_CALL(bandwidth_observer_,
295 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
296 InjectRtcpPacket(rr);
297
danilchap1e714ae2016-09-05 09:57:22 -0700298 std::vector<RTCPReportBlock> report_blocks;
299 rtcp_receiver_.StatisticsReceived(&report_blocks);
300 EXPECT_TRUE(report_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000301}
302
303TEST_F(RtcpReceiverTest, InjectRrPacketWithReportBlockNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700304 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000305 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700306 rb.SetMediaSsrc(kNotToUsSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000307 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700308 rr.SetSenderSsrc(kSenderSsrc);
309 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000310
danilchap1e714ae2016-09-05 09:57:22 -0700311 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
312 EXPECT_CALL(bandwidth_observer_,
313 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
314 InjectRtcpPacket(rr);
315
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200316 EXPECT_EQ(0, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000317 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700318 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000319 EXPECT_TRUE(received_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000320}
321
322TEST_F(RtcpReceiverTest, InjectRrPacketWithOneReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700323 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000324
325 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700326 rb.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000327 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700328 rr.SetSenderSsrc(kSenderSsrc);
329 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000330
danilchap1e714ae2016-09-05 09:57:22 -0700331 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
332 EXPECT_CALL(bandwidth_observer_,
333 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
334 InjectRtcpPacket(rr);
335
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200336 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
337 std::vector<RTCPReportBlock> received_blocks;
338 rtcp_receiver_.StatisticsReceived(&received_blocks);
339 EXPECT_EQ(1u, received_blocks.size());
340}
341
342TEST_F(RtcpReceiverTest, InjectSrPacketWithOneReportBlock) {
343 int64_t now = system_clock_.TimeInMilliseconds();
344
345 rtcp::ReportBlock rb;
346 rb.SetMediaSsrc(kReceiverMainSsrc);
347 rtcp::SenderReport sr;
348 sr.SetSenderSsrc(kSenderSsrc);
349 sr.AddReportBlock(rb);
350
351 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
352 EXPECT_CALL(bandwidth_observer_,
353 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
354 InjectRtcpPacket(sr);
355
356 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000357 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700358 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000359 EXPECT_EQ(1u, received_blocks.size());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000360}
361
362TEST_F(RtcpReceiverTest, InjectRrPacketWithTwoReportBlocks) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000363 const uint16_t kSequenceNumbers[] = {10, 12423};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000364 const uint32_t kCumLost[] = {13, 555};
365 const uint8_t kFracLost[] = {20, 11};
danilchap1e714ae2016-09-05 09:57:22 -0700366 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000367
368 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700369 rb1.SetMediaSsrc(kReceiverMainSsrc);
370 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
371 rb1.SetFractionLost(10);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000372
373 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700374 rb2.SetMediaSsrc(kReceiverExtraSsrc);
375 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
376 rb2.SetFractionLost(0);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000377
378 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700379 rr1.SetSenderSsrc(kSenderSsrc);
380 rr1.AddReportBlock(rb1);
381 rr1.AddReportBlock(rb2);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000382
danilchap1e714ae2016-09-05 09:57:22 -0700383 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
384 EXPECT_CALL(bandwidth_observer_,
385 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
386 InjectRtcpPacket(rr1);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000387
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200388 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700389 std::vector<RTCPReportBlock> received_blocks;
390 rtcp_receiver_.StatisticsReceived(&received_blocks);
391 EXPECT_THAT(received_blocks,
srte3e69e5c2017-08-09 06:13:45 -0700392 UnorderedElementsAre(Field(&RTCPReportBlock::fraction_lost, 0),
393 Field(&RTCPReportBlock::fraction_lost, 10)));
danilchap1e714ae2016-09-05 09:57:22 -0700394
395 // Insert next receiver report with same ssrc but new values.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000396 rtcp::ReportBlock rb3;
danilchap822a16f2016-09-27 09:27:47 -0700397 rb3.SetMediaSsrc(kReceiverMainSsrc);
398 rb3.SetExtHighestSeqNum(kSequenceNumbers[0]);
399 rb3.SetFractionLost(kFracLost[0]);
400 rb3.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000401
402 rtcp::ReportBlock rb4;
danilchap822a16f2016-09-27 09:27:47 -0700403 rb4.SetMediaSsrc(kReceiverExtraSsrc);
404 rb4.SetExtHighestSeqNum(kSequenceNumbers[1]);
405 rb4.SetFractionLost(kFracLost[1]);
406 rb4.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000407
408 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700409 rr2.SetSenderSsrc(kSenderSsrc);
410 rr2.AddReportBlock(rb3);
411 rr2.AddReportBlock(rb4);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000412
danilchap1e714ae2016-09-05 09:57:22 -0700413 // Advance time to make 1st sent time and 2nd sent time different.
414 system_clock_.AdvanceTimeMilliseconds(500);
415 now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000416
danilchap1e714ae2016-09-05 09:57:22 -0700417 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
418 EXPECT_CALL(bandwidth_observer_,
419 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
420 InjectRtcpPacket(rr2);
421
422 received_blocks.clear();
423 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000424 EXPECT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700425 EXPECT_THAT(
426 received_blocks,
427 UnorderedElementsAre(
428 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
429 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
430 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
431 Field(&RTCPReportBlock::extended_highest_sequence_number,
432 kSequenceNumbers[0])),
433 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverExtraSsrc),
434 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
435 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
436 Field(&RTCPReportBlock::extended_highest_sequence_number,
437 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000438}
439
440TEST_F(RtcpReceiverTest, InjectRrPacketsFromTwoRemoteSsrcs) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000441 const uint32_t kSenderSsrc2 = 0x20304;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000442 const uint16_t kSequenceNumbers[] = {10, 12423};
443 const uint32_t kCumLost[] = {13, 555};
444 const uint8_t kFracLost[] = {20, 11};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000445
446 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700447 rb1.SetMediaSsrc(kReceiverMainSsrc);
448 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
449 rb1.SetFractionLost(kFracLost[0]);
450 rb1.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000451 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700452 rr1.SetSenderSsrc(kSenderSsrc);
453 rr1.AddReportBlock(rb1);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000454
danilchap1e714ae2016-09-05 09:57:22 -0700455 int64_t now = system_clock_.TimeInMilliseconds();
456
457 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
458 EXPECT_CALL(bandwidth_observer_,
459 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
460 InjectRtcpPacket(rr1);
461
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200462 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000463
464 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700465 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000466 EXPECT_EQ(1u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700467 EXPECT_EQ(kSenderSsrc, received_blocks[0].sender_ssrc);
468 EXPECT_EQ(kReceiverMainSsrc, received_blocks[0].source_ssrc);
469 EXPECT_EQ(kFracLost[0], received_blocks[0].fraction_lost);
470 EXPECT_EQ(kCumLost[0], received_blocks[0].packets_lost);
471 EXPECT_EQ(kSequenceNumbers[0],
472 received_blocks[0].extended_highest_sequence_number);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000473
474 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700475 rb2.SetMediaSsrc(kReceiverMainSsrc);
476 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
477 rb2.SetFractionLost(kFracLost[1]);
478 rb2.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000479 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700480 rr2.SetSenderSsrc(kSenderSsrc2);
481 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -0700482
483 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
484 EXPECT_CALL(bandwidth_observer_,
485 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
486 InjectRtcpPacket(rr2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000487
488 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700489 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000490 ASSERT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700491 EXPECT_THAT(
492 received_blocks,
493 UnorderedElementsAre(
494 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
495 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc),
496 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
497 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
498 Field(&RTCPReportBlock::extended_highest_sequence_number,
499 kSequenceNumbers[0])),
500 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
501 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc2),
502 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
503 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
504 Field(&RTCPReportBlock::extended_highest_sequence_number,
505 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000506}
507
508TEST_F(RtcpReceiverTest, GetRtt) {
danilchap28b03eb2016-10-05 06:59:44 -0700509 const uint32_t kSentCompactNtp = 0x1234;
510 const uint32_t kDelayCompactNtp = 0x222;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000511 // No report block received.
Erik Språng6b8d3552015-09-24 15:06:57 +0200512 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700513 -1, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000514
515 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700516 rb.SetMediaSsrc(kReceiverMainSsrc);
danilchap28b03eb2016-10-05 06:59:44 -0700517 rb.SetLastSr(kSentCompactNtp);
518 rb.SetDelayLastSr(kDelayCompactNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700519
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000520 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700521 rr.SetSenderSsrc(kSenderSsrc);
522 rr.AddReportBlock(rb);
danilchap1e714ae2016-09-05 09:57:22 -0700523 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000524
danilchap1e714ae2016-09-05 09:57:22 -0700525 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
526 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
527 InjectRtcpPacket(rr);
528
Danil Chapovalov760c4b42017-09-27 13:25:24 +0200529 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReportBlockMs());
danilchap1e714ae2016-09-05 09:57:22 -0700530 EXPECT_EQ(
531 0, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000532}
533
danilchap1e714ae2016-09-05 09:57:22 -0700534// Ij packets are ignored.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000535TEST_F(RtcpReceiverTest, InjectIjWithNoItem) {
danilchapf8506cb2015-11-13 07:33:20 -0800536 rtcp::ExtendedJitterReport ij;
danilchap1e714ae2016-09-05 09:57:22 -0700537 InjectRtcpPacket(ij);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000538}
539
danilchap1e714ae2016-09-05 09:57:22 -0700540// App packets are ignored.
541TEST_F(RtcpReceiverTest, InjectApp) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000542 rtcp::App app;
danilchap822a16f2016-09-27 09:27:47 -0700543 app.SetSubType(30);
544 app.SetName(0x17a177e);
danilchap1e714ae2016-09-05 09:57:22 -0700545 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
danilchap822a16f2016-09-27 09:27:47 -0700546 app.SetData(kData, sizeof(kData));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000547
danilchap1e714ae2016-09-05 09:57:22 -0700548 InjectRtcpPacket(app);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000549}
550
551TEST_F(RtcpReceiverTest, InjectSdesWithOneChunk) {
danilchap1e714ae2016-09-05 09:57:22 -0700552 const char kCname[] = "alice@host";
553 MockRtcpCallbackImpl callback;
554 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000555 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700556 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000557
danilchap1e714ae2016-09-05 09:57:22 -0700558 EXPECT_CALL(callback, CNameChanged(StrEq(kCname), kSenderSsrc));
559 InjectRtcpPacket(sdes);
560
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000561 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700562 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
563 EXPECT_EQ(0, strncmp(cName, kCname, RTCP_CNAME_SIZE));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000564}
565
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000566TEST_F(RtcpReceiverTest, InjectByePacket_RemovesCname) {
danilchap1e714ae2016-09-05 09:57:22 -0700567 const char kCname[] = "alice@host";
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000568 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700569 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000570
danilchap1e714ae2016-09-05 09:57:22 -0700571 InjectRtcpPacket(sdes);
572
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000573 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700574 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000575
576 // Verify that BYE removes the CNAME.
577 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700578 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700579
580 InjectRtcpPacket(bye);
581
582 EXPECT_EQ(-1, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000583}
584
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000585TEST_F(RtcpReceiverTest, InjectByePacket_RemovesReportBlocks) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000586 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700587 rb1.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000588 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700589 rb2.SetMediaSsrc(kReceiverExtraSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000590 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700591 rr.SetSenderSsrc(kSenderSsrc);
592 rr.AddReportBlock(rb1);
593 rr.AddReportBlock(rb2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000594
danilchap1e714ae2016-09-05 09:57:22 -0700595 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
596 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
597 InjectRtcpPacket(rr);
598
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000599 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700600 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000601 EXPECT_EQ(2u, received_blocks.size());
602
603 // Verify that BYE removes the report blocks.
604 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700605 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700606
607 InjectRtcpPacket(bye);
608
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000609 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700610 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000611 EXPECT_TRUE(received_blocks.empty());
612
danilchap1e714ae2016-09-05 09:57:22 -0700613 // Inject packet again.
614 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
615 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
616 InjectRtcpPacket(rr);
617
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000618 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700619 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000620 EXPECT_EQ(2u, received_blocks.size());
621}
622
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200623TEST_F(RtcpReceiverTest, InjectByePacketRemovesReferenceTimeInfo) {
624 rtcp::ExtendedReports xr;
625 xr.SetSenderSsrc(kSenderSsrc);
626 rtcp::Rrtr rrtr;
627 rrtr.SetNtp(NtpTime(0x10203, 0x40506));
628 xr.SetRrtr(rrtr);
629 InjectRtcpPacket(xr);
630
631 rtcp::Bye bye;
632 bye.SetSenderSsrc(kSenderSsrc);
633 InjectRtcpPacket(bye);
634
635 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
636}
637
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000638TEST_F(RtcpReceiverTest, InjectPliPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000639 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700640 pli.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700641
642 EXPECT_CALL(
643 packet_type_counter_observer_,
644 RtcpPacketTypesCounterUpdated(
645 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 1)));
646 EXPECT_CALL(intra_frame_observer_,
647 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
648 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000649}
650
651TEST_F(RtcpReceiverTest, PliPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000652 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700653 pli.SetMediaSsrc(kNotToUsSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700654
655 EXPECT_CALL(
656 packet_type_counter_observer_,
657 RtcpPacketTypesCounterUpdated(
658 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 0)));
659 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
660 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000661}
662
663TEST_F(RtcpReceiverTest, InjectFirPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000664 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700665 fir.AddRequestTo(kReceiverMainSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700666
667 EXPECT_CALL(
668 packet_type_counter_observer_,
669 RtcpPacketTypesCounterUpdated(
670 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::fir_packets, 1)));
671 EXPECT_CALL(intra_frame_observer_,
672 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
673 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000674}
675
676TEST_F(RtcpReceiverTest, FirPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000677 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700678 fir.AddRequestTo(kNotToUsSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700679
680 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
681 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000682}
683
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100684TEST_F(RtcpReceiverTest, ExtendedReportsPacketWithZeroReportBlocksIgnored) {
685 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700686 xr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700687
688 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000689}
690
danilchap1e714ae2016-09-05 09:57:22 -0700691// VOiP reports are ignored.
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100692TEST_F(RtcpReceiverTest, InjectExtendedReportsVoipPacket) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000693 const uint8_t kLossRate = 123;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000694 rtcp::VoipMetric voip_metric;
danilchap822a16f2016-09-27 09:27:47 -0700695 voip_metric.SetMediaSsrc(kReceiverMainSsrc);
danilchap91941ae2015-12-15 07:06:36 -0800696 RTCPVoIPMetric metric;
697 metric.lossRate = kLossRate;
danilchap822a16f2016-09-27 09:27:47 -0700698 voip_metric.SetVoipMetric(metric);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100699 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700700 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700701 xr.SetVoipMetric(voip_metric);
danilchap1e714ae2016-09-05 09:57:22 -0700702
703 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000704}
705
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100706TEST_F(RtcpReceiverTest, ExtendedReportsVoipPacketNotToUsIgnored) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000707 rtcp::VoipMetric voip_metric;
danilchap822a16f2016-09-27 09:27:47 -0700708 voip_metric.SetMediaSsrc(kNotToUsSsrc);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100709 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700710 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700711 xr.SetVoipMetric(voip_metric);
danilchap1e714ae2016-09-05 09:57:22 -0700712
713 InjectRtcpPacket(xr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000714}
715
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100716TEST_F(RtcpReceiverTest, InjectExtendedReportsReceiverReferenceTimePacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700717 const NtpTime kNtp(0x10203, 0x40506);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000718 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700719 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100720 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700721 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700722 xr.SetRrtr(rrtr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000723
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200724 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
725 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
726 EXPECT_THAT(last_xr_rtis, IsEmpty());
danilchap1e714ae2016-09-05 09:57:22 -0700727
728 InjectRtcpPacket(xr);
729
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200730 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
731 ASSERT_THAT(last_xr_rtis, SizeIs(1));
732 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
733 EXPECT_EQ(CompactNtp(kNtp), last_xr_rtis[0].last_rr);
734 EXPECT_EQ(0U, last_xr_rtis[0].delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000735}
736
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100737TEST_F(RtcpReceiverTest, ExtendedReportsDlrrPacketNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700738 // Allow calculate rtt using dlrr/rrtr, simulating media receiver side.
739 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000740
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100741 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700742 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700743 xr.AddDlrrItem(ReceiveTimeInfo(kNotToUsSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700744
745 InjectRtcpPacket(xr);
746
747 int64_t rtt_ms = 0;
748 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000749}
750
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100751TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithSubBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700752 const uint32_t kLastRR = 0x12345;
753 const uint32_t kDelay = 0x23456;
754 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
755 int64_t rtt_ms = 0;
756 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000757
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100758 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700759 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700760 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
danilchap1e714ae2016-09-05 09:57:22 -0700761
762 InjectRtcpPacket(xr);
763
danilchap37953762017-02-09 11:15:25 -0800764 uint32_t compact_ntp_now = CompactNtp(system_clock_.CurrentNtpTime());
danilchap1e714ae2016-09-05 09:57:22 -0700765 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
766 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
767 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000768}
769
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100770TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithMultipleSubBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700771 const uint32_t kLastRR = 0x12345;
772 const uint32_t kDelay = 0x56789;
773 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000774
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100775 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700776 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700777 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
778 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 1, 0x12345, 0x67890));
779 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 2, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700780
781 InjectRtcpPacket(xr);
782
danilchap37953762017-02-09 11:15:25 -0800783 uint32_t compact_ntp_now = CompactNtp(system_clock_.CurrentNtpTime());
danilchap1e714ae2016-09-05 09:57:22 -0700784 int64_t rtt_ms = 0;
785 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
786 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
787 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000788}
789
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100790TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithMultipleReportBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700791 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000792
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000793 rtcp::Rrtr rrtr;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000794 rtcp::VoipMetric metric;
danilchap822a16f2016-09-27 09:27:47 -0700795 metric.SetMediaSsrc(kReceiverMainSsrc);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100796 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700797 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700798 xr.SetRrtr(rrtr);
799 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
800 xr.SetVoipMetric(metric);
danilchap1e714ae2016-09-05 09:57:22 -0700801
802 InjectRtcpPacket(xr);
803
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200804 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
805 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
806 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700807 int64_t rtt_ms = 0;
808 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000809}
810
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100811TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithUnknownReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700812 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000813
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000814 rtcp::Rrtr rrtr;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000815 rtcp::VoipMetric metric;
danilchap822a16f2016-09-27 09:27:47 -0700816 metric.SetMediaSsrc(kReceiverMainSsrc);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100817 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700818 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700819 xr.SetRrtr(rrtr);
820 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
821 xr.SetVoipMetric(metric);
danilchap1e714ae2016-09-05 09:57:22 -0700822
danilchap69e59e62016-02-17 03:11:42 -0800823 rtc::Buffer packet = xr.Build();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000824 // Modify the DLRR block to have an unsupported block type, from 5 to 6.
danilchap1e714ae2016-09-05 09:57:22 -0700825 ASSERT_EQ(5, packet.data()[20]);
826 packet.data()[20] = 6;
827 InjectRtcpPacket(packet);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000828
danilchap1e714ae2016-09-05 09:57:22 -0700829 // Validate Rrtr was received and processed.
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200830 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
831 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
832 EXPECT_THAT(last_xr_rtis, SizeIs(1));
danilchap1e714ae2016-09-05 09:57:22 -0700833 // Validate Dlrr report wasn't processed.
834 int64_t rtt_ms = 0;
835 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000836}
837
danilchap1e714ae2016-09-05 09:57:22 -0700838TEST_F(RtcpReceiverTest, TestExtendedReportsRrRttInitiallyFalse) {
839 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
840
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000841 int64_t rtt_ms;
danilchap1e714ae2016-09-05 09:57:22 -0700842 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000843}
844
danilchap1e714ae2016-09-05 09:57:22 -0700845TEST_F(RtcpReceiverTest, RttCalculatedAfterExtendedReportsDlrr) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100846 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100847 const int64_t kRttMs = rand.Rand(1, 9 * 3600 * 1000);
848 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
849 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700850 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
danilchap37953762017-02-09 11:15:25 -0800851 NtpTime now = system_clock_.CurrentNtpTime();
Danil Chapovalova094fd12016-02-22 18:59:36 +0100852 uint32_t sent_ntp = CompactNtp(now);
853 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
854
Danil Chapovalova094fd12016-02-22 18:59:36 +0100855 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700856 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700857 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700858
859 InjectRtcpPacket(xr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100860
861 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700862 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100863 EXPECT_NEAR(kRttMs, rtt_ms, 1);
864}
865
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100866TEST_F(RtcpReceiverTest, XrDlrrCalculatesNegativeRttAsOne) {
867 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100868 const int64_t kRttMs = rand.Rand(-3600 * 1000, -1);
869 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
870 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
danilchap37953762017-02-09 11:15:25 -0800871 NtpTime now = system_clock_.CurrentNtpTime();
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100872 uint32_t sent_ntp = CompactNtp(now);
873 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
danilchap1e714ae2016-09-05 09:57:22 -0700874 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100875
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100876 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700877 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700878 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700879
880 InjectRtcpPacket(xr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100881
882 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700883 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100884 EXPECT_EQ(1, rtt_ms);
885}
886
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200887TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfoInitiallyEmpty) {
888 EXPECT_THAT(rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000889}
890
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200891TEST_F(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfo) {
Danil Chapovalovfc47ed62015-12-07 14:46:35 +0100892 const NtpTime kNtp(0x10203, 0x40506);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100893 const uint32_t kNtpMid = CompactNtp(kNtp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000894
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000895 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700896 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100897 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700898 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700899 xr.SetRrtr(rrtr);
danilchap1e714ae2016-09-05 09:57:22 -0700900
901 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000902
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000903 system_clock_.AdvanceTimeMilliseconds(1000);
Mirta Dvornicicb1f063d2018-04-16 11:16:21 +0200904
905 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
906 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
907 ASSERT_THAT(last_xr_rtis, SizeIs(1));
908 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
909 EXPECT_EQ(kNtpMid, last_xr_rtis[0].last_rr);
910 EXPECT_EQ(65536U, last_xr_rtis[0].delay_since_last_rr);
911}
912
913TEST_F(RtcpReceiverTest,
914 ReceivedRrtrFromSameSsrcUpdatesReceivedReferenceTimeInfo) {
915 const NtpTime kNtp1(0x10203, 0x40506);
916 const NtpTime kNtp2(0x11223, 0x44556);
917 const int64_t kDelayMs = 2000;
918
919 rtcp::ExtendedReports xr;
920 xr.SetSenderSsrc(kSenderSsrc);
921 rtcp::Rrtr rrtr1;
922 rrtr1.SetNtp(kNtp1);
923 xr.SetRrtr(rrtr1);
924 InjectRtcpPacket(xr);
925 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
926 rtcp::Rrtr rrtr2;
927 rrtr2.SetNtp(kNtp2);
928 xr.SetRrtr(rrtr2);
929 InjectRtcpPacket(xr);
930 system_clock_.AdvanceTimeMilliseconds(kDelayMs);
931
932 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
933 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
934 ASSERT_THAT(last_xr_rtis, SizeIs(1));
935 EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
936 EXPECT_EQ(CompactNtp(kNtp2), last_xr_rtis[0].last_rr);
937 EXPECT_EQ(kDelayMs * 65536 / 1000, last_xr_rtis[0].delay_since_last_rr);
938}
939
940TEST_F(RtcpReceiverTest, StoresLastReceivedRrtrPerSsrc) {
941 const size_t kNumBufferedReports = 1;
942 const size_t kNumReports =
943 rtcp::ExtendedReports::kMaxNumberOfDlrrItems + kNumBufferedReports;
944 for (size_t i = 0; i < kNumReports; ++i) {
945 rtcp::ExtendedReports xr;
946 xr.SetSenderSsrc(i * 100);
947 rtcp::Rrtr rrtr;
948 rrtr.SetNtp(NtpTime(i * 200, i * 300));
949 xr.SetRrtr(rrtr);
950 InjectRtcpPacket(xr);
951 system_clock_.AdvanceTimeMilliseconds(1000);
952 }
953
954 std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
955 rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
956 ASSERT_THAT(last_xr_rtis,
957 SizeIs(rtcp::ExtendedReports::kMaxNumberOfDlrrItems));
958 for (size_t i = 0; i < rtcp::ExtendedReports::kMaxNumberOfDlrrItems; ++i) {
959 EXPECT_EQ(i * 100, last_xr_rtis[i].ssrc);
960 EXPECT_EQ(CompactNtp(NtpTime(i * 200, i * 300)), last_xr_rtis[i].last_rr);
961 EXPECT_EQ(65536U * (kNumReports - i), last_xr_rtis[i].delay_since_last_rr);
962 }
963
964 last_xr_rtis = rtcp_receiver_.ConsumeReceivedXrReferenceTimeInfo();
965 ASSERT_THAT(last_xr_rtis, SizeIs(kNumBufferedReports));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000966}
967
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000968TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000969 const int64_t kRtcpIntervalMs = 1000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000970 const uint16_t kSequenceNumber = 1234;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000971 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000972
973 // No RR received, shouldn't trigger a timeout.
danilchap1e714ae2016-09-05 09:57:22 -0700974 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
975 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000976
977 // Add a RR and advance the clock just enough to not trigger a timeout.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000978 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700979 rb1.SetMediaSsrc(kReceiverMainSsrc);
980 rb1.SetExtHighestSeqNum(kSequenceNumber);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000981 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700982 rr1.SetSenderSsrc(kSenderSsrc);
983 rr1.AddReportBlock(rb1);
danilchap1e714ae2016-09-05 09:57:22 -0700984
985 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
986 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
987 InjectRtcpPacket(rr1);
988
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000989 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs - 1);
danilchap1e714ae2016-09-05 09:57:22 -0700990 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
991 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000992
993 // Add a RR with the same extended max as the previous RR to trigger a
994 // sequence number timeout, but not a RR timeout.
danilchap1e714ae2016-09-05 09:57:22 -0700995 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
996 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
997 InjectRtcpPacket(rr1);
998
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000999 system_clock_.AdvanceTimeMilliseconds(2);
danilchap1e714ae2016-09-05 09:57:22 -07001000 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
1001 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001002
1003 // Advance clock enough to trigger an RR timeout too.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001004 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -07001005 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001006
1007 // We should only get one timeout even though we still haven't received a new
1008 // RR.
danilchap1e714ae2016-09-05 09:57:22 -07001009 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
1010 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001011
1012 // Add a new RR with increase sequence number to reset timers.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001013 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001014 rb2.SetMediaSsrc(kReceiverMainSsrc);
1015 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001016 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001017 rr2.SetSenderSsrc(kSenderSsrc);
1018 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001019
1020 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1021 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1022 InjectRtcpPacket(rr2);
1023
1024 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
1025 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001026
1027 // Verify we can get a timeout again once we've received new RR.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001028 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -07001029 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1030 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1031 InjectRtcpPacket(rr2);
1032
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001033 system_clock_.AdvanceTimeMilliseconds(kRtcpIntervalMs + 1);
danilchap1e714ae2016-09-05 09:57:22 -07001034 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
1035 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
1036
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001037 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -07001038 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +00001039}
1040
hta@webrtc.org47059b52012-05-02 07:46:22 +00001041TEST_F(RtcpReceiverTest, TmmbrReceivedWithNoIncomingPacket) {
danilchap1e714ae2016-09-05 09:57:22 -07001042 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001043}
1044
1045TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) {
danilchap1e714ae2016-09-05 09:57:22 -07001046 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001047 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001048 tmmbr.SetSenderSsrc(kSenderSsrc);
1049 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001050 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);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001055
danilchap1e714ae2016-09-05 09:57:22 -07001056 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1057 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(SizeIs(1)));
1058 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1059 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1060 InjectRtcpPacket(compound);
1061
1062 std::vector<rtcp::TmmbItem> tmmbr_received = rtcp_receiver_.TmmbrReceived();
1063 ASSERT_EQ(1u, tmmbr_received.size());
1064 EXPECT_EQ(kBitrateBps, tmmbr_received[0].bitrate_bps());
1065 EXPECT_EQ(kSenderSsrc, tmmbr_received[0].ssrc());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001066}
1067
1068TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -07001069 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001070 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001071 tmmbr.SetSenderSsrc(kSenderSsrc);
1072 tmmbr.AddTmmbr(rtcp::TmmbItem(kNotToUsSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001073
1074 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001075 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001076 rtcp::CompoundPacket compound;
1077 compound.Append(&sr);
1078 compound.Append(&tmmbr);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001079
danilchap1e714ae2016-09-05 09:57:22 -07001080 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1081 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1082 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1083 InjectRtcpPacket(compound);
1084
1085 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001086}
1087
1088TEST_F(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001089 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001090 tmmbr.SetSenderSsrc(kSenderSsrc);
1091 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 0, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001092 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001093 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -07001094 rtcp::CompoundPacket compound;
1095 compound.Append(&sr);
1096 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001097
danilchap1e714ae2016-09-05 09:57:22 -07001098 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1099 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1100 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
1101 InjectRtcpPacket(compound);
1102
1103 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +00001104}
1105
hta@webrtc.org404843e2012-05-02 09:56:45 +00001106TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001107 // Inject 3 packets "from" kSenderSsrc, kSenderSsrc+1, kSenderSsrc+2.
hta@webrtc.org404843e2012-05-02 09:56:45 +00001108 // The times of arrival are starttime + 0, starttime + 5 and starttime + 10.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001109 for (uint32_t ssrc = kSenderSsrc; ssrc < kSenderSsrc + 3; ++ssrc) {
1110 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001111 tmmbr.SetSenderSsrc(ssrc);
1112 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 30000, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001113 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001114 sr.SetSenderSsrc(ssrc);
danilchap7a4116a2016-03-14 08:19:28 -07001115 rtcp::CompoundPacket compound;
1116 compound.Append(&sr);
1117 compound.Append(&tmmbr);
danilchap1e714ae2016-09-05 09:57:22 -07001118
1119 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1120 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(_));
1121 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1122 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_));
1123 InjectRtcpPacket(compound);
1124
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001125 // 5 seconds between each packet.
1126 system_clock_.AdvanceTimeMilliseconds(5000);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001127 }
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001128 // It is now starttime + 15.
danilchap1e714ae2016-09-05 09:57:22 -07001129 std::vector<rtcp::TmmbItem> candidate_set = rtcp_receiver_.TmmbrReceived();
1130 ASSERT_EQ(3u, candidate_set.size());
1131 EXPECT_EQ(30000U, candidate_set[0].bitrate_bps());
1132
hta@webrtc.org404843e2012-05-02 09:56:45 +00001133 // We expect the timeout to be 25 seconds. Advance the clock by 12
1134 // seconds, timing out the first packet.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001135 system_clock_.AdvanceTimeMilliseconds(12000);
danilchap1e714ae2016-09-05 09:57:22 -07001136 candidate_set = rtcp_receiver_.TmmbrReceived();
1137 ASSERT_EQ(2u, candidate_set.size());
danilchap287e5482016-08-16 15:15:39 -07001138 EXPECT_EQ(kSenderSsrc + 1, candidate_set[0].ssrc());
hta@webrtc.org404843e2012-05-02 09:56:45 +00001139}
1140
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001141TEST_F(RtcpReceiverTest, Callbacks) {
danilchap1e714ae2016-09-05 09:57:22 -07001142 MockRtcpCallbackImpl callback;
1143 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001144
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001145 const uint8_t kFractionLoss = 3;
1146 const uint32_t kCumulativeLoss = 7;
1147 const uint32_t kJitter = 9;
1148 const uint16_t kSequenceNumber = 1234;
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001149
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001150 // First packet, all numbers should just propagate.
1151 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -07001152 rb1.SetMediaSsrc(kReceiverMainSsrc);
1153 rb1.SetExtHighestSeqNum(kSequenceNumber);
1154 rb1.SetFractionLost(kFractionLoss);
1155 rb1.SetCumulativeLost(kCumulativeLoss);
1156 rb1.SetJitter(kJitter);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001157
1158 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -07001159 rr1.SetSenderSsrc(kSenderSsrc);
1160 rr1.AddReportBlock(rb1);
srte186d9c32017-08-04 05:03:53 -07001161 EXPECT_CALL(callback,
1162 StatisticsUpdated(
1163 AllOf(Field(&RtcpStatistics::fraction_lost, kFractionLoss),
1164 Field(&RtcpStatistics::packets_lost, kCumulativeLoss),
1165 Field(&RtcpStatistics::extended_highest_sequence_number,
1166 kSequenceNumber),
1167 Field(&RtcpStatistics::jitter, kJitter)),
1168 kReceiverMainSsrc));
danilchap1e714ae2016-09-05 09:57:22 -07001169 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1170 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1171 InjectRtcpPacket(rr1);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001172
danilchap1e714ae2016-09-05 09:57:22 -07001173 rtcp_receiver_.RegisterRtcpStatisticsCallback(nullptr);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001174
danilchap1e714ae2016-09-05 09:57:22 -07001175 // Add arbitrary numbers, callback should not be called.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001176 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001177 rb2.SetMediaSsrc(kReceiverMainSsrc);
1178 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
1179 rb2.SetFractionLost(42);
1180 rb2.SetCumulativeLost(137);
1181 rb2.SetJitter(4711);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001182
1183 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001184 rr2.SetSenderSsrc(kSenderSsrc);
1185 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001186
1187 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1188 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1189 EXPECT_CALL(callback, StatisticsUpdated(_, _)).Times(0);
1190 InjectRtcpPacket(rr2);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001191}
hta@webrtc.org404843e2012-05-02 09:56:45 +00001192
sprang49f9cdb2015-10-01 03:06:57 -07001193TEST_F(RtcpReceiverTest, ReceivesTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001194 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001195 packet.SetMediaSsrc(kReceiverMainSsrc);
1196 packet.SetSenderSsrc(kSenderSsrc);
1197 packet.SetBase(1, 1000);
1198 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001199
danilchap1e714ae2016-09-05 09:57:22 -07001200 EXPECT_CALL(
1201 transport_feedback_observer_,
1202 OnTransportFeedback(AllOf(
1203 Property(&rtcp::TransportFeedback::media_ssrc, kReceiverMainSsrc),
1204 Property(&rtcp::TransportFeedback::sender_ssrc, kSenderSsrc))));
1205 InjectRtcpPacket(packet);
sprang49f9cdb2015-10-01 03:06:57 -07001206}
1207
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001208TEST_F(RtcpReceiverTest, ReceivesRemb) {
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001209 const uint32_t kBitrateBps = 500000;
1210 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001211 remb.SetSenderSsrc(kSenderSsrc);
1212 remb.SetBitrateBps(kBitrateBps);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001213
danilchap1e714ae2016-09-05 09:57:22 -07001214 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1215 InjectRtcpPacket(remb);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001216}
1217
sprang49f9cdb2015-10-01 03:06:57 -07001218TEST_F(RtcpReceiverTest, HandlesInvalidTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001219 // Send a compound packet with a TransportFeedback followed by something else.
1220 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001221 packet.SetMediaSsrc(kReceiverMainSsrc);
1222 packet.SetSenderSsrc(kSenderSsrc);
1223 packet.SetBase(1, 1000);
1224 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001225
1226 static uint32_t kBitrateBps = 50000;
1227 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001228 remb.SetSenderSsrc(kSenderSsrc);
1229 remb.SetBitrateBps(kBitrateBps);
danilchap7a4116a2016-03-14 08:19:28 -07001230 rtcp::CompoundPacket compound;
1231 compound.Append(&packet);
1232 compound.Append(&remb);
1233 rtc::Buffer built_packet = compound.Build();
sprang49f9cdb2015-10-01 03:06:57 -07001234
1235 // Modify the TransportFeedback packet so that it is invalid.
1236 const size_t kStatusCountOffset = 14;
1237 ByteWriter<uint16_t>::WriteBigEndian(
danilchap69e59e62016-02-17 03:11:42 -08001238 &built_packet.data()[kStatusCountOffset], 42);
sprang49f9cdb2015-10-01 03:06:57 -07001239
danilchap1e714ae2016-09-05 09:57:22 -07001240 // Stress no transport feedback is expected.
1241 EXPECT_CALL(transport_feedback_observer_, OnTransportFeedback(_)).Times(0);
1242 // But remb should be processed and cause a callback
1243 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1244 InjectRtcpPacket(built_packet);
sprang49f9cdb2015-10-01 03:06:57 -07001245}
1246
danilchap1e714ae2016-09-05 09:57:22 -07001247TEST_F(RtcpReceiverTest, Nack) {
1248 const uint16_t kNackList1[] = {1, 2, 3, 5};
danilchap142f0192016-10-20 08:22:42 -07001249 const uint16_t kNackList23[] = {5, 7, 30, 40, 41, 58, 59, 61, 63};
1250 const size_t kNackListLength2 = 4;
1251 const size_t kNackListLength3 = arraysize(kNackList23) - kNackListLength2;
danilchap1e714ae2016-09-05 09:57:22 -07001252 std::set<uint16_t> nack_set;
1253 nack_set.insert(std::begin(kNackList1), std::end(kNackList1));
danilchap142f0192016-10-20 08:22:42 -07001254 nack_set.insert(std::begin(kNackList23), std::end(kNackList23));
danilchap1e714ae2016-09-05 09:57:22 -07001255
danilchap142f0192016-10-20 08:22:42 -07001256 rtcp::Nack nack1;
1257 nack1.SetSenderSsrc(kSenderSsrc);
1258 nack1.SetMediaSsrc(kReceiverMainSsrc);
1259 nack1.SetPacketIds(kNackList1, arraysize(kNackList1));
danilchap1e714ae2016-09-05 09:57:22 -07001260
1261 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList1)));
danilchap1e714ae2016-09-05 09:57:22 -07001262 EXPECT_CALL(packet_type_counter_observer_,
1263 RtcpPacketTypesCounterUpdated(
1264 kReceiverMainSsrc,
1265 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
danilchap142f0192016-10-20 08:22:42 -07001266 arraysize(kNackList1)),
1267 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1268 arraysize(kNackList1)))));
1269 InjectRtcpPacket(nack1);
1270
1271 rtcp::Nack nack2;
1272 nack2.SetSenderSsrc(kSenderSsrc);
1273 nack2.SetMediaSsrc(kReceiverMainSsrc);
1274 nack2.SetPacketIds(kNackList23, kNackListLength2);
1275
1276 rtcp::Nack nack3;
1277 nack3.SetSenderSsrc(kSenderSsrc);
1278 nack3.SetMediaSsrc(kReceiverMainSsrc);
1279 nack3.SetPacketIds(kNackList23 + kNackListLength2, kNackListLength3);
1280
1281 rtcp::CompoundPacket two_nacks;
1282 two_nacks.Append(&nack2);
1283 two_nacks.Append(&nack3);
1284
1285 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList23)));
1286 EXPECT_CALL(packet_type_counter_observer_,
1287 RtcpPacketTypesCounterUpdated(
1288 kReceiverMainSsrc,
1289 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
1290 arraysize(kNackList1) + arraysize(kNackList23)),
danilchap1e714ae2016-09-05 09:57:22 -07001291 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1292 nack_set.size()))));
danilchap142f0192016-10-20 08:22:42 -07001293 InjectRtcpPacket(two_nacks);
danilchap1e714ae2016-09-05 09:57:22 -07001294}
1295
1296TEST_F(RtcpReceiverTest, NackNotForUsIgnored) {
1297 const uint16_t kNackList1[] = {1, 2, 3, 5};
1298 const size_t kNackListLength1 = std::end(kNackList1) - std::begin(kNackList1);
1299
1300 rtcp::Nack nack;
danilchap822a16f2016-09-27 09:27:47 -07001301 nack.SetSenderSsrc(kSenderSsrc);
1302 nack.SetMediaSsrc(kNotToUsSsrc);
1303 nack.SetPacketIds(kNackList1, kNackListLength1);
danilchap1e714ae2016-09-05 09:57:22 -07001304
1305 EXPECT_CALL(packet_type_counter_observer_,
1306 RtcpPacketTypesCounterUpdated(
1307 _, Field(&RtcpPacketTypeCounter::nack_requests, 0)));
1308 InjectRtcpPacket(nack);
1309}
1310
1311TEST_F(RtcpReceiverTest, ForceSenderReport) {
1312 rtcp::RapidResyncRequest rr;
danilchap822a16f2016-09-27 09:27:47 -07001313 rr.SetSenderSsrc(kSenderSsrc);
1314 rr.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -07001315
1316 EXPECT_CALL(rtp_rtcp_impl_, OnRequestSendReport());
1317 InjectRtcpPacket(rr);
1318}
hta@webrtc.org47059b52012-05-02 07:46:22 +00001319
spranga790d832016-12-02 07:29:44 -08001320TEST_F(RtcpReceiverTest, ReceivesTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001321 VideoBitrateAllocation expected_allocation;
spranga790d832016-12-02 07:29:44 -08001322 expected_allocation.SetBitrate(0, 0, 10000);
1323 expected_allocation.SetBitrate(0, 1, 20000);
1324 expected_allocation.SetBitrate(1, 0, 40000);
1325 expected_allocation.SetBitrate(1, 1, 80000);
1326
1327 rtcp::TargetBitrate bitrate;
1328 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1329 bitrate.AddTargetBitrate(0, 1, expected_allocation.GetBitrate(0, 1) / 1000);
1330 bitrate.AddTargetBitrate(1, 0, expected_allocation.GetBitrate(1, 0) / 1000);
1331 bitrate.AddTargetBitrate(1, 1, expected_allocation.GetBitrate(1, 1) / 1000);
1332
1333 rtcp::ExtendedReports xr;
1334 xr.SetTargetBitrate(bitrate);
1335
sprangb32aaf92017-08-28 05:49:12 -07001336 // Wrong sender ssrc, target bitrate should be discarded.
1337 xr.SetSenderSsrc(kSenderSsrc + 1);
1338 EXPECT_CALL(bitrate_allocation_observer_,
1339 OnBitrateAllocationUpdated(expected_allocation))
1340 .Times(0);
1341 InjectRtcpPacket(xr);
1342
1343 // Set correct ssrc, callback should be called once.
1344 xr.SetSenderSsrc(kSenderSsrc);
spranga790d832016-12-02 07:29:44 -08001345 EXPECT_CALL(bitrate_allocation_observer_,
1346 OnBitrateAllocationUpdated(expected_allocation));
1347 InjectRtcpPacket(xr);
1348}
1349
sprang6d314c72016-12-06 06:08:53 -08001350TEST_F(RtcpReceiverTest, HandlesIncorrectTargetBitrate) {
Erik Språng566124a2018-04-23 12:32:22 +02001351 VideoBitrateAllocation expected_allocation;
sprang6d314c72016-12-06 06:08:53 -08001352 expected_allocation.SetBitrate(0, 0, 10000);
1353
1354 rtcp::TargetBitrate bitrate;
1355 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1356 bitrate.AddTargetBitrate(0, kMaxTemporalStreams, 20000);
1357 bitrate.AddTargetBitrate(kMaxSpatialLayers, 0, 40000);
1358
1359 rtcp::ExtendedReports xr;
1360 xr.SetTargetBitrate(bitrate);
sprangb32aaf92017-08-28 05:49:12 -07001361 xr.SetSenderSsrc(kSenderSsrc);
sprang6d314c72016-12-06 06:08:53 -08001362
1363 EXPECT_CALL(bitrate_allocation_observer_,
1364 OnBitrateAllocationUpdated(expected_allocation));
1365 InjectRtcpPacket(xr);
1366}
1367
hta@webrtc.org47059b52012-05-02 07:46:22 +00001368} // namespace webrtc