blob: 44e53cf8c16806ee53fb5e46b3ee323da50ddf2d [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
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000068class ReceiveStatisticsTest : public ::testing::Test {
69 public:
Yves Gerey665174f2018-06-19 15:03:05 +020070 ReceiveStatisticsTest()
Niels Möllerd7819652019-08-13 14:43:02 +020071 : clock_(0), receive_statistics_(ReceiveStatistics::Create(&clock_)) {
Niels Möller1f3206c2018-09-14 08:26:32 +020072 packet1_ = CreateRtpPacket(kSsrc1, kPacketSize1);
73 packet2_ = CreateRtpPacket(kSsrc2, kPacketSize2);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000074 }
75
76 protected:
77 SimulatedClock clock_;
kwiberg84be5112016-04-27 01:19:58 -070078 std::unique_ptr<ReceiveStatistics> receive_statistics_;
Niels Möller1f3206c2018-09-14 08:26:32 +020079 RtpPacketReceived packet1_;
80 RtpPacketReceived packet2_;
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000081};
82
83TEST_F(ReceiveStatisticsTest, TwoIncomingSsrcs) {
Niels Möller1f3206c2018-09-14 08:26:32 +020084 receive_statistics_->OnRtpPacket(packet1_);
85 IncrementSequenceNumber(&packet1_);
86 receive_statistics_->OnRtpPacket(packet2_);
87 IncrementSequenceNumber(&packet2_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000088 clock_.AdvanceTimeMilliseconds(100);
Niels Möller1f3206c2018-09-14 08:26:32 +020089 receive_statistics_->OnRtpPacket(packet1_);
90 IncrementSequenceNumber(&packet1_);
91 receive_statistics_->OnRtpPacket(packet2_);
92 IncrementSequenceNumber(&packet2_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000093
94 StreamStatistician* statistician =
95 receive_statistics_->GetStatistician(kSsrc1);
96 ASSERT_TRUE(statistician != NULL);
97 EXPECT_GT(statistician->BitrateReceived(), 0u);
Niels Möller01525f92019-08-12 15:12:20 +020098 StreamDataCounters counters = statistician->GetReceiveStreamDataCounters();
99 EXPECT_EQ(176u, counters.transmitted.payload_bytes);
100 EXPECT_EQ(24u, counters.transmitted.header_bytes);
101 EXPECT_EQ(0u, counters.transmitted.padding_bytes);
102 EXPECT_EQ(2u, counters.transmitted.packets);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000103
Yves Gerey665174f2018-06-19 15:03:05 +0200104 statistician = receive_statistics_->GetStatistician(kSsrc2);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000105 ASSERT_TRUE(statistician != NULL);
106 EXPECT_GT(statistician->BitrateReceived(), 0u);
Niels Möller01525f92019-08-12 15:12:20 +0200107 counters = statistician->GetReceiveStreamDataCounters();
108 EXPECT_EQ(576u, counters.transmitted.payload_bytes);
109 EXPECT_EQ(24u, counters.transmitted.header_bytes);
110 EXPECT_EQ(0u, counters.transmitted.padding_bytes);
111 EXPECT_EQ(2u, counters.transmitted.packets);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000112
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200113 EXPECT_EQ(2u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000114 // Add more incoming packets and verify that they are registered in both
115 // access methods.
Niels Möller1f3206c2018-09-14 08:26:32 +0200116 receive_statistics_->OnRtpPacket(packet1_);
117 IncrementSequenceNumber(&packet1_);
118 receive_statistics_->OnRtpPacket(packet2_);
119 IncrementSequenceNumber(&packet2_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000120
Niels Möller01525f92019-08-12 15:12:20 +0200121 counters = receive_statistics_->GetStatistician(kSsrc1)
122 ->GetReceiveStreamDataCounters();
123 EXPECT_EQ(264u, counters.transmitted.payload_bytes);
124 EXPECT_EQ(36u, counters.transmitted.header_bytes);
125 EXPECT_EQ(0u, counters.transmitted.padding_bytes);
126 EXPECT_EQ(3u, counters.transmitted.packets);
127
128 counters = receive_statistics_->GetStatistician(kSsrc2)
129 ->GetReceiveStreamDataCounters();
130 EXPECT_EQ(864u, counters.transmitted.payload_bytes);
131 EXPECT_EQ(36u, counters.transmitted.header_bytes);
132 EXPECT_EQ(0u, counters.transmitted.padding_bytes);
133 EXPECT_EQ(3u, counters.transmitted.packets);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000134}
135
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100136TEST_F(ReceiveStatisticsTest,
137 RtcpReportBlocksReturnsMaxBlocksWhenThereAreMoreStatisticians) {
Niels Möller1f3206c2018-09-14 08:26:32 +0200138 RtpPacketReceived packet1 = CreateRtpPacket(kSsrc1, kPacketSize1);
139 RtpPacketReceived packet2 = CreateRtpPacket(kSsrc2, kPacketSize1);
140 RtpPacketReceived packet3 = CreateRtpPacket(kSsrc3, kPacketSize1);
141 receive_statistics_->OnRtpPacket(packet1);
142 receive_statistics_->OnRtpPacket(packet2);
143 receive_statistics_->OnRtpPacket(packet3);
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100144
145 EXPECT_THAT(receive_statistics_->RtcpReportBlocks(2), SizeIs(2));
146 EXPECT_THAT(receive_statistics_->RtcpReportBlocks(2), SizeIs(2));
147 EXPECT_THAT(receive_statistics_->RtcpReportBlocks(2), SizeIs(2));
148}
149
150TEST_F(ReceiveStatisticsTest,
151 RtcpReportBlocksReturnsAllObservedSsrcsWithMultipleCalls) {
Niels Möller1f3206c2018-09-14 08:26:32 +0200152 RtpPacketReceived packet1 = CreateRtpPacket(kSsrc1, kPacketSize1);
153 RtpPacketReceived packet2 = CreateRtpPacket(kSsrc2, kPacketSize1);
154 RtpPacketReceived packet3 = CreateRtpPacket(kSsrc3, kPacketSize1);
155 RtpPacketReceived packet4 = CreateRtpPacket(kSsrc4, kPacketSize1);
156 receive_statistics_->OnRtpPacket(packet1);
157 receive_statistics_->OnRtpPacket(packet2);
158 receive_statistics_->OnRtpPacket(packet3);
159 receive_statistics_->OnRtpPacket(packet4);
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100160
161 std::vector<uint32_t> observed_ssrcs;
162 std::vector<rtcp::ReportBlock> report_blocks =
163 receive_statistics_->RtcpReportBlocks(2);
164 ASSERT_THAT(report_blocks, SizeIs(2));
165 observed_ssrcs.push_back(report_blocks[0].source_ssrc());
166 observed_ssrcs.push_back(report_blocks[1].source_ssrc());
167
168 report_blocks = receive_statistics_->RtcpReportBlocks(2);
169 ASSERT_THAT(report_blocks, SizeIs(2));
170 observed_ssrcs.push_back(report_blocks[0].source_ssrc());
171 observed_ssrcs.push_back(report_blocks[1].source_ssrc());
172
173 EXPECT_THAT(observed_ssrcs,
174 UnorderedElementsAre(kSsrc1, kSsrc2, kSsrc3, kSsrc4));
175}
176
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000177TEST_F(ReceiveStatisticsTest, ActiveStatisticians) {
Niels Möller1f3206c2018-09-14 08:26:32 +0200178 receive_statistics_->OnRtpPacket(packet1_);
179 IncrementSequenceNumber(&packet1_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000180 clock_.AdvanceTimeMilliseconds(1000);
Niels Möller1f3206c2018-09-14 08:26:32 +0200181 receive_statistics_->OnRtpPacket(packet2_);
182 IncrementSequenceNumber(&packet2_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000183 // Nothing should time out since only 1000 ms has passed since the first
184 // packet came in.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200185 EXPECT_EQ(2u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000186
187 clock_.AdvanceTimeMilliseconds(7000);
188 // kSsrc1 should have timed out.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200189 EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000190
191 clock_.AdvanceTimeMilliseconds(1000);
192 // kSsrc2 should have timed out.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200193 EXPECT_EQ(0u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000194
Niels Möller1f3206c2018-09-14 08:26:32 +0200195 receive_statistics_->OnRtpPacket(packet1_);
196 IncrementSequenceNumber(&packet1_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000197 // kSsrc1 should be active again and the data counters should have survived.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200198 EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000199 StreamStatistician* statistician =
200 receive_statistics_->GetStatistician(kSsrc1);
201 ASSERT_TRUE(statistician != NULL);
Niels Möller01525f92019-08-12 15:12:20 +0200202 StreamDataCounters counters = statistician->GetReceiveStreamDataCounters();
203 EXPECT_EQ(176u, counters.transmitted.payload_bytes);
204 EXPECT_EQ(24u, counters.transmitted.header_bytes);
205 EXPECT_EQ(0u, counters.transmitted.padding_bytes);
206 EXPECT_EQ(2u, counters.transmitted.packets);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000207}
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000208
Niels Möller5304a322018-08-27 13:27:05 +0200209TEST_F(ReceiveStatisticsTest,
210 DoesntCreateRtcpReportBlockUntilFirstReceivedPacketForSsrc) {
211 // Creates a statistician object for the ssrc.
212 receive_statistics_->EnableRetransmitDetection(kSsrc1, true);
213 EXPECT_TRUE(receive_statistics_->GetStatistician(kSsrc1) != nullptr);
214 EXPECT_EQ(0u, receive_statistics_->RtcpReportBlocks(3).size());
215 // Receive first packet
Niels Möller1f3206c2018-09-14 08:26:32 +0200216 receive_statistics_->OnRtpPacket(packet1_);
Niels Möller5304a322018-08-27 13:27:05 +0200217 EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size());
218}
219
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000220TEST_F(ReceiveStatisticsTest, GetReceiveStreamDataCounters) {
Niels Möller1f3206c2018-09-14 08:26:32 +0200221 receive_statistics_->OnRtpPacket(packet1_);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000222 StreamStatistician* statistician =
223 receive_statistics_->GetStatistician(kSsrc1);
224 ASSERT_TRUE(statistician != NULL);
225
Niels Möller58b496b2019-08-12 12:16:31 +0200226 StreamDataCounters counters = statistician->GetReceiveStreamDataCounters();
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000227 EXPECT_GT(counters.first_packet_time_ms, -1);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000228 EXPECT_EQ(1u, counters.transmitted.packets);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000229
Niels Möller1f3206c2018-09-14 08:26:32 +0200230 receive_statistics_->OnRtpPacket(packet1_);
Niels Möller58b496b2019-08-12 12:16:31 +0200231 counters = statistician->GetReceiveStreamDataCounters();
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000232 EXPECT_GT(counters.first_packet_time_ms, -1);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000233 EXPECT_EQ(2u, counters.transmitted.packets);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000234}
235
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000236TEST_F(ReceiveStatisticsTest, SimpleLossComputation) {
237 packet1_.SetSequenceNumber(1);
238 receive_statistics_->OnRtpPacket(packet1_);
239 packet1_.SetSequenceNumber(3);
240 receive_statistics_->OnRtpPacket(packet1_);
241 packet1_.SetSequenceNumber(4);
242 receive_statistics_->OnRtpPacket(packet1_);
243 packet1_.SetSequenceNumber(5);
244 receive_statistics_->OnRtpPacket(packet1_);
245
Niels Möller9a9f18a2019-08-02 13:52:37 +0200246 StreamStatistician* statistician =
247 receive_statistics_->GetStatistician(kSsrc1);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000248 RtcpStatistics statistics;
Niels Möller9a9f18a2019-08-02 13:52:37 +0200249 statistician->GetStatistics(&statistics, true);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000250 // 20% = 51/255.
251 EXPECT_EQ(51u, statistics.fraction_lost);
252 EXPECT_EQ(1, statistics.packets_lost);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200253 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000254}
255
256TEST_F(ReceiveStatisticsTest, LossComputationWithReordering) {
257 packet1_.SetSequenceNumber(1);
258 receive_statistics_->OnRtpPacket(packet1_);
259 packet1_.SetSequenceNumber(3);
260 receive_statistics_->OnRtpPacket(packet1_);
261 packet1_.SetSequenceNumber(2);
262 receive_statistics_->OnRtpPacket(packet1_);
263 packet1_.SetSequenceNumber(5);
264 receive_statistics_->OnRtpPacket(packet1_);
265
Niels Möller9a9f18a2019-08-02 13:52:37 +0200266 StreamStatistician* statistician =
267 receive_statistics_->GetStatistician(kSsrc1);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000268 RtcpStatistics statistics;
Niels Möller9a9f18a2019-08-02 13:52:37 +0200269 statistician->GetStatistics(&statistics, true);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000270 // 20% = 51/255.
271 EXPECT_EQ(51u, statistics.fraction_lost);
272 EXPECT_EQ(1, statistics.packets_lost);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200273 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000274}
275
276TEST_F(ReceiveStatisticsTest, LossComputationWithDuplicates) {
277 // Lose 2 packets, but also receive 1 duplicate. Should actually count as
278 // only 1 packet being lost.
279 packet1_.SetSequenceNumber(1);
280 receive_statistics_->OnRtpPacket(packet1_);
281 packet1_.SetSequenceNumber(4);
282 receive_statistics_->OnRtpPacket(packet1_);
283 packet1_.SetSequenceNumber(4);
284 receive_statistics_->OnRtpPacket(packet1_);
285 packet1_.SetSequenceNumber(5);
286 receive_statistics_->OnRtpPacket(packet1_);
287
Niels Möller9a9f18a2019-08-02 13:52:37 +0200288 StreamStatistician* statistician =
289 receive_statistics_->GetStatistician(kSsrc1);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000290 RtcpStatistics statistics;
Niels Möller9a9f18a2019-08-02 13:52:37 +0200291 statistician->GetStatistics(&statistics, true);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000292 // 20% = 51/255.
293 EXPECT_EQ(51u, statistics.fraction_lost);
294 EXPECT_EQ(1, statistics.packets_lost);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200295 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000296}
297
298TEST_F(ReceiveStatisticsTest, LossComputationWithSequenceNumberWrapping) {
299 // First, test loss computation over a period that included a sequence number
300 // rollover.
301 packet1_.SetSequenceNumber(0xfffd);
302 receive_statistics_->OnRtpPacket(packet1_);
303 packet1_.SetSequenceNumber(0);
304 receive_statistics_->OnRtpPacket(packet1_);
305 packet1_.SetSequenceNumber(0xfffe);
306 receive_statistics_->OnRtpPacket(packet1_);
307 packet1_.SetSequenceNumber(1);
308 receive_statistics_->OnRtpPacket(packet1_);
309
310 // Only one packet was actually lost, 0xffff.
Niels Möller9a9f18a2019-08-02 13:52:37 +0200311 StreamStatistician* statistician =
312 receive_statistics_->GetStatistician(kSsrc1);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000313 RtcpStatistics statistics;
Niels Möller9a9f18a2019-08-02 13:52:37 +0200314 statistician->GetStatistics(&statistics, true);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000315 // 20% = 51/255.
316 EXPECT_EQ(51u, statistics.fraction_lost);
317 EXPECT_EQ(1, statistics.packets_lost);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200318 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000319
320 // Now test losing one packet *after* the rollover.
321 packet1_.SetSequenceNumber(3);
322 receive_statistics_->OnRtpPacket(packet1_);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200323 statistician->GetStatistics(&statistics, true);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000324 // 50% = 127/255.
325 EXPECT_EQ(127u, statistics.fraction_lost);
326 EXPECT_EQ(2, statistics.packets_lost);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200327 // 2 packets lost, 7 expected
328 EXPECT_EQ(28, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000329}
330
331TEST_F(ReceiveStatisticsTest, StreamRestartDoesntCountAsLoss) {
332 RtcpStatistics statistics;
Niels Möller87da1092019-05-24 14:04:28 +0200333 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000334
335 packet1_.SetSequenceNumber(0);
336 receive_statistics_->OnRtpPacket(packet1_);
337 packet1_.SetSequenceNumber(1);
338 receive_statistics_->OnRtpPacket(packet1_);
339
340 packet1_.SetSequenceNumber(400);
341 receive_statistics_->OnRtpPacket(packet1_);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200342 StreamStatistician* statistician =
343 receive_statistics_->GetStatistician(kSsrc1);
344 statistician->GetStatistics(&statistics, true);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000345 EXPECT_EQ(0, statistics.fraction_lost);
346 EXPECT_EQ(0, statistics.packets_lost);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200347 EXPECT_EQ(0, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000348
349 packet1_.SetSequenceNumber(401);
350 receive_statistics_->OnRtpPacket(packet1_);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200351 statistician->GetStatistics(&statistics, true);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000352 EXPECT_EQ(0, statistics.fraction_lost);
353 EXPECT_EQ(0, statistics.packets_lost);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200354 EXPECT_EQ(0, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000355}
356
357TEST_F(ReceiveStatisticsTest, CountsLossAfterStreamRestart) {
358 RtcpStatistics statistics;
Niels Möller87da1092019-05-24 14:04:28 +0200359 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000360
361 packet1_.SetSequenceNumber(0);
362 receive_statistics_->OnRtpPacket(packet1_);
363 packet1_.SetSequenceNumber(1);
364 receive_statistics_->OnRtpPacket(packet1_);
365
366 packet1_.SetSequenceNumber(400);
367 receive_statistics_->OnRtpPacket(packet1_);
368 packet1_.SetSequenceNumber(401);
369 receive_statistics_->OnRtpPacket(packet1_);
370 packet1_.SetSequenceNumber(403);
371 receive_statistics_->OnRtpPacket(packet1_);
372
Niels Möller9a9f18a2019-08-02 13:52:37 +0200373 StreamStatistician* statistician =
374 receive_statistics_->GetStatistician(kSsrc1);
375
376 statistician->GetStatistics(&statistics, true);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000377 EXPECT_EQ(1, statistics.packets_lost);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200378 // Is this reasonable? */
379 EXPECT_EQ(0, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000380}
381
382TEST_F(ReceiveStatisticsTest, StreamCanRestartAtSequenceNumberWrapAround) {
383 RtcpStatistics statistics;
Niels Möller87da1092019-05-24 14:04:28 +0200384 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000385
386 packet1_.SetSequenceNumber(0xffff - 401);
387 receive_statistics_->OnRtpPacket(packet1_);
388 packet1_.SetSequenceNumber(0xffff - 400);
389 receive_statistics_->OnRtpPacket(packet1_);
390
391 packet1_.SetSequenceNumber(0xffff);
392 receive_statistics_->OnRtpPacket(packet1_);
393 packet1_.SetSequenceNumber(0);
394 receive_statistics_->OnRtpPacket(packet1_);
395 packet1_.SetSequenceNumber(2);
396 receive_statistics_->OnRtpPacket(packet1_);
397
398 receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
399 true);
400 EXPECT_EQ(1, statistics.packets_lost);
401}
402
403TEST_F(ReceiveStatisticsTest, StreamRestartNeedsTwoConsecutivePackets) {
404 RtcpStatistics statistics;
Niels Möller87da1092019-05-24 14:04:28 +0200405 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000406
407 packet1_.SetSequenceNumber(400);
408 receive_statistics_->OnRtpPacket(packet1_);
409 packet1_.SetSequenceNumber(401);
410 receive_statistics_->OnRtpPacket(packet1_);
411
412 packet1_.SetSequenceNumber(1);
413 receive_statistics_->OnRtpPacket(packet1_);
414 packet1_.SetSequenceNumber(3);
415 receive_statistics_->OnRtpPacket(packet1_);
416 receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
417 true);
418 EXPECT_EQ(401u, statistics.extended_highest_sequence_number);
419
420 packet1_.SetSequenceNumber(4);
421 receive_statistics_->OnRtpPacket(packet1_);
422 receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
423 true);
424 EXPECT_EQ(4u, statistics.extended_highest_sequence_number);
425}
426
427TEST_F(ReceiveStatisticsTest, WrapsAroundExtendedHighestSequenceNumber) {
428 RtcpStatistics statistics;
429 packet1_.SetSequenceNumber(0xffff);
430 receive_statistics_->OnRtpPacket(packet1_);
431 receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
432 true);
433 EXPECT_EQ(0xffffu, statistics.extended_highest_sequence_number);
434
435 // Wrap around.
436 packet1_.SetSequenceNumber(1);
437 receive_statistics_->OnRtpPacket(packet1_);
438 receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
439 true);
440 EXPECT_EQ(0x10001u, statistics.extended_highest_sequence_number);
441
442 // Should be treated as out of order; shouldn't increment highest extended
443 // sequence number.
444 packet1_.SetSequenceNumber(0x10000 - 6);
445 receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
446 true);
447 EXPECT_EQ(0x10001u, statistics.extended_highest_sequence_number);
448
449 // Receive a couple packets then wrap around again.
Niels Möller87da1092019-05-24 14:04:28 +0200450 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000451 for (int i = 10; i < 0xffff; i += 150) {
452 packet1_.SetSequenceNumber(i);
453 receive_statistics_->OnRtpPacket(packet1_);
454 }
455 packet1_.SetSequenceNumber(1);
456 receive_statistics_->OnRtpPacket(packet1_);
457 receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
458 true);
459 EXPECT_EQ(0x20001u, statistics.extended_highest_sequence_number);
460}
461
Niels Möllerd7819652019-08-13 14:43:02 +0200462TEST_F(ReceiveStatisticsTest, StreamDataCounters) {
463 receive_statistics_ = ReceiveStatistics::Create(&clock_);
Niels Möller5304a322018-08-27 13:27:05 +0200464 receive_statistics_->EnableRetransmitDetection(kSsrc1, true);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000465
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000466 const size_t kHeaderLength = 20;
467 const size_t kPaddingLength = 9;
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000468
Niels Möller1f3206c2018-09-14 08:26:32 +0200469 // One packet with payload size kPacketSize1.
470 RtpPacketReceived packet1 =
471 CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 0);
472 receive_statistics_->OnRtpPacket(packet1);
Niels Möllerd7819652019-08-13 14:43:02 +0200473 StreamDataCounters counters = receive_statistics_->GetStatistician(kSsrc1)
474 ->GetReceiveStreamDataCounters();
475 EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1);
476 EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength);
477 EXPECT_EQ(counters.transmitted.padding_bytes, 0u);
478 EXPECT_EQ(counters.transmitted.packets, 1u);
479 EXPECT_EQ(counters.retransmitted.payload_bytes, 0u);
480 EXPECT_EQ(counters.retransmitted.header_bytes, 0u);
481 EXPECT_EQ(counters.retransmitted.padding_bytes, 0u);
482 EXPECT_EQ(counters.retransmitted.packets, 0u);
483 EXPECT_EQ(counters.fec.packets, 0u);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000484
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000485 // Another packet of size kPacketSize1 with 9 bytes padding.
Niels Möller1f3206c2018-09-14 08:26:32 +0200486 RtpPacketReceived packet2 =
487 CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 9);
488 packet2.SetSequenceNumber(packet1.SequenceNumber() + 1);
489 clock_.AdvanceTimeMilliseconds(5);
490 receive_statistics_->OnRtpPacket(packet2);
Niels Möllerd7819652019-08-13 14:43:02 +0200491 counters = receive_statistics_->GetStatistician(kSsrc1)
492 ->GetReceiveStreamDataCounters();
493 EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1 * 2);
494 EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength * 2);
495 EXPECT_EQ(counters.transmitted.padding_bytes, kPaddingLength);
496 EXPECT_EQ(counters.transmitted.packets, 2u);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000497
498 clock_.AdvanceTimeMilliseconds(5);
499 // Retransmit last packet.
Niels Möller1f3206c2018-09-14 08:26:32 +0200500 receive_statistics_->OnRtpPacket(packet2);
Niels Möllerd7819652019-08-13 14:43:02 +0200501 counters = receive_statistics_->GetStatistician(kSsrc1)
502 ->GetReceiveStreamDataCounters();
503 EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1 * 3);
504 EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength * 3);
505 EXPECT_EQ(counters.transmitted.padding_bytes, kPaddingLength * 2);
506 EXPECT_EQ(counters.transmitted.packets, 3u);
507 EXPECT_EQ(counters.retransmitted.payload_bytes, kPacketSize1);
508 EXPECT_EQ(counters.retransmitted.header_bytes, kHeaderLength);
509 EXPECT_EQ(counters.retransmitted.padding_bytes, kPaddingLength);
510 EXPECT_EQ(counters.retransmitted.packets, 1u);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000511
asapersson@webrtc.org273fbbb2015-01-27 12:17:29 +0000512 // One FEC packet.
Niels Möller1f3206c2018-09-14 08:26:32 +0200513 packet1.SetSequenceNumber(packet2.SequenceNumber() + 1);
514 clock_.AdvanceTimeMilliseconds(5);
515 receive_statistics_->OnRtpPacket(packet1);
516 receive_statistics_->FecPacketReceived(packet1);
Niels Möllerd7819652019-08-13 14:43:02 +0200517 counters = receive_statistics_->GetStatistician(kSsrc1)
518 ->GetReceiveStreamDataCounters();
519 EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1 * 4);
520 EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength * 4);
521 EXPECT_EQ(counters.transmitted.packets, 4u);
522 EXPECT_EQ(counters.fec.payload_bytes, kPacketSize1);
523 EXPECT_EQ(counters.fec.header_bytes, kHeaderLength);
524 EXPECT_EQ(counters.fec.packets, 1u);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000525}
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000526
Henrik Boströmcb755b02019-04-02 15:11:48 +0200527TEST_F(ReceiveStatisticsTest, LastPacketReceivedTimestamp) {
Niels Möllerd7819652019-08-13 14:43:02 +0200528 receive_statistics_ = ReceiveStatistics::Create(&clock_);
Henrik Boströmcb755b02019-04-02 15:11:48 +0200529
530 clock_.AdvanceTimeMilliseconds(42);
531 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd7819652019-08-13 14:43:02 +0200532 StreamDataCounters counters = receive_statistics_->GetStatistician(kSsrc1)
533 ->GetReceiveStreamDataCounters();
534
535 EXPECT_EQ(42, counters.last_packet_received_timestamp_ms);
Henrik Boströmcb755b02019-04-02 15:11:48 +0200536
537 clock_.AdvanceTimeMilliseconds(3);
538 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd7819652019-08-13 14:43:02 +0200539 counters = receive_statistics_->GetStatistician(kSsrc1)
540 ->GetReceiveStreamDataCounters();
541 EXPECT_EQ(45, counters.last_packet_received_timestamp_ms);
Henrik Boströmcb755b02019-04-02 15:11:48 +0200542}
543
Niels Möllerd7819652019-08-13 14:43:02 +0200544TEST_F(ReceiveStatisticsTest, FecFirst) {
545 receive_statistics_ = ReceiveStatistics::Create(&clock_);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000546
547 const uint32_t kHeaderLength = 20;
Niels Möller1f3206c2018-09-14 08:26:32 +0200548 RtpPacketReceived packet =
549 CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 0);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000550 // If first packet is FEC, ignore it.
Niels Möller1f3206c2018-09-14 08:26:32 +0200551 receive_statistics_->FecPacketReceived(packet);
Niels Möllerd7819652019-08-13 14:43:02 +0200552
553 EXPECT_EQ(receive_statistics_->GetStatistician(kSsrc1), nullptr);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000554
Niels Möller1f3206c2018-09-14 08:26:32 +0200555 receive_statistics_->OnRtpPacket(packet);
Niels Möllerd7819652019-08-13 14:43:02 +0200556 StreamDataCounters counters = receive_statistics_->GetStatistician(kSsrc1)
557 ->GetReceiveStreamDataCounters();
558 EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1);
559 EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength);
560 EXPECT_EQ(counters.transmitted.padding_bytes, 0u);
561 EXPECT_EQ(counters.transmitted.packets, 1u);
562 EXPECT_EQ(counters.fec.packets, 0u);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000563
Niels Möller1f3206c2018-09-14 08:26:32 +0200564 receive_statistics_->FecPacketReceived(packet);
Niels Möllerd7819652019-08-13 14:43:02 +0200565 counters = receive_statistics_->GetStatistician(kSsrc1)
566 ->GetReceiveStreamDataCounters();
567 EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1);
568 EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength);
569 EXPECT_EQ(counters.transmitted.padding_bytes, 0u);
570 EXPECT_EQ(counters.transmitted.packets, 1u);
571 EXPECT_EQ(counters.fec.payload_bytes, kPacketSize1);
572 EXPECT_EQ(counters.fec.header_bytes, kHeaderLength);
573 EXPECT_EQ(counters.fec.packets, 1u);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000574}
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100575
576} // namespace
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000577} // namespace webrtc