blob: 50585e2dfe584a5f792eb72eed8a48e061edf53c [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
kwiberg529662a2017-09-04 05:43:17 -070013#include "webrtc/api/array_view.h"
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000014#include "webrtc/common_types.h"
spranga790d832016-12-02 07:29:44 -080015#include "webrtc/common_video/include/video_bitrate_allocator.h"
sprang49f9cdb2015-10-01 03:06:57 -070016#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +000017#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
danilchap0219c9b2015-11-18 05:56:53 -080018#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h"
danilchap50c51362015-11-22 09:03:11 -080019#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h"
danilchap7a4116a2016-03-14 08:19:28 -070020#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.h"
danilchapf8506cb2015-11-13 07:33:20 -080021#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.h"
Danil Chapovalov256e5b22016-01-15 14:16:24 +010022#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
Danil Chapovalov5679da12016-01-15 13:19:53 +010023#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/fir.h"
danilchap1e714ae2016-09-05 09:57:22 -070024#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/nack.h"
danilchapf8385ad2015-11-27 05:36:09 -080025#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/pli.h"
danilchap1e714ae2016-09-05 09:57:22 -070026#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/rapid_resync_request.h"
Danil Chapovalov97f7e132015-12-04 16:13:30 +010027#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
Danil Chapovalova5eba6c2016-01-15 12:40:15 +010028#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/remb.h"
Danil Chapovalov1567d0b2016-01-15 17:34:27 +010029#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sdes.h"
danilchap34ed2b92016-01-18 02:43:32 -080030#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
danilchap7e8145f2016-01-11 11:49:19 -080031#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.h"
sprang49f9cdb2015-10-01 03:06:57 -070032#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
danilchapb8b6fbb2015-12-10 05:05:27 -080033#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
Danil Chapovalova094fd12016-02-22 18:59:36 +010034#include "webrtc/modules/rtp_rtcp/source/time_util.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020035#include "webrtc/rtc_base/arraysize.h"
36#include "webrtc/rtc_base/random.h"
Danil Chapovalova094fd12016-02-22 18:59:36 +010037#include "webrtc/system_wrappers/include/ntp_time.h"
kwibergac9f8762016-09-30 22:29:43 -070038#include "webrtc/test/gmock.h"
39#include "webrtc/test/gtest.h"
hta@webrtc.org47059b52012-05-02 07:46:22 +000040
41namespace webrtc {
danilchap1e714ae2016-09-05 09:57:22 -070042namespace {
hta@webrtc.org47059b52012-05-02 07:46:22 +000043
danilchap1e714ae2016-09-05 09:57:22 -070044using ::testing::_;
45using ::testing::AllOf;
46using ::testing::ElementsAreArray;
47using ::testing::Field;
48using ::testing::IsEmpty;
49using ::testing::NiceMock;
50using ::testing::Property;
51using ::testing::SizeIs;
52using ::testing::StrEq;
53using ::testing::StrictMock;
54using ::testing::UnorderedElementsAre;
danilchap80ac24d2016-10-31 08:40:47 -070055using rtcp::ReceiveTimeInfo;
hta@webrtc.org47059b52012-05-02 07:46:22 +000056
danilchap1e714ae2016-09-05 09:57:22 -070057class MockRtcpPacketTypeCounterObserver : public RtcpPacketTypeCounterObserver {
hta@webrtc.org47059b52012-05-02 07:46:22 +000058 public:
danilchap1e714ae2016-09-05 09:57:22 -070059 MOCK_METHOD2(RtcpPacketTypesCounterUpdated,
60 void(uint32_t, const RtcpPacketTypeCounter&));
hta@webrtc.org47059b52012-05-02 07:46:22 +000061};
62
danilchap1e714ae2016-09-05 09:57:22 -070063class MockRtcpIntraFrameObserver : public RtcpIntraFrameObserver {
64 public:
65 MOCK_METHOD1(OnReceivedIntraFrameRequest, void(uint32_t));
danilchap1e714ae2016-09-05 09:57:22 -070066};
67
68class MockRtcpCallbackImpl : public RtcpStatisticsCallback {
69 public:
70 MOCK_METHOD2(StatisticsUpdated, void(const RtcpStatistics&, uint32_t));
71 MOCK_METHOD2(CNameChanged, void(const char*, uint32_t));
72};
73
74class MockTransportFeedbackObserver : public TransportFeedbackObserver {
75 public:
elad.alond12a8e12017-03-23 11:04:48 -070076 MOCK_METHOD3(AddPacket, void(uint32_t, uint16_t, size_t));
77 MOCK_METHOD4(AddPacket,
78 void(uint32_t, uint16_t, size_t, const PacedPacketInfo&));
danilchap1e714ae2016-09-05 09:57:22 -070079 MOCK_METHOD1(OnTransportFeedback, void(const rtcp::TransportFeedback&));
elad.alonf9490002017-03-06 05:32:21 -080080 MOCK_CONST_METHOD0(GetTransportFeedbackVector, std::vector<PacketFeedback>());
danilchap1e714ae2016-09-05 09:57:22 -070081};
82
83class MockRtcpBandwidthObserver : public RtcpBandwidthObserver {
84 public:
85 MOCK_METHOD1(OnReceivedEstimatedBitrate, void(uint32_t));
86 MOCK_METHOD3(OnReceivedRtcpReceiverReport,
87 void(const ReportBlockList&, int64_t, int64_t));
88};
89
90class MockModuleRtpRtcp : public RTCPReceiver::ModuleRtpRtcp {
91 public:
92 MOCK_METHOD1(SetTmmbn, void(std::vector<rtcp::TmmbItem>));
93 MOCK_METHOD0(OnRequestSendReport, void());
94 MOCK_METHOD1(OnReceivedNack, void(const std::vector<uint16_t>&));
95 MOCK_METHOD1(OnReceivedRtcpReportBlocks, void(const ReportBlockList&));
96};
97
spranga790d832016-12-02 07:29:44 -080098class MockVideoBitrateAllocationObserver
99 : public VideoBitrateAllocationObserver {
100 public:
101 MOCK_METHOD1(OnBitrateAllocationUpdated,
102 void(const BitrateAllocation& allocation));
103};
104
danilchap1e714ae2016-09-05 09:57:22 -0700105// SSRC of remote peer, that sends rtcp packet to the rtcp receiver under test.
106constexpr uint32_t kSenderSsrc = 0x10203;
107// SSRCs of local peer, that rtcp packet addressed to.
108constexpr uint32_t kReceiverMainSsrc = 0x123456;
109// RtcpReceiver can accept several ssrc, e.g. regular and rtx streams.
110constexpr uint32_t kReceiverExtraSsrc = 0x1234567;
111// SSRCs to ignore (i.e. not configured in RtcpReceiver).
112constexpr uint32_t kNotToUsSsrc = 0x654321;
113constexpr uint32_t kUnknownSenderSsrc = 0x54321;
114
115} // namespace
116
hta@webrtc.org47059b52012-05-02 07:46:22 +0000117class RtcpReceiverTest : public ::testing::Test {
118 protected:
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000119 RtcpReceiverTest()
danilchap1e714ae2016-09-05 09:57:22 -0700120 : system_clock_(1335900000),
121 rtcp_receiver_(&system_clock_,
122 false,
123 &packet_type_counter_observer_,
124 &bandwidth_observer_,
125 &intra_frame_observer_,
126 &transport_feedback_observer_,
spranga790d832016-12-02 07:29:44 -0800127 &bitrate_allocation_observer_,
danilchap1e714ae2016-09-05 09:57:22 -0700128 &rtp_rtcp_impl_) {}
129 void SetUp() {
130 std::set<uint32_t> ssrcs = {kReceiverMainSsrc, kReceiverExtraSsrc};
danilchap1e714ae2016-09-05 09:57:22 -0700131 rtcp_receiver_.SetSsrcs(kReceiverMainSsrc, ssrcs);
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000132
danilchap1e714ae2016-09-05 09:57:22 -0700133 rtcp_receiver_.SetRemoteSSRC(kSenderSsrc);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000134 }
Erik Språng737336d2016-07-29 12:59:36 +0200135
danilchap1e714ae2016-09-05 09:57:22 -0700136 void InjectRtcpPacket(rtc::ArrayView<const uint8_t> raw) {
137 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
hta@webrtc.org47059b52012-05-02 07:46:22 +0000138 }
139
danilchap1e714ae2016-09-05 09:57:22 -0700140 void InjectRtcpPacket(const rtcp::RtcpPacket& packet) {
141 rtc::Buffer raw = packet.Build();
142 rtcp_receiver_.IncomingPacket(raw.data(), raw.size());
143 }
144
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000145 SimulatedClock system_clock_;
danilchap1e714ae2016-09-05 09:57:22 -0700146 // Callbacks to packet_type_counter_observer are frequent but most of the time
147 // are not interesting.
148 NiceMock<MockRtcpPacketTypeCounterObserver> packet_type_counter_observer_;
149 StrictMock<MockRtcpBandwidthObserver> bandwidth_observer_;
150 StrictMock<MockRtcpIntraFrameObserver> intra_frame_observer_;
151 StrictMock<MockTransportFeedbackObserver> transport_feedback_observer_;
spranga790d832016-12-02 07:29:44 -0800152 StrictMock<MockVideoBitrateAllocationObserver> bitrate_allocation_observer_;
danilchap1e714ae2016-09-05 09:57:22 -0700153 StrictMock<MockModuleRtpRtcp> rtp_rtcp_impl_;
hta@webrtc.org47059b52012-05-02 07:46:22 +0000154
danilchap1e714ae2016-09-05 09:57:22 -0700155 RTCPReceiver rtcp_receiver_;
156};
hta@webrtc.org47059b52012-05-02 07:46:22 +0000157
158TEST_F(RtcpReceiverTest, BrokenPacketIsIgnored) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000159 const uint8_t bad_packet[] = {0, 0, 0, 0};
danilchap1e714ae2016-09-05 09:57:22 -0700160 EXPECT_CALL(packet_type_counter_observer_,
161 RtcpPacketTypesCounterUpdated(_, _))
162 .Times(0);
163 InjectRtcpPacket(bad_packet);
hta@webrtc.org47059b52012-05-02 07:46:22 +0000164}
165
danilchap50da1d32016-03-10 13:13:52 -0800166TEST_F(RtcpReceiverTest, InvalidFeedbackPacketIsIgnored) {
167 // Too short feedback packet.
danilchap1e714ae2016-09-05 09:57:22 -0700168 const uint8_t bad_packet[] = {0x81, rtcp::Rtpfb::kPacketType, 0, 0};
169
170 // TODO(danilchap): Add expectation RtcpPacketTypesCounterUpdated
171 // is not called once parser would be adjusted to avoid that callback on
172 // semi-valid packets.
173 InjectRtcpPacket(bad_packet);
danilchap50da1d32016-03-10 13:13:52 -0800174}
175
hta@webrtc.org47059b52012-05-02 07:46:22 +0000176TEST_F(RtcpReceiverTest, InjectSrPacket) {
danilchapa04d9c32017-07-25 04:03:39 -0700177 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
danilchap1e714ae2016-09-05 09:57:22 -0700178
179 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000180 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700181 sr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700182
183 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
184 EXPECT_CALL(bandwidth_observer_,
185 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
186 InjectRtcpPacket(sr);
187
danilchapa04d9c32017-07-25 04:03:39 -0700188 EXPECT_TRUE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
hta@webrtc.org47059b52012-05-02 07:46:22 +0000189}
190
danilchap1e714ae2016-09-05 09:57:22 -0700191TEST_F(RtcpReceiverTest, InjectSrPacketFromUnknownSender) {
192 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000193 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700194 sr.SetSenderSsrc(kUnknownSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700195
196 // The parser will handle report blocks in Sender Report from other than his
197 // expected peer.
198 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
199 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, now));
200 InjectRtcpPacket(sr);
201
202 // But will not flag that he's gotten sender information.
danilchapa04d9c32017-07-25 04:03:39 -0700203 EXPECT_FALSE(rtcp_receiver_.NTP(nullptr, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000204}
205
Danil Chapovalova094fd12016-02-22 18:59:36 +0100206TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesRTT) {
207 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100208 const int64_t kRttMs = r.Rand(1, 9 * 3600 * 1000);
209 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
210 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100211
Danil Chapovalova094fd12016-02-22 18:59:36 +0100212 int64_t rtt_ms = 0;
213 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700214 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100215
danilchap37953762017-02-09 11:15:25 -0800216 uint32_t sent_ntp = CompactNtp(system_clock_.CurrentNtpTime());
Danil Chapovalova094fd12016-02-22 18:59:36 +0100217 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
218
219 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700220 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100221 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700222 block.SetMediaSsrc(kReceiverMainSsrc);
223 block.SetLastSr(sent_ntp);
224 block.SetDelayLastSr(kDelayNtp);
225 sr.AddReportBlock(block);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100226
danilchap1e714ae2016-09-05 09:57:22 -0700227 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
228 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
229 InjectRtcpPacket(sr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100230
231 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700232 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100233 EXPECT_NEAR(kRttMs, rtt_ms, 1);
234}
235
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100236TEST_F(RtcpReceiverTest, InjectSrPacketCalculatesNegativeRTTAsOne) {
237 Random r(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100238 const int64_t kRttMs = r.Rand(-3600 * 1000, -1);
239 const uint32_t kDelayNtp = r.Rand(0, 0x7fffffff);
240 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
241
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100242 int64_t rtt_ms = 0;
243 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700244 -1, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100245
danilchap37953762017-02-09 11:15:25 -0800246 uint32_t sent_ntp = CompactNtp(system_clock_.CurrentNtpTime());
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100247 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
248
249 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700250 sr.SetSenderSsrc(kSenderSsrc);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100251 rtcp::ReportBlock block;
danilchap822a16f2016-09-27 09:27:47 -0700252 block.SetMediaSsrc(kReceiverMainSsrc);
253 block.SetLastSr(sent_ntp);
254 block.SetDelayLastSr(kDelayNtp);
255 sr.AddReportBlock(block);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100256
danilchap1e714ae2016-09-05 09:57:22 -0700257 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
258 EXPECT_CALL(bandwidth_observer_,
259 OnReceivedRtcpReceiverReport(SizeIs(1), _, _));
260 InjectRtcpPacket(sr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100261
262 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700263 0, rtcp_receiver_.RTT(kSenderSsrc, &rtt_ms, nullptr, nullptr, nullptr));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100264 EXPECT_EQ(1, rtt_ms);
265}
266
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000267TEST_F(RtcpReceiverTest, InjectRrPacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700268 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000269 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700270 rr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700271
272 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
273 EXPECT_CALL(bandwidth_observer_,
274 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
275 InjectRtcpPacket(rr);
276
danilchap1e714ae2016-09-05 09:57:22 -0700277 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReceiverReport());
278 std::vector<RTCPReportBlock> report_blocks;
279 rtcp_receiver_.StatisticsReceived(&report_blocks);
280 EXPECT_TRUE(report_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000281}
282
283TEST_F(RtcpReceiverTest, InjectRrPacketWithReportBlockNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700284 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000285 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700286 rb.SetMediaSsrc(kNotToUsSsrc);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000287 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700288 rr.SetSenderSsrc(kSenderSsrc);
289 rr.AddReportBlock(rb);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000290
danilchap1e714ae2016-09-05 09:57:22 -0700291 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(IsEmpty()));
292 EXPECT_CALL(bandwidth_observer_,
293 OnReceivedRtcpReceiverReport(IsEmpty(), _, now));
294 InjectRtcpPacket(rr);
295
296 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReceiverReport());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000297 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700298 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000299 EXPECT_TRUE(received_blocks.empty());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000300}
301
302TEST_F(RtcpReceiverTest, InjectRrPacketWithOneReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700303 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000304
305 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700306 rb.SetMediaSsrc(kReceiverMainSsrc);
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(SizeIs(1)));
312 EXPECT_CALL(bandwidth_observer_,
313 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
314 InjectRtcpPacket(rr);
315
316 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReceiverReport());
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_EQ(1u, received_blocks.size());
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000320}
321
322TEST_F(RtcpReceiverTest, InjectRrPacketWithTwoReportBlocks) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000323 const uint16_t kSequenceNumbers[] = {10, 12423};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000324 const uint32_t kCumLost[] = {13, 555};
325 const uint8_t kFracLost[] = {20, 11};
danilchap1e714ae2016-09-05 09:57:22 -0700326 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000327
328 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700329 rb1.SetMediaSsrc(kReceiverMainSsrc);
330 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
331 rb1.SetFractionLost(10);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000332
333 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700334 rb2.SetMediaSsrc(kReceiverExtraSsrc);
335 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
336 rb2.SetFractionLost(0);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000337
338 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700339 rr1.SetSenderSsrc(kSenderSsrc);
340 rr1.AddReportBlock(rb1);
341 rr1.AddReportBlock(rb2);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000342
danilchap1e714ae2016-09-05 09:57:22 -0700343 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
344 EXPECT_CALL(bandwidth_observer_,
345 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
346 InjectRtcpPacket(rr1);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000347
danilchap1e714ae2016-09-05 09:57:22 -0700348 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReceiverReport());
349 std::vector<RTCPReportBlock> received_blocks;
350 rtcp_receiver_.StatisticsReceived(&received_blocks);
351 EXPECT_THAT(received_blocks,
srte3e69e5c2017-08-09 06:13:45 -0700352 UnorderedElementsAre(Field(&RTCPReportBlock::fraction_lost, 0),
353 Field(&RTCPReportBlock::fraction_lost, 10)));
danilchap1e714ae2016-09-05 09:57:22 -0700354
355 // Insert next receiver report with same ssrc but new values.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000356 rtcp::ReportBlock rb3;
danilchap822a16f2016-09-27 09:27:47 -0700357 rb3.SetMediaSsrc(kReceiverMainSsrc);
358 rb3.SetExtHighestSeqNum(kSequenceNumbers[0]);
359 rb3.SetFractionLost(kFracLost[0]);
360 rb3.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000361
362 rtcp::ReportBlock rb4;
danilchap822a16f2016-09-27 09:27:47 -0700363 rb4.SetMediaSsrc(kReceiverExtraSsrc);
364 rb4.SetExtHighestSeqNum(kSequenceNumbers[1]);
365 rb4.SetFractionLost(kFracLost[1]);
366 rb4.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000367
368 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700369 rr2.SetSenderSsrc(kSenderSsrc);
370 rr2.AddReportBlock(rb3);
371 rr2.AddReportBlock(rb4);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000372
danilchap1e714ae2016-09-05 09:57:22 -0700373 // Advance time to make 1st sent time and 2nd sent time different.
374 system_clock_.AdvanceTimeMilliseconds(500);
375 now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000376
danilchap1e714ae2016-09-05 09:57:22 -0700377 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(2)));
378 EXPECT_CALL(bandwidth_observer_,
379 OnReceivedRtcpReceiverReport(SizeIs(2), _, now));
380 InjectRtcpPacket(rr2);
381
382 received_blocks.clear();
383 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000384 EXPECT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700385 EXPECT_THAT(
386 received_blocks,
387 UnorderedElementsAre(
388 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
389 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
390 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
391 Field(&RTCPReportBlock::extended_highest_sequence_number,
392 kSequenceNumbers[0])),
393 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverExtraSsrc),
394 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
395 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
396 Field(&RTCPReportBlock::extended_highest_sequence_number,
397 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000398}
399
400TEST_F(RtcpReceiverTest, InjectRrPacketsFromTwoRemoteSsrcs) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000401 const uint32_t kSenderSsrc2 = 0x20304;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000402 const uint16_t kSequenceNumbers[] = {10, 12423};
403 const uint32_t kCumLost[] = {13, 555};
404 const uint8_t kFracLost[] = {20, 11};
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000405
406 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700407 rb1.SetMediaSsrc(kReceiverMainSsrc);
408 rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
409 rb1.SetFractionLost(kFracLost[0]);
410 rb1.SetCumulativeLost(kCumLost[0]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000411 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700412 rr1.SetSenderSsrc(kSenderSsrc);
413 rr1.AddReportBlock(rb1);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000414
danilchap1e714ae2016-09-05 09:57:22 -0700415 int64_t now = system_clock_.TimeInMilliseconds();
416
417 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
418 EXPECT_CALL(bandwidth_observer_,
419 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
420 InjectRtcpPacket(rr1);
421
422 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReceiverReport());
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000423
424 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700425 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000426 EXPECT_EQ(1u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700427 EXPECT_EQ(kSenderSsrc, received_blocks[0].sender_ssrc);
428 EXPECT_EQ(kReceiverMainSsrc, received_blocks[0].source_ssrc);
429 EXPECT_EQ(kFracLost[0], received_blocks[0].fraction_lost);
430 EXPECT_EQ(kCumLost[0], received_blocks[0].packets_lost);
431 EXPECT_EQ(kSequenceNumbers[0],
432 received_blocks[0].extended_highest_sequence_number);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000433
434 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700435 rb2.SetMediaSsrc(kReceiverMainSsrc);
436 rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
437 rb2.SetFractionLost(kFracLost[1]);
438 rb2.SetCumulativeLost(kCumLost[1]);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000439 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700440 rr2.SetSenderSsrc(kSenderSsrc2);
441 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -0700442
443 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(SizeIs(1)));
444 EXPECT_CALL(bandwidth_observer_,
445 OnReceivedRtcpReceiverReport(SizeIs(1), _, now));
446 InjectRtcpPacket(rr2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000447
448 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700449 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000450 ASSERT_EQ(2u, received_blocks.size());
srte3e69e5c2017-08-09 06:13:45 -0700451 EXPECT_THAT(
452 received_blocks,
453 UnorderedElementsAre(
454 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
455 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc),
456 Field(&RTCPReportBlock::fraction_lost, kFracLost[0]),
457 Field(&RTCPReportBlock::packets_lost, kCumLost[0]),
458 Field(&RTCPReportBlock::extended_highest_sequence_number,
459 kSequenceNumbers[0])),
460 AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc),
461 Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc2),
462 Field(&RTCPReportBlock::fraction_lost, kFracLost[1]),
463 Field(&RTCPReportBlock::packets_lost, kCumLost[1]),
464 Field(&RTCPReportBlock::extended_highest_sequence_number,
465 kSequenceNumbers[1]))));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000466}
467
468TEST_F(RtcpReceiverTest, GetRtt) {
danilchap28b03eb2016-10-05 06:59:44 -0700469 const uint32_t kSentCompactNtp = 0x1234;
470 const uint32_t kDelayCompactNtp = 0x222;
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000471 // No report block received.
Erik Språng6b8d3552015-09-24 15:06:57 +0200472 EXPECT_EQ(
danilchap1e714ae2016-09-05 09:57:22 -0700473 -1, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000474
475 rtcp::ReportBlock rb;
danilchap822a16f2016-09-27 09:27:47 -0700476 rb.SetMediaSsrc(kReceiverMainSsrc);
danilchap28b03eb2016-10-05 06:59:44 -0700477 rb.SetLastSr(kSentCompactNtp);
478 rb.SetDelayLastSr(kDelayCompactNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700479
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000480 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700481 rr.SetSenderSsrc(kSenderSsrc);
482 rr.AddReportBlock(rb);
danilchap1e714ae2016-09-05 09:57:22 -0700483 int64_t now = system_clock_.TimeInMilliseconds();
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000484
danilchap1e714ae2016-09-05 09:57:22 -0700485 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
486 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
487 InjectRtcpPacket(rr);
488
489 EXPECT_EQ(now, rtcp_receiver_.LastReceivedReceiverReport());
490 EXPECT_EQ(
491 0, rtcp_receiver_.RTT(kSenderSsrc, nullptr, nullptr, nullptr, nullptr));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000492}
493
danilchap1e714ae2016-09-05 09:57:22 -0700494// Ij packets are ignored.
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000495TEST_F(RtcpReceiverTest, InjectIjWithNoItem) {
danilchapf8506cb2015-11-13 07:33:20 -0800496 rtcp::ExtendedJitterReport ij;
danilchap1e714ae2016-09-05 09:57:22 -0700497 InjectRtcpPacket(ij);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000498}
499
danilchap1e714ae2016-09-05 09:57:22 -0700500// App packets are ignored.
501TEST_F(RtcpReceiverTest, InjectApp) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000502 rtcp::App app;
danilchap822a16f2016-09-27 09:27:47 -0700503 app.SetSubType(30);
504 app.SetName(0x17a177e);
danilchap1e714ae2016-09-05 09:57:22 -0700505 const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
danilchap822a16f2016-09-27 09:27:47 -0700506 app.SetData(kData, sizeof(kData));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000507
danilchap1e714ae2016-09-05 09:57:22 -0700508 InjectRtcpPacket(app);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000509}
510
511TEST_F(RtcpReceiverTest, InjectSdesWithOneChunk) {
danilchap1e714ae2016-09-05 09:57:22 -0700512 const char kCname[] = "alice@host";
513 MockRtcpCallbackImpl callback;
514 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000515 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700516 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000517
danilchap1e714ae2016-09-05 09:57:22 -0700518 EXPECT_CALL(callback, CNameChanged(StrEq(kCname), kSenderSsrc));
519 InjectRtcpPacket(sdes);
520
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000521 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700522 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
523 EXPECT_EQ(0, strncmp(cName, kCname, RTCP_CNAME_SIZE));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000524}
525
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000526TEST_F(RtcpReceiverTest, InjectByePacket_RemovesCname) {
danilchap1e714ae2016-09-05 09:57:22 -0700527 const char kCname[] = "alice@host";
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000528 rtcp::Sdes sdes;
danilchap822a16f2016-09-27 09:27:47 -0700529 sdes.AddCName(kSenderSsrc, kCname);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000530
danilchap1e714ae2016-09-05 09:57:22 -0700531 InjectRtcpPacket(sdes);
532
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000533 char cName[RTCP_CNAME_SIZE];
danilchap1e714ae2016-09-05 09:57:22 -0700534 EXPECT_EQ(0, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000535
536 // Verify that BYE removes the CNAME.
537 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700538 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700539
540 InjectRtcpPacket(bye);
541
542 EXPECT_EQ(-1, rtcp_receiver_.CNAME(kSenderSsrc, cName));
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000543}
544
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000545TEST_F(RtcpReceiverTest, InjectByePacket_RemovesReportBlocks) {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000546 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700547 rb1.SetMediaSsrc(kReceiverMainSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000548 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700549 rb2.SetMediaSsrc(kReceiverExtraSsrc);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000550 rtcp::ReceiverReport rr;
danilchap822a16f2016-09-27 09:27:47 -0700551 rr.SetSenderSsrc(kSenderSsrc);
552 rr.AddReportBlock(rb1);
553 rr.AddReportBlock(rb2);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000554
danilchap1e714ae2016-09-05 09:57:22 -0700555 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
556 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
557 InjectRtcpPacket(rr);
558
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000559 std::vector<RTCPReportBlock> received_blocks;
danilchap1e714ae2016-09-05 09:57:22 -0700560 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000561 EXPECT_EQ(2u, received_blocks.size());
562
563 // Verify that BYE removes the report blocks.
564 rtcp::Bye bye;
danilchap822a16f2016-09-27 09:27:47 -0700565 bye.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700566
567 InjectRtcpPacket(bye);
568
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000569 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700570 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000571 EXPECT_TRUE(received_blocks.empty());
572
danilchap1e714ae2016-09-05 09:57:22 -0700573 // Inject packet again.
574 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
575 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
576 InjectRtcpPacket(rr);
577
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000578 received_blocks.clear();
danilchap1e714ae2016-09-05 09:57:22 -0700579 rtcp_receiver_.StatisticsReceived(&received_blocks);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000580 EXPECT_EQ(2u, received_blocks.size());
581}
582
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000583TEST_F(RtcpReceiverTest, InjectPliPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000584 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700585 pli.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700586
587 EXPECT_CALL(
588 packet_type_counter_observer_,
589 RtcpPacketTypesCounterUpdated(
590 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 1)));
591 EXPECT_CALL(intra_frame_observer_,
592 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
593 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000594}
595
596TEST_F(RtcpReceiverTest, PliPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000597 rtcp::Pli pli;
danilchap822a16f2016-09-27 09:27:47 -0700598 pli.SetMediaSsrc(kNotToUsSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700599
600 EXPECT_CALL(
601 packet_type_counter_observer_,
602 RtcpPacketTypesCounterUpdated(
603 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 0)));
604 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
605 InjectRtcpPacket(pli);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000606}
607
608TEST_F(RtcpReceiverTest, InjectFirPacket) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000609 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700610 fir.AddRequestTo(kReceiverMainSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700611
612 EXPECT_CALL(
613 packet_type_counter_observer_,
614 RtcpPacketTypesCounterUpdated(
615 kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::fir_packets, 1)));
616 EXPECT_CALL(intra_frame_observer_,
617 OnReceivedIntraFrameRequest(kReceiverMainSsrc));
618 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000619}
620
621TEST_F(RtcpReceiverTest, FirPacketNotToUsIgnored) {
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000622 rtcp::Fir fir;
danilchap822a16f2016-09-27 09:27:47 -0700623 fir.AddRequestTo(kNotToUsSsrc, 13);
danilchap1e714ae2016-09-05 09:57:22 -0700624
625 EXPECT_CALL(intra_frame_observer_, OnReceivedIntraFrameRequest(_)).Times(0);
626 InjectRtcpPacket(fir);
asapersson@webrtc.orgf8723d62014-08-28 07:35:06 +0000627}
628
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100629TEST_F(RtcpReceiverTest, ExtendedReportsPacketWithZeroReportBlocksIgnored) {
630 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700631 xr.SetSenderSsrc(kSenderSsrc);
danilchap1e714ae2016-09-05 09:57:22 -0700632
633 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000634}
635
danilchap1e714ae2016-09-05 09:57:22 -0700636// VOiP reports are ignored.
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100637TEST_F(RtcpReceiverTest, InjectExtendedReportsVoipPacket) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000638 const uint8_t kLossRate = 123;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000639 rtcp::VoipMetric voip_metric;
danilchap822a16f2016-09-27 09:27:47 -0700640 voip_metric.SetMediaSsrc(kReceiverMainSsrc);
danilchap91941ae2015-12-15 07:06:36 -0800641 RTCPVoIPMetric metric;
642 metric.lossRate = kLossRate;
danilchap822a16f2016-09-27 09:27:47 -0700643 voip_metric.SetVoipMetric(metric);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100644 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700645 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700646 xr.SetVoipMetric(voip_metric);
danilchap1e714ae2016-09-05 09:57:22 -0700647
648 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000649}
650
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100651TEST_F(RtcpReceiverTest, ExtendedReportsVoipPacketNotToUsIgnored) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000652 rtcp::VoipMetric voip_metric;
danilchap822a16f2016-09-27 09:27:47 -0700653 voip_metric.SetMediaSsrc(kNotToUsSsrc);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100654 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700655 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700656 xr.SetVoipMetric(voip_metric);
danilchap1e714ae2016-09-05 09:57:22 -0700657
658 InjectRtcpPacket(xr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000659}
660
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100661TEST_F(RtcpReceiverTest, InjectExtendedReportsReceiverReferenceTimePacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700662 const NtpTime kNtp(0x10203, 0x40506);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000663 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700664 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100665 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700666 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700667 xr.SetRrtr(rrtr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000668
danilchap80ac24d2016-10-31 08:40:47 -0700669 ReceiveTimeInfo rrtime;
danilchap1e714ae2016-09-05 09:57:22 -0700670 EXPECT_FALSE(rtcp_receiver_.LastReceivedXrReferenceTimeInfo(&rrtime));
671
672 InjectRtcpPacket(xr);
673
674 EXPECT_TRUE(rtcp_receiver_.LastReceivedXrReferenceTimeInfo(&rrtime));
danilchap798896a2016-09-28 02:54:25 -0700675 EXPECT_EQ(rrtime.ssrc, kSenderSsrc);
676 EXPECT_EQ(rrtime.last_rr, CompactNtp(kNtp));
677 EXPECT_EQ(0U, rrtime.delay_since_last_rr);
danilchap1e714ae2016-09-05 09:57:22 -0700678
679 system_clock_.AdvanceTimeMilliseconds(1500);
680 EXPECT_TRUE(rtcp_receiver_.LastReceivedXrReferenceTimeInfo(&rrtime));
danilchap798896a2016-09-28 02:54:25 -0700681 EXPECT_NEAR(1500, CompactNtpRttToMs(rrtime.delay_since_last_rr), 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000682}
683
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100684TEST_F(RtcpReceiverTest, ExtendedReportsDlrrPacketNotToUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700685 // Allow calculate rtt using dlrr/rrtr, simulating media receiver side.
686 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000687
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100688 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700689 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700690 xr.AddDlrrItem(ReceiveTimeInfo(kNotToUsSsrc, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700691
692 InjectRtcpPacket(xr);
693
694 int64_t rtt_ms = 0;
695 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000696}
697
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100698TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithSubBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700699 const uint32_t kLastRR = 0x12345;
700 const uint32_t kDelay = 0x23456;
701 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
702 int64_t rtt_ms = 0;
703 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000704
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100705 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700706 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700707 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
danilchap1e714ae2016-09-05 09:57:22 -0700708
709 InjectRtcpPacket(xr);
710
danilchap37953762017-02-09 11:15:25 -0800711 uint32_t compact_ntp_now = CompactNtp(system_clock_.CurrentNtpTime());
danilchap1e714ae2016-09-05 09:57:22 -0700712 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
713 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
714 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000715}
716
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100717TEST_F(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithMultipleSubBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700718 const uint32_t kLastRR = 0x12345;
719 const uint32_t kDelay = 0x56789;
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(kReceiverMainSsrc, kLastRR, kDelay));
725 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 1, 0x12345, 0x67890));
726 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 2, 0x12345, 0x67890));
danilchap1e714ae2016-09-05 09:57:22 -0700727
728 InjectRtcpPacket(xr);
729
danilchap37953762017-02-09 11:15:25 -0800730 uint32_t compact_ntp_now = CompactNtp(system_clock_.CurrentNtpTime());
danilchap1e714ae2016-09-05 09:57:22 -0700731 int64_t rtt_ms = 0;
732 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
733 uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
734 EXPECT_NEAR(CompactNtpRttToMs(rtt_ntp), rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000735}
736
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100737TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithMultipleReportBlocks) {
danilchap1e714ae2016-09-05 09:57:22 -0700738 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000739
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000740 rtcp::Rrtr rrtr;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000741 rtcp::VoipMetric metric;
danilchap822a16f2016-09-27 09:27:47 -0700742 metric.SetMediaSsrc(kReceiverMainSsrc);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100743 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700744 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700745 xr.SetRrtr(rrtr);
746 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
747 xr.SetVoipMetric(metric);
danilchap1e714ae2016-09-05 09:57:22 -0700748
749 InjectRtcpPacket(xr);
750
danilchap80ac24d2016-10-31 08:40:47 -0700751 ReceiveTimeInfo rrtime;
danilchap1e714ae2016-09-05 09:57:22 -0700752 EXPECT_TRUE(rtcp_receiver_.LastReceivedXrReferenceTimeInfo(&rrtime));
753 int64_t rtt_ms = 0;
754 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000755}
756
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100757TEST_F(RtcpReceiverTest, InjectExtendedReportsPacketWithUnknownReportBlock) {
danilchap1e714ae2016-09-05 09:57:22 -0700758 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000759
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000760 rtcp::Rrtr rrtr;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000761 rtcp::VoipMetric metric;
danilchap822a16f2016-09-27 09:27:47 -0700762 metric.SetMediaSsrc(kReceiverMainSsrc);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100763 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700764 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700765 xr.SetRrtr(rrtr);
766 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));
767 xr.SetVoipMetric(metric);
danilchap1e714ae2016-09-05 09:57:22 -0700768
danilchap69e59e62016-02-17 03:11:42 -0800769 rtc::Buffer packet = xr.Build();
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000770 // Modify the DLRR block to have an unsupported block type, from 5 to 6.
danilchap1e714ae2016-09-05 09:57:22 -0700771 ASSERT_EQ(5, packet.data()[20]);
772 packet.data()[20] = 6;
773 InjectRtcpPacket(packet);
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000774
danilchap1e714ae2016-09-05 09:57:22 -0700775 // Validate Rrtr was received and processed.
danilchap80ac24d2016-10-31 08:40:47 -0700776 ReceiveTimeInfo rrtime;
danilchap1e714ae2016-09-05 09:57:22 -0700777 EXPECT_TRUE(rtcp_receiver_.LastReceivedXrReferenceTimeInfo(&rrtime));
778 // Validate Dlrr report wasn't processed.
779 int64_t rtt_ms = 0;
780 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org38599512013-11-12 08:08:26 +0000781}
782
danilchap1e714ae2016-09-05 09:57:22 -0700783TEST_F(RtcpReceiverTest, TestExtendedReportsRrRttInitiallyFalse) {
784 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
785
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000786 int64_t rtt_ms;
danilchap1e714ae2016-09-05 09:57:22 -0700787 EXPECT_FALSE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000788}
789
danilchap1e714ae2016-09-05 09:57:22 -0700790TEST_F(RtcpReceiverTest, RttCalculatedAfterExtendedReportsDlrr) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100791 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100792 const int64_t kRttMs = rand.Rand(1, 9 * 3600 * 1000);
793 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
794 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
danilchap1e714ae2016-09-05 09:57:22 -0700795 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
danilchap37953762017-02-09 11:15:25 -0800796 NtpTime now = system_clock_.CurrentNtpTime();
Danil Chapovalova094fd12016-02-22 18:59:36 +0100797 uint32_t sent_ntp = CompactNtp(now);
798 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
799
Danil Chapovalova094fd12016-02-22 18:59:36 +0100800 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700801 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700802 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700803
804 InjectRtcpPacket(xr);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100805
806 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700807 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalova094fd12016-02-22 18:59:36 +0100808 EXPECT_NEAR(kRttMs, rtt_ms, 1);
809}
810
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100811TEST_F(RtcpReceiverTest, XrDlrrCalculatesNegativeRttAsOne) {
812 Random rand(0x0123456789abcdef);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100813 const int64_t kRttMs = rand.Rand(-3600 * 1000, -1);
814 const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
815 const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
danilchap37953762017-02-09 11:15:25 -0800816 NtpTime now = system_clock_.CurrentNtpTime();
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100817 uint32_t sent_ntp = CompactNtp(now);
818 system_clock_.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
danilchap1e714ae2016-09-05 09:57:22 -0700819 rtcp_receiver_.SetRtcpXrRrtrStatus(true);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100820
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100821 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700822 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700823 xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
danilchap1e714ae2016-09-05 09:57:22 -0700824
825 InjectRtcpPacket(xr);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100826
827 int64_t rtt_ms = 0;
danilchap1e714ae2016-09-05 09:57:22 -0700828 EXPECT_TRUE(rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms));
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100829 EXPECT_EQ(1, rtt_ms);
830}
831
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000832TEST_F(RtcpReceiverTest, LastReceivedXrReferenceTimeInfoInitiallyFalse) {
danilchap80ac24d2016-10-31 08:40:47 -0700833 ReceiveTimeInfo info;
danilchap1e714ae2016-09-05 09:57:22 -0700834 EXPECT_FALSE(rtcp_receiver_.LastReceivedXrReferenceTimeInfo(&info));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000835}
836
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100837TEST_F(RtcpReceiverTest, GetLastReceivedExtendedReportsReferenceTimeInfo) {
Danil Chapovalovfc47ed62015-12-07 14:46:35 +0100838 const NtpTime kNtp(0x10203, 0x40506);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100839 const uint32_t kNtpMid = CompactNtp(kNtp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000840
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000841 rtcp::Rrtr rrtr;
danilchap822a16f2016-09-27 09:27:47 -0700842 rrtr.SetNtp(kNtp);
Danil Chapovalov256e5b22016-01-15 14:16:24 +0100843 rtcp::ExtendedReports xr;
danilchap822a16f2016-09-27 09:27:47 -0700844 xr.SetSenderSsrc(kSenderSsrc);
danilchap80ac24d2016-10-31 08:40:47 -0700845 xr.SetRrtr(rrtr);
danilchap1e714ae2016-09-05 09:57:22 -0700846
847 InjectRtcpPacket(xr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000848
danilchap80ac24d2016-10-31 08:40:47 -0700849 ReceiveTimeInfo info;
danilchap1e714ae2016-09-05 09:57:22 -0700850 EXPECT_TRUE(rtcp_receiver_.LastReceivedXrReferenceTimeInfo(&info));
danilchap798896a2016-09-28 02:54:25 -0700851 EXPECT_EQ(kSenderSsrc, info.ssrc);
852 EXPECT_EQ(kNtpMid, info.last_rr);
853 EXPECT_EQ(0U, info.delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000854
855 system_clock_.AdvanceTimeMilliseconds(1000);
danilchap1e714ae2016-09-05 09:57:22 -0700856 EXPECT_TRUE(rtcp_receiver_.LastReceivedXrReferenceTimeInfo(&info));
danilchap798896a2016-09-28 02:54:25 -0700857 EXPECT_EQ(65536U, info.delay_since_last_rr);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000858}
859
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000860TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000861 const int64_t kRtcpIntervalMs = 1000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000862 const uint16_t kSequenceNumber = 1234;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000863 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000864
865 // No RR received, shouldn't trigger a timeout.
danilchap1e714ae2016-09-05 09:57:22 -0700866 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
867 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000868
869 // Add a RR and advance the clock just enough to not trigger a timeout.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000870 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -0700871 rb1.SetMediaSsrc(kReceiverMainSsrc);
872 rb1.SetExtHighestSeqNum(kSequenceNumber);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000873 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -0700874 rr1.SetSenderSsrc(kSenderSsrc);
875 rr1.AddReportBlock(rb1);
danilchap1e714ae2016-09-05 09:57:22 -0700876
877 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
878 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
879 InjectRtcpPacket(rr1);
880
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000881 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs - 1);
danilchap1e714ae2016-09-05 09:57:22 -0700882 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
883 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000884
885 // Add a RR with the same extended max as the previous RR to trigger a
886 // sequence number timeout, but not a RR timeout.
danilchap1e714ae2016-09-05 09:57:22 -0700887 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
888 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
889 InjectRtcpPacket(rr1);
890
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000891 system_clock_.AdvanceTimeMilliseconds(2);
danilchap1e714ae2016-09-05 09:57:22 -0700892 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
893 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000894
895 // Advance clock enough to trigger an RR timeout too.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000896 system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -0700897 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000898
899 // We should only get one timeout even though we still haven't received a new
900 // RR.
danilchap1e714ae2016-09-05 09:57:22 -0700901 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
902 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000903
904 // Add a new RR with increase sequence number to reset timers.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000905 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -0700906 rb2.SetMediaSsrc(kReceiverMainSsrc);
907 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000908 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -0700909 rr2.SetSenderSsrc(kSenderSsrc);
910 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -0700911
912 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
913 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
914 InjectRtcpPacket(rr2);
915
916 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
917 EXPECT_FALSE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000918
919 // Verify we can get a timeout again once we've received new RR.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000920 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -0700921 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
922 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
923 InjectRtcpPacket(rr2);
924
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000925 system_clock_.AdvanceTimeMilliseconds(kRtcpIntervalMs + 1);
danilchap1e714ae2016-09-05 09:57:22 -0700926 EXPECT_FALSE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
927 EXPECT_TRUE(rtcp_receiver_.RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
928
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000929 system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
danilchap1e714ae2016-09-05 09:57:22 -0700930 EXPECT_TRUE(rtcp_receiver_.RtcpRrTimeout(kRtcpIntervalMs));
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000931}
932
hta@webrtc.org47059b52012-05-02 07:46:22 +0000933TEST_F(RtcpReceiverTest, TmmbrReceivedWithNoIncomingPacket) {
danilchap1e714ae2016-09-05 09:57:22 -0700934 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +0000935}
936
937TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) {
danilchap1e714ae2016-09-05 09:57:22 -0700938 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000939 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -0700940 tmmbr.SetSenderSsrc(kSenderSsrc);
941 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000942 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700943 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -0700944 rtcp::CompoundPacket compound;
945 compound.Append(&sr);
946 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000947
danilchap1e714ae2016-09-05 09:57:22 -0700948 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
949 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(SizeIs(1)));
950 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
951 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
952 InjectRtcpPacket(compound);
953
954 std::vector<rtcp::TmmbItem> tmmbr_received = rtcp_receiver_.TmmbrReceived();
955 ASSERT_EQ(1u, tmmbr_received.size());
956 EXPECT_EQ(kBitrateBps, tmmbr_received[0].bitrate_bps());
957 EXPECT_EQ(kSenderSsrc, tmmbr_received[0].ssrc());
hta@webrtc.org47059b52012-05-02 07:46:22 +0000958}
959
960TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) {
danilchap1e714ae2016-09-05 09:57:22 -0700961 const uint32_t kBitrateBps = 30000;
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000962 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -0700963 tmmbr.SetSenderSsrc(kSenderSsrc);
964 tmmbr.AddTmmbr(rtcp::TmmbItem(kNotToUsSsrc, kBitrateBps, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000965
966 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700967 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -0700968 rtcp::CompoundPacket compound;
969 compound.Append(&sr);
970 compound.Append(&tmmbr);
hta@webrtc.org404843e2012-05-02 09:56:45 +0000971
danilchap1e714ae2016-09-05 09:57:22 -0700972 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
973 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
974 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
975 InjectRtcpPacket(compound);
976
977 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +0000978}
979
980TEST_F(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000981 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -0700982 tmmbr.SetSenderSsrc(kSenderSsrc);
983 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 0, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000984 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -0700985 sr.SetSenderSsrc(kSenderSsrc);
danilchap7a4116a2016-03-14 08:19:28 -0700986 rtcp::CompoundPacket compound;
987 compound.Append(&sr);
988 compound.Append(&tmmbr);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000989
danilchap1e714ae2016-09-05 09:57:22 -0700990 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
991 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
992 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_)).Times(0);
993 InjectRtcpPacket(compound);
994
995 EXPECT_EQ(0u, rtcp_receiver_.TmmbrReceived().size());
hta@webrtc.org47059b52012-05-02 07:46:22 +0000996}
997
hta@webrtc.org404843e2012-05-02 09:56:45 +0000998TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +0000999 // Inject 3 packets "from" kSenderSsrc, kSenderSsrc+1, kSenderSsrc+2.
hta@webrtc.org404843e2012-05-02 09:56:45 +00001000 // The times of arrival are starttime + 0, starttime + 5 and starttime + 10.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001001 for (uint32_t ssrc = kSenderSsrc; ssrc < kSenderSsrc + 3; ++ssrc) {
1002 rtcp::Tmmbr tmmbr;
danilchap822a16f2016-09-27 09:27:47 -07001003 tmmbr.SetSenderSsrc(ssrc);
1004 tmmbr.AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 30000, 0));
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001005 rtcp::SenderReport sr;
danilchap822a16f2016-09-27 09:27:47 -07001006 sr.SetSenderSsrc(ssrc);
danilchap7a4116a2016-03-14 08:19:28 -07001007 rtcp::CompoundPacket compound;
1008 compound.Append(&sr);
1009 compound.Append(&tmmbr);
danilchap1e714ae2016-09-05 09:57:22 -07001010
1011 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1012 EXPECT_CALL(rtp_rtcp_impl_, SetTmmbn(_));
1013 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1014 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(_));
1015 InjectRtcpPacket(compound);
1016
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001017 // 5 seconds between each packet.
1018 system_clock_.AdvanceTimeMilliseconds(5000);
hta@webrtc.org404843e2012-05-02 09:56:45 +00001019 }
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001020 // It is now starttime + 15.
danilchap1e714ae2016-09-05 09:57:22 -07001021 std::vector<rtcp::TmmbItem> candidate_set = rtcp_receiver_.TmmbrReceived();
1022 ASSERT_EQ(3u, candidate_set.size());
1023 EXPECT_EQ(30000U, candidate_set[0].bitrate_bps());
1024
hta@webrtc.org404843e2012-05-02 09:56:45 +00001025 // We expect the timeout to be 25 seconds. Advance the clock by 12
1026 // seconds, timing out the first packet.
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001027 system_clock_.AdvanceTimeMilliseconds(12000);
danilchap1e714ae2016-09-05 09:57:22 -07001028 candidate_set = rtcp_receiver_.TmmbrReceived();
1029 ASSERT_EQ(2u, candidate_set.size());
danilchap287e5482016-08-16 15:15:39 -07001030 EXPECT_EQ(kSenderSsrc + 1, candidate_set[0].ssrc());
hta@webrtc.org404843e2012-05-02 09:56:45 +00001031}
1032
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001033TEST_F(RtcpReceiverTest, Callbacks) {
danilchap1e714ae2016-09-05 09:57:22 -07001034 MockRtcpCallbackImpl callback;
1035 rtcp_receiver_.RegisterRtcpStatisticsCallback(&callback);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001036
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001037 const uint8_t kFractionLoss = 3;
1038 const uint32_t kCumulativeLoss = 7;
1039 const uint32_t kJitter = 9;
1040 const uint16_t kSequenceNumber = 1234;
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001041
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001042 // First packet, all numbers should just propagate.
1043 rtcp::ReportBlock rb1;
danilchap822a16f2016-09-27 09:27:47 -07001044 rb1.SetMediaSsrc(kReceiverMainSsrc);
1045 rb1.SetExtHighestSeqNum(kSequenceNumber);
1046 rb1.SetFractionLost(kFractionLoss);
1047 rb1.SetCumulativeLost(kCumulativeLoss);
1048 rb1.SetJitter(kJitter);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001049
1050 rtcp::ReceiverReport rr1;
danilchap822a16f2016-09-27 09:27:47 -07001051 rr1.SetSenderSsrc(kSenderSsrc);
1052 rr1.AddReportBlock(rb1);
srte186d9c32017-08-04 05:03:53 -07001053 EXPECT_CALL(callback,
1054 StatisticsUpdated(
1055 AllOf(Field(&RtcpStatistics::fraction_lost, kFractionLoss),
1056 Field(&RtcpStatistics::packets_lost, kCumulativeLoss),
1057 Field(&RtcpStatistics::extended_highest_sequence_number,
1058 kSequenceNumber),
1059 Field(&RtcpStatistics::jitter, kJitter)),
1060 kReceiverMainSsrc));
danilchap1e714ae2016-09-05 09:57:22 -07001061 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1062 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1063 InjectRtcpPacket(rr1);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001064
danilchap1e714ae2016-09-05 09:57:22 -07001065 rtcp_receiver_.RegisterRtcpStatisticsCallback(nullptr);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001066
danilchap1e714ae2016-09-05 09:57:22 -07001067 // Add arbitrary numbers, callback should not be called.
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001068 rtcp::ReportBlock rb2;
danilchap822a16f2016-09-27 09:27:47 -07001069 rb2.SetMediaSsrc(kReceiverMainSsrc);
1070 rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
1071 rb2.SetFractionLost(42);
1072 rb2.SetCumulativeLost(137);
1073 rb2.SetJitter(4711);
asapersson@webrtc.orge75d78d2014-07-29 08:21:50 +00001074
1075 rtcp::ReceiverReport rr2;
danilchap822a16f2016-09-27 09:27:47 -07001076 rr2.SetSenderSsrc(kSenderSsrc);
1077 rr2.AddReportBlock(rb2);
danilchap1e714ae2016-09-05 09:57:22 -07001078
1079 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedRtcpReportBlocks(_));
1080 EXPECT_CALL(bandwidth_observer_, OnReceivedRtcpReceiverReport(_, _, _));
1081 EXPECT_CALL(callback, StatisticsUpdated(_, _)).Times(0);
1082 InjectRtcpPacket(rr2);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001083}
hta@webrtc.org404843e2012-05-02 09:56:45 +00001084
sprang49f9cdb2015-10-01 03:06:57 -07001085TEST_F(RtcpReceiverTest, ReceivesTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001086 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001087 packet.SetMediaSsrc(kReceiverMainSsrc);
1088 packet.SetSenderSsrc(kSenderSsrc);
1089 packet.SetBase(1, 1000);
1090 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001091
danilchap1e714ae2016-09-05 09:57:22 -07001092 EXPECT_CALL(
1093 transport_feedback_observer_,
1094 OnTransportFeedback(AllOf(
1095 Property(&rtcp::TransportFeedback::media_ssrc, kReceiverMainSsrc),
1096 Property(&rtcp::TransportFeedback::sender_ssrc, kSenderSsrc))));
1097 InjectRtcpPacket(packet);
sprang49f9cdb2015-10-01 03:06:57 -07001098}
1099
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001100TEST_F(RtcpReceiverTest, ReceivesRemb) {
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001101 const uint32_t kBitrateBps = 500000;
1102 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001103 remb.SetSenderSsrc(kSenderSsrc);
1104 remb.SetBitrateBps(kBitrateBps);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001105
danilchap1e714ae2016-09-05 09:57:22 -07001106 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1107 InjectRtcpPacket(remb);
Danil Chapovalovee6e4272016-04-19 12:15:10 +02001108}
1109
sprang49f9cdb2015-10-01 03:06:57 -07001110TEST_F(RtcpReceiverTest, HandlesInvalidTransportFeedback) {
sprang49f9cdb2015-10-01 03:06:57 -07001111 // Send a compound packet with a TransportFeedback followed by something else.
1112 rtcp::TransportFeedback packet;
danilchap822a16f2016-09-27 09:27:47 -07001113 packet.SetMediaSsrc(kReceiverMainSsrc);
1114 packet.SetSenderSsrc(kSenderSsrc);
1115 packet.SetBase(1, 1000);
1116 packet.AddReceivedPacket(1, 1000);
sprang49f9cdb2015-10-01 03:06:57 -07001117
1118 static uint32_t kBitrateBps = 50000;
1119 rtcp::Remb remb;
danilchap822a16f2016-09-27 09:27:47 -07001120 remb.SetSenderSsrc(kSenderSsrc);
1121 remb.SetBitrateBps(kBitrateBps);
danilchap7a4116a2016-03-14 08:19:28 -07001122 rtcp::CompoundPacket compound;
1123 compound.Append(&packet);
1124 compound.Append(&remb);
1125 rtc::Buffer built_packet = compound.Build();
sprang49f9cdb2015-10-01 03:06:57 -07001126
1127 // Modify the TransportFeedback packet so that it is invalid.
1128 const size_t kStatusCountOffset = 14;
1129 ByteWriter<uint16_t>::WriteBigEndian(
danilchap69e59e62016-02-17 03:11:42 -08001130 &built_packet.data()[kStatusCountOffset], 42);
sprang49f9cdb2015-10-01 03:06:57 -07001131
danilchap1e714ae2016-09-05 09:57:22 -07001132 // Stress no transport feedback is expected.
1133 EXPECT_CALL(transport_feedback_observer_, OnTransportFeedback(_)).Times(0);
1134 // But remb should be processed and cause a callback
1135 EXPECT_CALL(bandwidth_observer_, OnReceivedEstimatedBitrate(kBitrateBps));
1136 InjectRtcpPacket(built_packet);
sprang49f9cdb2015-10-01 03:06:57 -07001137}
1138
danilchap1e714ae2016-09-05 09:57:22 -07001139TEST_F(RtcpReceiverTest, Nack) {
1140 const uint16_t kNackList1[] = {1, 2, 3, 5};
danilchap142f0192016-10-20 08:22:42 -07001141 const uint16_t kNackList23[] = {5, 7, 30, 40, 41, 58, 59, 61, 63};
1142 const size_t kNackListLength2 = 4;
1143 const size_t kNackListLength3 = arraysize(kNackList23) - kNackListLength2;
danilchap1e714ae2016-09-05 09:57:22 -07001144 std::set<uint16_t> nack_set;
1145 nack_set.insert(std::begin(kNackList1), std::end(kNackList1));
danilchap142f0192016-10-20 08:22:42 -07001146 nack_set.insert(std::begin(kNackList23), std::end(kNackList23));
danilchap1e714ae2016-09-05 09:57:22 -07001147
danilchap142f0192016-10-20 08:22:42 -07001148 rtcp::Nack nack1;
1149 nack1.SetSenderSsrc(kSenderSsrc);
1150 nack1.SetMediaSsrc(kReceiverMainSsrc);
1151 nack1.SetPacketIds(kNackList1, arraysize(kNackList1));
danilchap1e714ae2016-09-05 09:57:22 -07001152
1153 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList1)));
danilchap1e714ae2016-09-05 09:57:22 -07001154 EXPECT_CALL(packet_type_counter_observer_,
1155 RtcpPacketTypesCounterUpdated(
1156 kReceiverMainSsrc,
1157 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
danilchap142f0192016-10-20 08:22:42 -07001158 arraysize(kNackList1)),
1159 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1160 arraysize(kNackList1)))));
1161 InjectRtcpPacket(nack1);
1162
1163 rtcp::Nack nack2;
1164 nack2.SetSenderSsrc(kSenderSsrc);
1165 nack2.SetMediaSsrc(kReceiverMainSsrc);
1166 nack2.SetPacketIds(kNackList23, kNackListLength2);
1167
1168 rtcp::Nack nack3;
1169 nack3.SetSenderSsrc(kSenderSsrc);
1170 nack3.SetMediaSsrc(kReceiverMainSsrc);
1171 nack3.SetPacketIds(kNackList23 + kNackListLength2, kNackListLength3);
1172
1173 rtcp::CompoundPacket two_nacks;
1174 two_nacks.Append(&nack2);
1175 two_nacks.Append(&nack3);
1176
1177 EXPECT_CALL(rtp_rtcp_impl_, OnReceivedNack(ElementsAreArray(kNackList23)));
1178 EXPECT_CALL(packet_type_counter_observer_,
1179 RtcpPacketTypesCounterUpdated(
1180 kReceiverMainSsrc,
1181 AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
1182 arraysize(kNackList1) + arraysize(kNackList23)),
danilchap1e714ae2016-09-05 09:57:22 -07001183 Field(&RtcpPacketTypeCounter::unique_nack_requests,
1184 nack_set.size()))));
danilchap142f0192016-10-20 08:22:42 -07001185 InjectRtcpPacket(two_nacks);
danilchap1e714ae2016-09-05 09:57:22 -07001186}
1187
1188TEST_F(RtcpReceiverTest, NackNotForUsIgnored) {
1189 const uint16_t kNackList1[] = {1, 2, 3, 5};
1190 const size_t kNackListLength1 = std::end(kNackList1) - std::begin(kNackList1);
1191
1192 rtcp::Nack nack;
danilchap822a16f2016-09-27 09:27:47 -07001193 nack.SetSenderSsrc(kSenderSsrc);
1194 nack.SetMediaSsrc(kNotToUsSsrc);
1195 nack.SetPacketIds(kNackList1, kNackListLength1);
danilchap1e714ae2016-09-05 09:57:22 -07001196
1197 EXPECT_CALL(packet_type_counter_observer_,
1198 RtcpPacketTypesCounterUpdated(
1199 _, Field(&RtcpPacketTypeCounter::nack_requests, 0)));
1200 InjectRtcpPacket(nack);
1201}
1202
1203TEST_F(RtcpReceiverTest, ForceSenderReport) {
1204 rtcp::RapidResyncRequest rr;
danilchap822a16f2016-09-27 09:27:47 -07001205 rr.SetSenderSsrc(kSenderSsrc);
1206 rr.SetMediaSsrc(kReceiverMainSsrc);
danilchap1e714ae2016-09-05 09:57:22 -07001207
1208 EXPECT_CALL(rtp_rtcp_impl_, OnRequestSendReport());
1209 InjectRtcpPacket(rr);
1210}
hta@webrtc.org47059b52012-05-02 07:46:22 +00001211
spranga790d832016-12-02 07:29:44 -08001212TEST_F(RtcpReceiverTest, ReceivesTargetBitrate) {
1213 BitrateAllocation expected_allocation;
1214 expected_allocation.SetBitrate(0, 0, 10000);
1215 expected_allocation.SetBitrate(0, 1, 20000);
1216 expected_allocation.SetBitrate(1, 0, 40000);
1217 expected_allocation.SetBitrate(1, 1, 80000);
1218
1219 rtcp::TargetBitrate bitrate;
1220 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1221 bitrate.AddTargetBitrate(0, 1, expected_allocation.GetBitrate(0, 1) / 1000);
1222 bitrate.AddTargetBitrate(1, 0, expected_allocation.GetBitrate(1, 0) / 1000);
1223 bitrate.AddTargetBitrate(1, 1, expected_allocation.GetBitrate(1, 1) / 1000);
1224
1225 rtcp::ExtendedReports xr;
1226 xr.SetTargetBitrate(bitrate);
1227
sprangb32aaf92017-08-28 05:49:12 -07001228 // Wrong sender ssrc, target bitrate should be discarded.
1229 xr.SetSenderSsrc(kSenderSsrc + 1);
1230 EXPECT_CALL(bitrate_allocation_observer_,
1231 OnBitrateAllocationUpdated(expected_allocation))
1232 .Times(0);
1233 InjectRtcpPacket(xr);
1234
1235 // Set correct ssrc, callback should be called once.
1236 xr.SetSenderSsrc(kSenderSsrc);
spranga790d832016-12-02 07:29:44 -08001237 EXPECT_CALL(bitrate_allocation_observer_,
1238 OnBitrateAllocationUpdated(expected_allocation));
1239 InjectRtcpPacket(xr);
1240}
1241
sprang6d314c72016-12-06 06:08:53 -08001242TEST_F(RtcpReceiverTest, HandlesIncorrectTargetBitrate) {
1243 BitrateAllocation expected_allocation;
1244 expected_allocation.SetBitrate(0, 0, 10000);
1245
1246 rtcp::TargetBitrate bitrate;
1247 bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
1248 bitrate.AddTargetBitrate(0, kMaxTemporalStreams, 20000);
1249 bitrate.AddTargetBitrate(kMaxSpatialLayers, 0, 40000);
1250
1251 rtcp::ExtendedReports xr;
1252 xr.SetTargetBitrate(bitrate);
sprangb32aaf92017-08-28 05:49:12 -07001253 xr.SetSenderSsrc(kSenderSsrc);
sprang6d314c72016-12-06 06:08:53 -08001254
1255 EXPECT_CALL(bitrate_allocation_observer_,
1256 OnBitrateAllocationUpdated(expected_allocation));
1257 InjectRtcpPacket(xr);
1258}
1259
hta@webrtc.org47059b52012-05-02 07:46:22 +00001260} // namespace webrtc