blob: d40a7434691cbef1be76310e35415e8c998c3449 [file] [log] [blame]
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +00001/*
2 * Copyright (c) 2013 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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "modules/rtp_rtcp/include/receive_statistics.h"
12
kwiberg84be5112016-04-27 01:19:58 -070013#include <memory>
Danil Chapovalovd1996b72018-01-16 11:07:18 +010014#include <vector>
kwiberg84be5112016-04-27 01:19:58 -070015
Niels Möller1f3206c2018-09-14 08:26:32 +020016#include "modules/rtp_rtcp/source/rtp_packet_received.h"
17#include "rtc_base/random.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "system_wrappers/include/clock.h"
19#include "test/gmock.h"
20#include "test/gtest.h"
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000021
22namespace webrtc {
Danil Chapovalovd1996b72018-01-16 11:07:18 +010023namespace {
24
25using ::testing::SizeIs;
26using ::testing::UnorderedElementsAre;
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000027
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000028const size_t kPacketSize1 = 100;
29const size_t kPacketSize2 = 300;
Danil Chapovalovd1996b72018-01-16 11:07:18 +010030const uint32_t kSsrc1 = 101;
31const uint32_t kSsrc2 = 202;
32const uint32_t kSsrc3 = 203;
33const uint32_t kSsrc4 = 304;
34
Niels Möller1f3206c2018-09-14 08:26:32 +020035RtpPacketReceived CreateRtpPacket(uint32_t ssrc,
36 size_t header_size,
37 size_t payload_size,
38 size_t padding_size) {
39 RtpPacketReceived packet;
40 packet.SetSsrc(ssrc);
41 packet.SetSequenceNumber(100);
42 packet.set_payload_type_frequency(90000);
43 RTC_CHECK_GE(header_size, 12);
44 RTC_CHECK_EQ(header_size % 4, 0);
45 if (header_size > 12) {
46 // Insert csrcs to increase header size.
47 const int num_csrcs = (header_size - 12) / 4;
48 std::vector<uint32_t> csrcs(num_csrcs);
49 packet.SetCsrcs(csrcs);
50 }
51 packet.SetPayloadSize(payload_size);
Danil Chapovalovf7fcaf02018-10-10 14:56:01 +020052 packet.SetPadding(padding_size);
Niels Möller1f3206c2018-09-14 08:26:32 +020053 return packet;
54}
55
56RtpPacketReceived CreateRtpPacket(uint32_t ssrc, size_t packet_size) {
57 return CreateRtpPacket(ssrc, 12, packet_size - 12, 0);
58}
59
60void IncrementSequenceNumber(RtpPacketReceived* packet, uint16_t incr) {
61 packet->SetSequenceNumber(packet->SequenceNumber() + incr);
62}
63
64void IncrementSequenceNumber(RtpPacketReceived* packet) {
65 IncrementSequenceNumber(packet, 1);
66}
67
Per Kjellanderee8cd202021-03-10 12:31:38 +010068class ReceiveStatisticsTest : public ::testing::TestWithParam<bool> {
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000069 public:
Yves Gerey665174f2018-06-19 15:03:05 +020070 ReceiveStatisticsTest()
Per Kjellanderee8cd202021-03-10 12:31:38 +010071 : clock_(0),
72 receive_statistics_(
73 GetParam() ? ReceiveStatistics::Create(&clock_)
74 : ReceiveStatistics::CreateThreadCompatible(&clock_)) {
Niels Möller1f3206c2018-09-14 08:26:32 +020075 packet1_ = CreateRtpPacket(kSsrc1, kPacketSize1);
76 packet2_ = CreateRtpPacket(kSsrc2, kPacketSize2);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000077 }
78
79 protected:
80 SimulatedClock clock_;
kwiberg84be5112016-04-27 01:19:58 -070081 std::unique_ptr<ReceiveStatistics> receive_statistics_;
Niels Möller1f3206c2018-09-14 08:26:32 +020082 RtpPacketReceived packet1_;
83 RtpPacketReceived packet2_;
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000084};
85
Per Kjellanderee8cd202021-03-10 12:31:38 +010086INSTANTIATE_TEST_SUITE_P(All,
87 ReceiveStatisticsTest,
88 ::testing::Bool(),
89 [](::testing::TestParamInfo<bool> info) {
90 return info.param ? "WithMutex" : "WithoutMutex";
91 });
92
93TEST_P(ReceiveStatisticsTest, TwoIncomingSsrcs) {
Niels Möller1f3206c2018-09-14 08:26:32 +020094 receive_statistics_->OnRtpPacket(packet1_);
95 IncrementSequenceNumber(&packet1_);
96 receive_statistics_->OnRtpPacket(packet2_);
97 IncrementSequenceNumber(&packet2_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000098 clock_.AdvanceTimeMilliseconds(100);
Niels Möller1f3206c2018-09-14 08:26:32 +020099 receive_statistics_->OnRtpPacket(packet1_);
100 IncrementSequenceNumber(&packet1_);
101 receive_statistics_->OnRtpPacket(packet2_);
102 IncrementSequenceNumber(&packet2_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000103
104 StreamStatistician* statistician =
105 receive_statistics_->GetStatistician(kSsrc1);
106 ASSERT_TRUE(statistician != NULL);
107 EXPECT_GT(statistician->BitrateReceived(), 0u);
Niels Möller01525f92019-08-12 15:12:20 +0200108 StreamDataCounters counters = statistician->GetReceiveStreamDataCounters();
109 EXPECT_EQ(176u, counters.transmitted.payload_bytes);
110 EXPECT_EQ(24u, counters.transmitted.header_bytes);
111 EXPECT_EQ(0u, counters.transmitted.padding_bytes);
112 EXPECT_EQ(2u, counters.transmitted.packets);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000113
Yves Gerey665174f2018-06-19 15:03:05 +0200114 statistician = receive_statistics_->GetStatistician(kSsrc2);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000115 ASSERT_TRUE(statistician != NULL);
116 EXPECT_GT(statistician->BitrateReceived(), 0u);
Niels Möller01525f92019-08-12 15:12:20 +0200117 counters = statistician->GetReceiveStreamDataCounters();
118 EXPECT_EQ(576u, counters.transmitted.payload_bytes);
119 EXPECT_EQ(24u, counters.transmitted.header_bytes);
120 EXPECT_EQ(0u, counters.transmitted.padding_bytes);
121 EXPECT_EQ(2u, counters.transmitted.packets);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000122
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200123 EXPECT_EQ(2u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000124 // Add more incoming packets and verify that they are registered in both
125 // access methods.
Niels Möller1f3206c2018-09-14 08:26:32 +0200126 receive_statistics_->OnRtpPacket(packet1_);
127 IncrementSequenceNumber(&packet1_);
128 receive_statistics_->OnRtpPacket(packet2_);
129 IncrementSequenceNumber(&packet2_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000130
Niels Möller01525f92019-08-12 15:12:20 +0200131 counters = receive_statistics_->GetStatistician(kSsrc1)
132 ->GetReceiveStreamDataCounters();
133 EXPECT_EQ(264u, counters.transmitted.payload_bytes);
134 EXPECT_EQ(36u, counters.transmitted.header_bytes);
135 EXPECT_EQ(0u, counters.transmitted.padding_bytes);
136 EXPECT_EQ(3u, counters.transmitted.packets);
137
138 counters = receive_statistics_->GetStatistician(kSsrc2)
139 ->GetReceiveStreamDataCounters();
140 EXPECT_EQ(864u, counters.transmitted.payload_bytes);
141 EXPECT_EQ(36u, counters.transmitted.header_bytes);
142 EXPECT_EQ(0u, counters.transmitted.padding_bytes);
143 EXPECT_EQ(3u, counters.transmitted.packets);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000144}
145
Per Kjellanderee8cd202021-03-10 12:31:38 +0100146TEST_P(ReceiveStatisticsTest,
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100147 RtcpReportBlocksReturnsMaxBlocksWhenThereAreMoreStatisticians) {
Niels Möller1f3206c2018-09-14 08:26:32 +0200148 RtpPacketReceived packet1 = CreateRtpPacket(kSsrc1, kPacketSize1);
149 RtpPacketReceived packet2 = CreateRtpPacket(kSsrc2, kPacketSize1);
150 RtpPacketReceived packet3 = CreateRtpPacket(kSsrc3, kPacketSize1);
151 receive_statistics_->OnRtpPacket(packet1);
152 receive_statistics_->OnRtpPacket(packet2);
153 receive_statistics_->OnRtpPacket(packet3);
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100154
155 EXPECT_THAT(receive_statistics_->RtcpReportBlocks(2), SizeIs(2));
156 EXPECT_THAT(receive_statistics_->RtcpReportBlocks(2), SizeIs(2));
157 EXPECT_THAT(receive_statistics_->RtcpReportBlocks(2), SizeIs(2));
158}
159
Per Kjellanderee8cd202021-03-10 12:31:38 +0100160TEST_P(ReceiveStatisticsTest,
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100161 RtcpReportBlocksReturnsAllObservedSsrcsWithMultipleCalls) {
Niels Möller1f3206c2018-09-14 08:26:32 +0200162 RtpPacketReceived packet1 = CreateRtpPacket(kSsrc1, kPacketSize1);
163 RtpPacketReceived packet2 = CreateRtpPacket(kSsrc2, kPacketSize1);
164 RtpPacketReceived packet3 = CreateRtpPacket(kSsrc3, kPacketSize1);
165 RtpPacketReceived packet4 = CreateRtpPacket(kSsrc4, kPacketSize1);
166 receive_statistics_->OnRtpPacket(packet1);
167 receive_statistics_->OnRtpPacket(packet2);
168 receive_statistics_->OnRtpPacket(packet3);
169 receive_statistics_->OnRtpPacket(packet4);
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100170
171 std::vector<uint32_t> observed_ssrcs;
172 std::vector<rtcp::ReportBlock> report_blocks =
173 receive_statistics_->RtcpReportBlocks(2);
174 ASSERT_THAT(report_blocks, SizeIs(2));
175 observed_ssrcs.push_back(report_blocks[0].source_ssrc());
176 observed_ssrcs.push_back(report_blocks[1].source_ssrc());
177
178 report_blocks = receive_statistics_->RtcpReportBlocks(2);
179 ASSERT_THAT(report_blocks, SizeIs(2));
180 observed_ssrcs.push_back(report_blocks[0].source_ssrc());
181 observed_ssrcs.push_back(report_blocks[1].source_ssrc());
182
183 EXPECT_THAT(observed_ssrcs,
184 UnorderedElementsAre(kSsrc1, kSsrc2, kSsrc3, kSsrc4));
185}
186
Per Kjellanderee8cd202021-03-10 12:31:38 +0100187TEST_P(ReceiveStatisticsTest, ActiveStatisticians) {
Niels Möller1f3206c2018-09-14 08:26:32 +0200188 receive_statistics_->OnRtpPacket(packet1_);
189 IncrementSequenceNumber(&packet1_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000190 clock_.AdvanceTimeMilliseconds(1000);
Niels Möller1f3206c2018-09-14 08:26:32 +0200191 receive_statistics_->OnRtpPacket(packet2_);
192 IncrementSequenceNumber(&packet2_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000193 // Nothing should time out since only 1000 ms has passed since the first
194 // packet came in.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200195 EXPECT_EQ(2u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000196
197 clock_.AdvanceTimeMilliseconds(7000);
198 // kSsrc1 should have timed out.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200199 EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000200
201 clock_.AdvanceTimeMilliseconds(1000);
202 // kSsrc2 should have timed out.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200203 EXPECT_EQ(0u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000204
Niels Möller1f3206c2018-09-14 08:26:32 +0200205 receive_statistics_->OnRtpPacket(packet1_);
206 IncrementSequenceNumber(&packet1_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000207 // kSsrc1 should be active again and the data counters should have survived.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200208 EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000209 StreamStatistician* statistician =
210 receive_statistics_->GetStatistician(kSsrc1);
211 ASSERT_TRUE(statistician != NULL);
Niels Möller01525f92019-08-12 15:12:20 +0200212 StreamDataCounters counters = statistician->GetReceiveStreamDataCounters();
213 EXPECT_EQ(176u, counters.transmitted.payload_bytes);
214 EXPECT_EQ(24u, counters.transmitted.header_bytes);
215 EXPECT_EQ(0u, counters.transmitted.padding_bytes);
216 EXPECT_EQ(2u, counters.transmitted.packets);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000217}
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000218
Per Kjellanderee8cd202021-03-10 12:31:38 +0100219TEST_P(ReceiveStatisticsTest,
Niels Möller5304a322018-08-27 13:27:05 +0200220 DoesntCreateRtcpReportBlockUntilFirstReceivedPacketForSsrc) {
221 // Creates a statistician object for the ssrc.
222 receive_statistics_->EnableRetransmitDetection(kSsrc1, true);
223 EXPECT_TRUE(receive_statistics_->GetStatistician(kSsrc1) != nullptr);
224 EXPECT_EQ(0u, receive_statistics_->RtcpReportBlocks(3).size());
225 // Receive first packet
Niels Möller1f3206c2018-09-14 08:26:32 +0200226 receive_statistics_->OnRtpPacket(packet1_);
Niels Möller5304a322018-08-27 13:27:05 +0200227 EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size());
228}
229
Per Kjellanderee8cd202021-03-10 12:31:38 +0100230TEST_P(ReceiveStatisticsTest, GetReceiveStreamDataCounters) {
Niels Möller1f3206c2018-09-14 08:26:32 +0200231 receive_statistics_->OnRtpPacket(packet1_);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000232 StreamStatistician* statistician =
233 receive_statistics_->GetStatistician(kSsrc1);
234 ASSERT_TRUE(statistician != NULL);
235
Niels Möller58b496b2019-08-12 12:16:31 +0200236 StreamDataCounters counters = statistician->GetReceiveStreamDataCounters();
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000237 EXPECT_GT(counters.first_packet_time_ms, -1);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000238 EXPECT_EQ(1u, counters.transmitted.packets);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000239
Niels Möller1f3206c2018-09-14 08:26:32 +0200240 receive_statistics_->OnRtpPacket(packet1_);
Niels Möller58b496b2019-08-12 12:16:31 +0200241 counters = statistician->GetReceiveStreamDataCounters();
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000242 EXPECT_GT(counters.first_packet_time_ms, -1);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000243 EXPECT_EQ(2u, counters.transmitted.packets);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000244}
245
Per Kjellanderee8cd202021-03-10 12:31:38 +0100246TEST_P(ReceiveStatisticsTest, SimpleLossComputation) {
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000247 packet1_.SetSequenceNumber(1);
248 receive_statistics_->OnRtpPacket(packet1_);
249 packet1_.SetSequenceNumber(3);
250 receive_statistics_->OnRtpPacket(packet1_);
251 packet1_.SetSequenceNumber(4);
252 receive_statistics_->OnRtpPacket(packet1_);
253 packet1_.SetSequenceNumber(5);
254 receive_statistics_->OnRtpPacket(packet1_);
255
Niels Möllerd77cc242019-08-22 09:40:25 +0200256 std::vector<rtcp::ReportBlock> report_blocks =
257 receive_statistics_->RtcpReportBlocks(1);
258 ASSERT_THAT(report_blocks, SizeIs(1));
259 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
260
261 // 20% = 51/255.
262 EXPECT_EQ(51u, report_blocks[0].fraction_lost());
263 EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed());
Niels Möller9a9f18a2019-08-02 13:52:37 +0200264 StreamStatistician* statistician =
265 receive_statistics_->GetStatistician(kSsrc1);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200266 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000267}
268
Per Kjellanderee8cd202021-03-10 12:31:38 +0100269TEST_P(ReceiveStatisticsTest, LossComputationWithReordering) {
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000270 packet1_.SetSequenceNumber(1);
271 receive_statistics_->OnRtpPacket(packet1_);
272 packet1_.SetSequenceNumber(3);
273 receive_statistics_->OnRtpPacket(packet1_);
274 packet1_.SetSequenceNumber(2);
275 receive_statistics_->OnRtpPacket(packet1_);
276 packet1_.SetSequenceNumber(5);
277 receive_statistics_->OnRtpPacket(packet1_);
278
Niels Möllerd77cc242019-08-22 09:40:25 +0200279 std::vector<rtcp::ReportBlock> report_blocks =
280 receive_statistics_->RtcpReportBlocks(1);
281 ASSERT_THAT(report_blocks, SizeIs(1));
282 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
283
284 // 20% = 51/255.
285 EXPECT_EQ(51u, report_blocks[0].fraction_lost());
286 EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed());
Niels Möller9a9f18a2019-08-02 13:52:37 +0200287 StreamStatistician* statistician =
288 receive_statistics_->GetStatistician(kSsrc1);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200289 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000290}
291
Per Kjellanderee8cd202021-03-10 12:31:38 +0100292TEST_P(ReceiveStatisticsTest, LossComputationWithDuplicates) {
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000293 // Lose 2 packets, but also receive 1 duplicate. Should actually count as
294 // only 1 packet being lost.
295 packet1_.SetSequenceNumber(1);
296 receive_statistics_->OnRtpPacket(packet1_);
297 packet1_.SetSequenceNumber(4);
298 receive_statistics_->OnRtpPacket(packet1_);
299 packet1_.SetSequenceNumber(4);
300 receive_statistics_->OnRtpPacket(packet1_);
301 packet1_.SetSequenceNumber(5);
302 receive_statistics_->OnRtpPacket(packet1_);
303
Niels Möllerd77cc242019-08-22 09:40:25 +0200304 std::vector<rtcp::ReportBlock> report_blocks =
305 receive_statistics_->RtcpReportBlocks(1);
306 ASSERT_THAT(report_blocks, SizeIs(1));
307 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
308
309 // 20% = 51/255.
310 EXPECT_EQ(51u, report_blocks[0].fraction_lost());
311 EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed());
Niels Möller9a9f18a2019-08-02 13:52:37 +0200312 StreamStatistician* statistician =
313 receive_statistics_->GetStatistician(kSsrc1);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200314 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000315}
316
Per Kjellanderee8cd202021-03-10 12:31:38 +0100317TEST_P(ReceiveStatisticsTest, LossComputationWithSequenceNumberWrapping) {
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000318 // First, test loss computation over a period that included a sequence number
319 // rollover.
320 packet1_.SetSequenceNumber(0xfffd);
321 receive_statistics_->OnRtpPacket(packet1_);
322 packet1_.SetSequenceNumber(0);
323 receive_statistics_->OnRtpPacket(packet1_);
324 packet1_.SetSequenceNumber(0xfffe);
325 receive_statistics_->OnRtpPacket(packet1_);
326 packet1_.SetSequenceNumber(1);
327 receive_statistics_->OnRtpPacket(packet1_);
328
329 // Only one packet was actually lost, 0xffff.
Niels Möllerd77cc242019-08-22 09:40:25 +0200330 std::vector<rtcp::ReportBlock> report_blocks =
331 receive_statistics_->RtcpReportBlocks(1);
332 ASSERT_THAT(report_blocks, SizeIs(1));
333 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
334
335 // 20% = 51/255.
336 EXPECT_EQ(51u, report_blocks[0].fraction_lost());
337 EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed());
Niels Möller9a9f18a2019-08-02 13:52:37 +0200338 StreamStatistician* statistician =
339 receive_statistics_->GetStatistician(kSsrc1);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200340 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000341
342 // Now test losing one packet *after* the rollover.
343 packet1_.SetSequenceNumber(3);
344 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd77cc242019-08-22 09:40:25 +0200345
346 report_blocks = receive_statistics_->RtcpReportBlocks(1);
347 ASSERT_THAT(report_blocks, SizeIs(1));
348 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
349
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000350 // 50% = 127/255.
Niels Möllerd77cc242019-08-22 09:40:25 +0200351 EXPECT_EQ(127u, report_blocks[0].fraction_lost());
352 EXPECT_EQ(2, report_blocks[0].cumulative_lost_signed());
Niels Möller9a9f18a2019-08-02 13:52:37 +0200353 // 2 packets lost, 7 expected
354 EXPECT_EQ(28, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000355}
356
Per Kjellanderee8cd202021-03-10 12:31:38 +0100357TEST_P(ReceiveStatisticsTest, StreamRestartDoesntCountAsLoss) {
Niels Möller87da1092019-05-24 14:04:28 +0200358 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000359
360 packet1_.SetSequenceNumber(0);
361 receive_statistics_->OnRtpPacket(packet1_);
362 packet1_.SetSequenceNumber(1);
363 receive_statistics_->OnRtpPacket(packet1_);
364
365 packet1_.SetSequenceNumber(400);
366 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd77cc242019-08-22 09:40:25 +0200367
368 std::vector<rtcp::ReportBlock> report_blocks =
369 receive_statistics_->RtcpReportBlocks(1);
370 ASSERT_THAT(report_blocks, SizeIs(1));
371 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
372
373 EXPECT_EQ(0, report_blocks[0].fraction_lost());
374 EXPECT_EQ(0, report_blocks[0].cumulative_lost_signed());
Niels Möller9a9f18a2019-08-02 13:52:37 +0200375 StreamStatistician* statistician =
376 receive_statistics_->GetStatistician(kSsrc1);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200377 EXPECT_EQ(0, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000378
379 packet1_.SetSequenceNumber(401);
380 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd77cc242019-08-22 09:40:25 +0200381 report_blocks = receive_statistics_->RtcpReportBlocks(1);
382 ASSERT_THAT(report_blocks, SizeIs(1));
383 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
384
385 EXPECT_EQ(0, report_blocks[0].fraction_lost());
386 EXPECT_EQ(0, report_blocks[0].cumulative_lost_signed());
Niels Möller9a9f18a2019-08-02 13:52:37 +0200387 EXPECT_EQ(0, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000388}
389
Per Kjellanderee8cd202021-03-10 12:31:38 +0100390TEST_P(ReceiveStatisticsTest, CountsLossAfterStreamRestart) {
Niels Möller87da1092019-05-24 14:04:28 +0200391 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000392
393 packet1_.SetSequenceNumber(0);
394 receive_statistics_->OnRtpPacket(packet1_);
395 packet1_.SetSequenceNumber(1);
396 receive_statistics_->OnRtpPacket(packet1_);
397
398 packet1_.SetSequenceNumber(400);
399 receive_statistics_->OnRtpPacket(packet1_);
400 packet1_.SetSequenceNumber(401);
401 receive_statistics_->OnRtpPacket(packet1_);
402 packet1_.SetSequenceNumber(403);
403 receive_statistics_->OnRtpPacket(packet1_);
404
Niels Möllerd77cc242019-08-22 09:40:25 +0200405 std::vector<rtcp::ReportBlock> report_blocks =
406 receive_statistics_->RtcpReportBlocks(1);
407 ASSERT_THAT(report_blocks, SizeIs(1));
408 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
409
410 EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed());
411
Niels Möller9a9f18a2019-08-02 13:52:37 +0200412 StreamStatistician* statistician =
413 receive_statistics_->GetStatistician(kSsrc1);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200414 // Is this reasonable? */
415 EXPECT_EQ(0, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000416}
417
Per Kjellanderee8cd202021-03-10 12:31:38 +0100418TEST_P(ReceiveStatisticsTest, StreamCanRestartAtSequenceNumberWrapAround) {
Niels Möller87da1092019-05-24 14:04:28 +0200419 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000420
421 packet1_.SetSequenceNumber(0xffff - 401);
422 receive_statistics_->OnRtpPacket(packet1_);
423 packet1_.SetSequenceNumber(0xffff - 400);
424 receive_statistics_->OnRtpPacket(packet1_);
425
426 packet1_.SetSequenceNumber(0xffff);
427 receive_statistics_->OnRtpPacket(packet1_);
428 packet1_.SetSequenceNumber(0);
429 receive_statistics_->OnRtpPacket(packet1_);
430 packet1_.SetSequenceNumber(2);
431 receive_statistics_->OnRtpPacket(packet1_);
432
Niels Möllerd77cc242019-08-22 09:40:25 +0200433 std::vector<rtcp::ReportBlock> report_blocks =
434 receive_statistics_->RtcpReportBlocks(1);
435 ASSERT_THAT(report_blocks, SizeIs(1));
436 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
437
438 EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000439}
440
Per Kjellanderee8cd202021-03-10 12:31:38 +0100441TEST_P(ReceiveStatisticsTest, StreamRestartNeedsTwoConsecutivePackets) {
Niels Möller87da1092019-05-24 14:04:28 +0200442 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000443
444 packet1_.SetSequenceNumber(400);
445 receive_statistics_->OnRtpPacket(packet1_);
446 packet1_.SetSequenceNumber(401);
447 receive_statistics_->OnRtpPacket(packet1_);
448
449 packet1_.SetSequenceNumber(1);
450 receive_statistics_->OnRtpPacket(packet1_);
451 packet1_.SetSequenceNumber(3);
452 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd77cc242019-08-22 09:40:25 +0200453
454 std::vector<rtcp::ReportBlock> report_blocks =
455 receive_statistics_->RtcpReportBlocks(1);
456 ASSERT_THAT(report_blocks, SizeIs(1));
457 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
458
459 EXPECT_EQ(401u, report_blocks[0].extended_high_seq_num());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000460
461 packet1_.SetSequenceNumber(4);
462 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd77cc242019-08-22 09:40:25 +0200463
464 report_blocks = receive_statistics_->RtcpReportBlocks(1);
465 ASSERT_THAT(report_blocks, SizeIs(1));
466 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
467
468 EXPECT_EQ(4u, report_blocks[0].extended_high_seq_num());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000469}
470
Per Kjellanderee8cd202021-03-10 12:31:38 +0100471TEST_P(ReceiveStatisticsTest, WrapsAroundExtendedHighestSequenceNumber) {
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000472 packet1_.SetSequenceNumber(0xffff);
473 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd77cc242019-08-22 09:40:25 +0200474
475 std::vector<rtcp::ReportBlock> report_blocks =
476 receive_statistics_->RtcpReportBlocks(1);
477 ASSERT_THAT(report_blocks, SizeIs(1));
478 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
479
480 EXPECT_EQ(0xffffu, report_blocks[0].extended_high_seq_num());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000481
482 // Wrap around.
483 packet1_.SetSequenceNumber(1);
484 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd77cc242019-08-22 09:40:25 +0200485
486 report_blocks = receive_statistics_->RtcpReportBlocks(1);
487 ASSERT_THAT(report_blocks, SizeIs(1));
488 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
489
490 EXPECT_EQ(0x10001u, report_blocks[0].extended_high_seq_num());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000491
492 // Should be treated as out of order; shouldn't increment highest extended
493 // sequence number.
494 packet1_.SetSequenceNumber(0x10000 - 6);
Niels Möllerd77cc242019-08-22 09:40:25 +0200495 report_blocks = receive_statistics_->RtcpReportBlocks(1);
496 ASSERT_THAT(report_blocks, SizeIs(1));
497 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
498
499 EXPECT_EQ(0x10001u, report_blocks[0].extended_high_seq_num());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000500
501 // Receive a couple packets then wrap around again.
Niels Möller87da1092019-05-24 14:04:28 +0200502 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000503 for (int i = 10; i < 0xffff; i += 150) {
504 packet1_.SetSequenceNumber(i);
505 receive_statistics_->OnRtpPacket(packet1_);
506 }
507 packet1_.SetSequenceNumber(1);
508 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd77cc242019-08-22 09:40:25 +0200509 report_blocks = receive_statistics_->RtcpReportBlocks(1);
510 ASSERT_THAT(report_blocks, SizeIs(1));
511 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
512
513 EXPECT_EQ(0x20001u, report_blocks[0].extended_high_seq_num());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000514}
515
Per Kjellanderee8cd202021-03-10 12:31:38 +0100516TEST_P(ReceiveStatisticsTest, StreamDataCounters) {
Niels Möller5304a322018-08-27 13:27:05 +0200517 receive_statistics_->EnableRetransmitDetection(kSsrc1, true);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000518
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000519 const size_t kHeaderLength = 20;
520 const size_t kPaddingLength = 9;
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000521
Niels Möller1f3206c2018-09-14 08:26:32 +0200522 // One packet with payload size kPacketSize1.
523 RtpPacketReceived packet1 =
524 CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 0);
525 receive_statistics_->OnRtpPacket(packet1);
Niels Möllerd7819652019-08-13 14:43:02 +0200526 StreamDataCounters counters = receive_statistics_->GetStatistician(kSsrc1)
527 ->GetReceiveStreamDataCounters();
528 EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1);
529 EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength);
530 EXPECT_EQ(counters.transmitted.padding_bytes, 0u);
531 EXPECT_EQ(counters.transmitted.packets, 1u);
532 EXPECT_EQ(counters.retransmitted.payload_bytes, 0u);
533 EXPECT_EQ(counters.retransmitted.header_bytes, 0u);
534 EXPECT_EQ(counters.retransmitted.padding_bytes, 0u);
535 EXPECT_EQ(counters.retransmitted.packets, 0u);
536 EXPECT_EQ(counters.fec.packets, 0u);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000537
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000538 // Another packet of size kPacketSize1 with 9 bytes padding.
Niels Möller1f3206c2018-09-14 08:26:32 +0200539 RtpPacketReceived packet2 =
540 CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 9);
541 packet2.SetSequenceNumber(packet1.SequenceNumber() + 1);
542 clock_.AdvanceTimeMilliseconds(5);
543 receive_statistics_->OnRtpPacket(packet2);
Niels Möllerd7819652019-08-13 14:43:02 +0200544 counters = receive_statistics_->GetStatistician(kSsrc1)
545 ->GetReceiveStreamDataCounters();
546 EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1 * 2);
547 EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength * 2);
548 EXPECT_EQ(counters.transmitted.padding_bytes, kPaddingLength);
549 EXPECT_EQ(counters.transmitted.packets, 2u);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000550
551 clock_.AdvanceTimeMilliseconds(5);
552 // Retransmit last packet.
Niels Möller1f3206c2018-09-14 08:26:32 +0200553 receive_statistics_->OnRtpPacket(packet2);
Niels Möllerd7819652019-08-13 14:43:02 +0200554 counters = receive_statistics_->GetStatistician(kSsrc1)
555 ->GetReceiveStreamDataCounters();
556 EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1 * 3);
557 EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength * 3);
558 EXPECT_EQ(counters.transmitted.padding_bytes, kPaddingLength * 2);
559 EXPECT_EQ(counters.transmitted.packets, 3u);
560 EXPECT_EQ(counters.retransmitted.payload_bytes, kPacketSize1);
561 EXPECT_EQ(counters.retransmitted.header_bytes, kHeaderLength);
562 EXPECT_EQ(counters.retransmitted.padding_bytes, kPaddingLength);
563 EXPECT_EQ(counters.retransmitted.packets, 1u);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000564}
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000565
Per Kjellanderee8cd202021-03-10 12:31:38 +0100566TEST_P(ReceiveStatisticsTest, LastPacketReceivedTimestamp) {
Henrik Boströmcb755b02019-04-02 15:11:48 +0200567 clock_.AdvanceTimeMilliseconds(42);
568 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd7819652019-08-13 14:43:02 +0200569 StreamDataCounters counters = receive_statistics_->GetStatistician(kSsrc1)
570 ->GetReceiveStreamDataCounters();
571
572 EXPECT_EQ(42, counters.last_packet_received_timestamp_ms);
Henrik Boströmcb755b02019-04-02 15:11:48 +0200573
574 clock_.AdvanceTimeMilliseconds(3);
575 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd7819652019-08-13 14:43:02 +0200576 counters = receive_statistics_->GetStatistician(kSsrc1)
577 ->GetReceiveStreamDataCounters();
578 EXPECT_EQ(45, counters.last_packet_received_timestamp_ms);
Henrik Boströmcb755b02019-04-02 15:11:48 +0200579}
580
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100581} // namespace
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000582} // namespace webrtc