blob: 28c14036f0789e613b227153eee1b80bf0d13ffd [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()
Danil Chapovalov8ce0d2b2018-11-23 11:03:25 +010071 : clock_(0),
Niels Möller12ebfa62019-08-06 16:04:12 +020072 receive_statistics_(ReceiveStatistics::Create(&clock_, nullptr)) {
Niels Möller1f3206c2018-09-14 08:26:32 +020073 packet1_ = CreateRtpPacket(kSsrc1, kPacketSize1);
74 packet2_ = CreateRtpPacket(kSsrc2, kPacketSize2);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000075 }
76
77 protected:
78 SimulatedClock clock_;
kwiberg84be5112016-04-27 01:19:58 -070079 std::unique_ptr<ReceiveStatistics> receive_statistics_;
Niels Möller1f3206c2018-09-14 08:26:32 +020080 RtpPacketReceived packet1_;
81 RtpPacketReceived packet2_;
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000082};
83
84TEST_F(ReceiveStatisticsTest, TwoIncomingSsrcs) {
Niels Möller1f3206c2018-09-14 08:26:32 +020085 receive_statistics_->OnRtpPacket(packet1_);
86 IncrementSequenceNumber(&packet1_);
87 receive_statistics_->OnRtpPacket(packet2_);
88 IncrementSequenceNumber(&packet2_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000089 clock_.AdvanceTimeMilliseconds(100);
Niels Möller1f3206c2018-09-14 08:26:32 +020090 receive_statistics_->OnRtpPacket(packet1_);
91 IncrementSequenceNumber(&packet1_);
92 receive_statistics_->OnRtpPacket(packet2_);
93 IncrementSequenceNumber(&packet2_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000094
95 StreamStatistician* statistician =
96 receive_statistics_->GetStatistician(kSsrc1);
97 ASSERT_TRUE(statistician != NULL);
98 EXPECT_GT(statistician->BitrateReceived(), 0u);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000099 size_t bytes_received = 0;
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000100 uint32_t packets_received = 0;
101 statistician->GetDataCounters(&bytes_received, &packets_received);
102 EXPECT_EQ(200u, bytes_received);
103 EXPECT_EQ(2u, packets_received);
104
Yves Gerey665174f2018-06-19 15:03:05 +0200105 statistician = receive_statistics_->GetStatistician(kSsrc2);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000106 ASSERT_TRUE(statistician != NULL);
107 EXPECT_GT(statistician->BitrateReceived(), 0u);
108 statistician->GetDataCounters(&bytes_received, &packets_received);
109 EXPECT_EQ(600u, bytes_received);
110 EXPECT_EQ(2u, packets_received);
111
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200112 EXPECT_EQ(2u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000113 // Add more incoming packets and verify that they are registered in both
114 // access methods.
Niels Möller1f3206c2018-09-14 08:26:32 +0200115 receive_statistics_->OnRtpPacket(packet1_);
116 IncrementSequenceNumber(&packet1_);
117 receive_statistics_->OnRtpPacket(packet2_);
118 IncrementSequenceNumber(&packet2_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000119
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000120 receive_statistics_->GetStatistician(kSsrc1)->GetDataCounters(
121 &bytes_received, &packets_received);
122 EXPECT_EQ(300u, bytes_received);
123 EXPECT_EQ(3u, packets_received);
124 receive_statistics_->GetStatistician(kSsrc2)->GetDataCounters(
125 &bytes_received, &packets_received);
126 EXPECT_EQ(900u, bytes_received);
127 EXPECT_EQ(3u, packets_received);
128}
129
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100130TEST_F(ReceiveStatisticsTest,
131 RtcpReportBlocksReturnsMaxBlocksWhenThereAreMoreStatisticians) {
Niels Möller1f3206c2018-09-14 08:26:32 +0200132 RtpPacketReceived packet1 = CreateRtpPacket(kSsrc1, kPacketSize1);
133 RtpPacketReceived packet2 = CreateRtpPacket(kSsrc2, kPacketSize1);
134 RtpPacketReceived packet3 = CreateRtpPacket(kSsrc3, kPacketSize1);
135 receive_statistics_->OnRtpPacket(packet1);
136 receive_statistics_->OnRtpPacket(packet2);
137 receive_statistics_->OnRtpPacket(packet3);
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100138
139 EXPECT_THAT(receive_statistics_->RtcpReportBlocks(2), SizeIs(2));
140 EXPECT_THAT(receive_statistics_->RtcpReportBlocks(2), SizeIs(2));
141 EXPECT_THAT(receive_statistics_->RtcpReportBlocks(2), SizeIs(2));
142}
143
144TEST_F(ReceiveStatisticsTest,
145 RtcpReportBlocksReturnsAllObservedSsrcsWithMultipleCalls) {
Niels Möller1f3206c2018-09-14 08:26:32 +0200146 RtpPacketReceived packet1 = CreateRtpPacket(kSsrc1, kPacketSize1);
147 RtpPacketReceived packet2 = CreateRtpPacket(kSsrc2, kPacketSize1);
148 RtpPacketReceived packet3 = CreateRtpPacket(kSsrc3, kPacketSize1);
149 RtpPacketReceived packet4 = CreateRtpPacket(kSsrc4, kPacketSize1);
150 receive_statistics_->OnRtpPacket(packet1);
151 receive_statistics_->OnRtpPacket(packet2);
152 receive_statistics_->OnRtpPacket(packet3);
153 receive_statistics_->OnRtpPacket(packet4);
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100154
155 std::vector<uint32_t> observed_ssrcs;
156 std::vector<rtcp::ReportBlock> report_blocks =
157 receive_statistics_->RtcpReportBlocks(2);
158 ASSERT_THAT(report_blocks, SizeIs(2));
159 observed_ssrcs.push_back(report_blocks[0].source_ssrc());
160 observed_ssrcs.push_back(report_blocks[1].source_ssrc());
161
162 report_blocks = receive_statistics_->RtcpReportBlocks(2);
163 ASSERT_THAT(report_blocks, SizeIs(2));
164 observed_ssrcs.push_back(report_blocks[0].source_ssrc());
165 observed_ssrcs.push_back(report_blocks[1].source_ssrc());
166
167 EXPECT_THAT(observed_ssrcs,
168 UnorderedElementsAre(kSsrc1, kSsrc2, kSsrc3, kSsrc4));
169}
170
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000171TEST_F(ReceiveStatisticsTest, ActiveStatisticians) {
Niels Möller1f3206c2018-09-14 08:26:32 +0200172 receive_statistics_->OnRtpPacket(packet1_);
173 IncrementSequenceNumber(&packet1_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000174 clock_.AdvanceTimeMilliseconds(1000);
Niels Möller1f3206c2018-09-14 08:26:32 +0200175 receive_statistics_->OnRtpPacket(packet2_);
176 IncrementSequenceNumber(&packet2_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000177 // Nothing should time out since only 1000 ms has passed since the first
178 // packet came in.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200179 EXPECT_EQ(2u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000180
181 clock_.AdvanceTimeMilliseconds(7000);
182 // kSsrc1 should have timed out.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200183 EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000184
185 clock_.AdvanceTimeMilliseconds(1000);
186 // kSsrc2 should have timed out.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200187 EXPECT_EQ(0u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000188
Niels Möller1f3206c2018-09-14 08:26:32 +0200189 receive_statistics_->OnRtpPacket(packet1_);
190 IncrementSequenceNumber(&packet1_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000191 // kSsrc1 should be active again and the data counters should have survived.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200192 EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000193 StreamStatistician* statistician =
194 receive_statistics_->GetStatistician(kSsrc1);
195 ASSERT_TRUE(statistician != NULL);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000196 size_t bytes_received = 0;
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000197 uint32_t packets_received = 0;
198 statistician->GetDataCounters(&bytes_received, &packets_received);
199 EXPECT_EQ(200u, bytes_received);
200 EXPECT_EQ(2u, packets_received);
201}
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000202
Niels Möller5304a322018-08-27 13:27:05 +0200203TEST_F(ReceiveStatisticsTest,
204 DoesntCreateRtcpReportBlockUntilFirstReceivedPacketForSsrc) {
205 // Creates a statistician object for the ssrc.
206 receive_statistics_->EnableRetransmitDetection(kSsrc1, true);
207 EXPECT_TRUE(receive_statistics_->GetStatistician(kSsrc1) != nullptr);
208 EXPECT_EQ(0u, receive_statistics_->RtcpReportBlocks(3).size());
209 // Receive first packet
Niels Möller1f3206c2018-09-14 08:26:32 +0200210 receive_statistics_->OnRtpPacket(packet1_);
Niels Möller5304a322018-08-27 13:27:05 +0200211 EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size());
212}
213
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000214TEST_F(ReceiveStatisticsTest, GetReceiveStreamDataCounters) {
Niels Möller1f3206c2018-09-14 08:26:32 +0200215 receive_statistics_->OnRtpPacket(packet1_);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000216 StreamStatistician* statistician =
217 receive_statistics_->GetStatistician(kSsrc1);
218 ASSERT_TRUE(statistician != NULL);
219
220 StreamDataCounters counters;
221 statistician->GetReceiveStreamDataCounters(&counters);
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000222 EXPECT_GT(counters.first_packet_time_ms, -1);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000223 EXPECT_EQ(1u, counters.transmitted.packets);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000224
Niels Möller1f3206c2018-09-14 08:26:32 +0200225 receive_statistics_->OnRtpPacket(packet1_);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000226 statistician->GetReceiveStreamDataCounters(&counters);
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(2u, counters.transmitted.packets);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000229}
230
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000231TEST_F(ReceiveStatisticsTest, SimpleLossComputation) {
232 packet1_.SetSequenceNumber(1);
233 receive_statistics_->OnRtpPacket(packet1_);
234 packet1_.SetSequenceNumber(3);
235 receive_statistics_->OnRtpPacket(packet1_);
236 packet1_.SetSequenceNumber(4);
237 receive_statistics_->OnRtpPacket(packet1_);
238 packet1_.SetSequenceNumber(5);
239 receive_statistics_->OnRtpPacket(packet1_);
240
Niels Möller9a9f18a2019-08-02 13:52:37 +0200241 StreamStatistician* statistician =
242 receive_statistics_->GetStatistician(kSsrc1);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000243 RtcpStatistics statistics;
Niels Möller9a9f18a2019-08-02 13:52:37 +0200244 statistician->GetStatistics(&statistics, true);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000245 // 20% = 51/255.
246 EXPECT_EQ(51u, statistics.fraction_lost);
247 EXPECT_EQ(1, statistics.packets_lost);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200248 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000249}
250
251TEST_F(ReceiveStatisticsTest, LossComputationWithReordering) {
252 packet1_.SetSequenceNumber(1);
253 receive_statistics_->OnRtpPacket(packet1_);
254 packet1_.SetSequenceNumber(3);
255 receive_statistics_->OnRtpPacket(packet1_);
256 packet1_.SetSequenceNumber(2);
257 receive_statistics_->OnRtpPacket(packet1_);
258 packet1_.SetSequenceNumber(5);
259 receive_statistics_->OnRtpPacket(packet1_);
260
Niels Möller9a9f18a2019-08-02 13:52:37 +0200261 StreamStatistician* statistician =
262 receive_statistics_->GetStatistician(kSsrc1);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000263 RtcpStatistics statistics;
Niels Möller9a9f18a2019-08-02 13:52:37 +0200264 statistician->GetStatistics(&statistics, true);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000265 // 20% = 51/255.
266 EXPECT_EQ(51u, statistics.fraction_lost);
267 EXPECT_EQ(1, statistics.packets_lost);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200268 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000269}
270
271TEST_F(ReceiveStatisticsTest, LossComputationWithDuplicates) {
272 // Lose 2 packets, but also receive 1 duplicate. Should actually count as
273 // only 1 packet being lost.
274 packet1_.SetSequenceNumber(1);
275 receive_statistics_->OnRtpPacket(packet1_);
276 packet1_.SetSequenceNumber(4);
277 receive_statistics_->OnRtpPacket(packet1_);
278 packet1_.SetSequenceNumber(4);
279 receive_statistics_->OnRtpPacket(packet1_);
280 packet1_.SetSequenceNumber(5);
281 receive_statistics_->OnRtpPacket(packet1_);
282
Niels Möller9a9f18a2019-08-02 13:52:37 +0200283 StreamStatistician* statistician =
284 receive_statistics_->GetStatistician(kSsrc1);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000285 RtcpStatistics statistics;
Niels Möller9a9f18a2019-08-02 13:52:37 +0200286 statistician->GetStatistics(&statistics, true);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000287 // 20% = 51/255.
288 EXPECT_EQ(51u, statistics.fraction_lost);
289 EXPECT_EQ(1, statistics.packets_lost);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200290 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000291}
292
293TEST_F(ReceiveStatisticsTest, LossComputationWithSequenceNumberWrapping) {
294 // First, test loss computation over a period that included a sequence number
295 // rollover.
296 packet1_.SetSequenceNumber(0xfffd);
297 receive_statistics_->OnRtpPacket(packet1_);
298 packet1_.SetSequenceNumber(0);
299 receive_statistics_->OnRtpPacket(packet1_);
300 packet1_.SetSequenceNumber(0xfffe);
301 receive_statistics_->OnRtpPacket(packet1_);
302 packet1_.SetSequenceNumber(1);
303 receive_statistics_->OnRtpPacket(packet1_);
304
305 // Only one packet was actually lost, 0xffff.
Niels Möller9a9f18a2019-08-02 13:52:37 +0200306 StreamStatistician* statistician =
307 receive_statistics_->GetStatistician(kSsrc1);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000308 RtcpStatistics statistics;
Niels Möller9a9f18a2019-08-02 13:52:37 +0200309 statistician->GetStatistics(&statistics, true);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000310 // 20% = 51/255.
311 EXPECT_EQ(51u, statistics.fraction_lost);
312 EXPECT_EQ(1, statistics.packets_lost);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200313 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000314
315 // Now test losing one packet *after* the rollover.
316 packet1_.SetSequenceNumber(3);
317 receive_statistics_->OnRtpPacket(packet1_);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200318 statistician->GetStatistics(&statistics, true);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000319 // 50% = 127/255.
320 EXPECT_EQ(127u, statistics.fraction_lost);
321 EXPECT_EQ(2, statistics.packets_lost);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200322 // 2 packets lost, 7 expected
323 EXPECT_EQ(28, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000324}
325
326TEST_F(ReceiveStatisticsTest, StreamRestartDoesntCountAsLoss) {
327 RtcpStatistics statistics;
Niels Möller87da1092019-05-24 14:04:28 +0200328 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000329
330 packet1_.SetSequenceNumber(0);
331 receive_statistics_->OnRtpPacket(packet1_);
332 packet1_.SetSequenceNumber(1);
333 receive_statistics_->OnRtpPacket(packet1_);
334
335 packet1_.SetSequenceNumber(400);
336 receive_statistics_->OnRtpPacket(packet1_);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200337 StreamStatistician* statistician =
338 receive_statistics_->GetStatistician(kSsrc1);
339 statistician->GetStatistics(&statistics, true);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000340 EXPECT_EQ(0, statistics.fraction_lost);
341 EXPECT_EQ(0, statistics.packets_lost);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200342 EXPECT_EQ(0, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000343
344 packet1_.SetSequenceNumber(401);
345 receive_statistics_->OnRtpPacket(packet1_);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200346 statistician->GetStatistics(&statistics, true);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000347 EXPECT_EQ(0, statistics.fraction_lost);
348 EXPECT_EQ(0, statistics.packets_lost);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200349 EXPECT_EQ(0, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000350}
351
352TEST_F(ReceiveStatisticsTest, CountsLossAfterStreamRestart) {
353 RtcpStatistics statistics;
Niels Möller87da1092019-05-24 14:04:28 +0200354 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000355
356 packet1_.SetSequenceNumber(0);
357 receive_statistics_->OnRtpPacket(packet1_);
358 packet1_.SetSequenceNumber(1);
359 receive_statistics_->OnRtpPacket(packet1_);
360
361 packet1_.SetSequenceNumber(400);
362 receive_statistics_->OnRtpPacket(packet1_);
363 packet1_.SetSequenceNumber(401);
364 receive_statistics_->OnRtpPacket(packet1_);
365 packet1_.SetSequenceNumber(403);
366 receive_statistics_->OnRtpPacket(packet1_);
367
Niels Möller9a9f18a2019-08-02 13:52:37 +0200368 StreamStatistician* statistician =
369 receive_statistics_->GetStatistician(kSsrc1);
370
371 statistician->GetStatistics(&statistics, true);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000372 EXPECT_EQ(1, statistics.packets_lost);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200373 // Is this reasonable? */
374 EXPECT_EQ(0, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000375}
376
377TEST_F(ReceiveStatisticsTest, StreamCanRestartAtSequenceNumberWrapAround) {
378 RtcpStatistics statistics;
Niels Möller87da1092019-05-24 14:04:28 +0200379 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000380
381 packet1_.SetSequenceNumber(0xffff - 401);
382 receive_statistics_->OnRtpPacket(packet1_);
383 packet1_.SetSequenceNumber(0xffff - 400);
384 receive_statistics_->OnRtpPacket(packet1_);
385
386 packet1_.SetSequenceNumber(0xffff);
387 receive_statistics_->OnRtpPacket(packet1_);
388 packet1_.SetSequenceNumber(0);
389 receive_statistics_->OnRtpPacket(packet1_);
390 packet1_.SetSequenceNumber(2);
391 receive_statistics_->OnRtpPacket(packet1_);
392
393 receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
394 true);
395 EXPECT_EQ(1, statistics.packets_lost);
396}
397
398TEST_F(ReceiveStatisticsTest, StreamRestartNeedsTwoConsecutivePackets) {
399 RtcpStatistics statistics;
Niels Möller87da1092019-05-24 14:04:28 +0200400 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000401
402 packet1_.SetSequenceNumber(400);
403 receive_statistics_->OnRtpPacket(packet1_);
404 packet1_.SetSequenceNumber(401);
405 receive_statistics_->OnRtpPacket(packet1_);
406
407 packet1_.SetSequenceNumber(1);
408 receive_statistics_->OnRtpPacket(packet1_);
409 packet1_.SetSequenceNumber(3);
410 receive_statistics_->OnRtpPacket(packet1_);
411 receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
412 true);
413 EXPECT_EQ(401u, statistics.extended_highest_sequence_number);
414
415 packet1_.SetSequenceNumber(4);
416 receive_statistics_->OnRtpPacket(packet1_);
417 receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
418 true);
419 EXPECT_EQ(4u, statistics.extended_highest_sequence_number);
420}
421
422TEST_F(ReceiveStatisticsTest, WrapsAroundExtendedHighestSequenceNumber) {
423 RtcpStatistics statistics;
424 packet1_.SetSequenceNumber(0xffff);
425 receive_statistics_->OnRtpPacket(packet1_);
426 receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
427 true);
428 EXPECT_EQ(0xffffu, statistics.extended_highest_sequence_number);
429
430 // Wrap around.
431 packet1_.SetSequenceNumber(1);
432 receive_statistics_->OnRtpPacket(packet1_);
433 receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
434 true);
435 EXPECT_EQ(0x10001u, statistics.extended_highest_sequence_number);
436
437 // Should be treated as out of order; shouldn't increment highest extended
438 // sequence number.
439 packet1_.SetSequenceNumber(0x10000 - 6);
440 receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
441 true);
442 EXPECT_EQ(0x10001u, statistics.extended_highest_sequence_number);
443
444 // Receive a couple packets then wrap around again.
Niels Möller87da1092019-05-24 14:04:28 +0200445 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000446 for (int i = 10; i < 0xffff; i += 150) {
447 packet1_.SetSequenceNumber(i);
448 receive_statistics_->OnRtpPacket(packet1_);
449 }
450 packet1_.SetSequenceNumber(1);
451 receive_statistics_->OnRtpPacket(packet1_);
452 receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
453 true);
454 EXPECT_EQ(0x20001u, statistics.extended_highest_sequence_number);
455}
456
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000457class RtpTestCallback : public StreamDataCountersCallback {
458 public:
459 RtpTestCallback()
460 : StreamDataCountersCallback(), num_calls_(0), ssrc_(0), stats_() {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +0000461 ~RtpTestCallback() override = default;
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000462
Danil Chapovalovdd7e2842018-03-09 15:37:03 +0000463 void DataCountersUpdated(const StreamDataCounters& counters,
464 uint32_t ssrc) override {
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000465 ssrc_ = ssrc;
466 stats_ = counters;
467 ++num_calls_;
468 }
469
asapersson@webrtc.org44149392015-02-04 08:34:47 +0000470 void MatchPacketCounter(const RtpPacketCounter& expected,
471 const RtpPacketCounter& actual) {
472 EXPECT_EQ(expected.payload_bytes, actual.payload_bytes);
473 EXPECT_EQ(expected.header_bytes, actual.header_bytes);
474 EXPECT_EQ(expected.padding_bytes, actual.padding_bytes);
475 EXPECT_EQ(expected.packets, actual.packets);
476 }
477
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000478 void Matches(uint32_t num_calls,
479 uint32_t ssrc,
480 const StreamDataCounters& expected) {
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000481 EXPECT_EQ(num_calls, num_calls_);
482 EXPECT_EQ(ssrc, ssrc_);
asapersson@webrtc.org44149392015-02-04 08:34:47 +0000483 MatchPacketCounter(expected.transmitted, stats_.transmitted);
484 MatchPacketCounter(expected.retransmitted, stats_.retransmitted);
485 MatchPacketCounter(expected.fec, stats_.fec);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000486 }
487
488 uint32_t num_calls_;
489 uint32_t ssrc_;
490 StreamDataCounters stats_;
491};
492
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000493TEST_F(ReceiveStatisticsTest, RtpCallbacks) {
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000494 RtpTestCallback callback;
Niels Möller12ebfa62019-08-06 16:04:12 +0200495 receive_statistics_ = ReceiveStatistics::Create(&clock_, &callback);
Niels Möller5304a322018-08-27 13:27:05 +0200496 receive_statistics_->EnableRetransmitDetection(kSsrc1, true);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000497
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000498 const size_t kHeaderLength = 20;
499 const size_t kPaddingLength = 9;
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000500
Niels Möller1f3206c2018-09-14 08:26:32 +0200501 // One packet with payload size kPacketSize1.
502 RtpPacketReceived packet1 =
503 CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 0);
504 receive_statistics_->OnRtpPacket(packet1);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000505 StreamDataCounters expected;
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000506 expected.transmitted.payload_bytes = kPacketSize1;
507 expected.transmitted.header_bytes = kHeaderLength;
508 expected.transmitted.padding_bytes = 0;
509 expected.transmitted.packets = 1;
510 expected.retransmitted.payload_bytes = 0;
511 expected.retransmitted.header_bytes = 0;
512 expected.retransmitted.padding_bytes = 0;
513 expected.retransmitted.packets = 0;
514 expected.fec.packets = 0;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000515 callback.Matches(1, kSsrc1, expected);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000516
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000517 // Another packet of size kPacketSize1 with 9 bytes padding.
Niels Möller1f3206c2018-09-14 08:26:32 +0200518 RtpPacketReceived packet2 =
519 CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 9);
520 packet2.SetSequenceNumber(packet1.SequenceNumber() + 1);
521 clock_.AdvanceTimeMilliseconds(5);
522 receive_statistics_->OnRtpPacket(packet2);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000523 expected.transmitted.payload_bytes = kPacketSize1 * 2;
524 expected.transmitted.header_bytes = kHeaderLength * 2;
525 expected.transmitted.padding_bytes = kPaddingLength;
526 expected.transmitted.packets = 2;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000527 callback.Matches(2, kSsrc1, expected);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000528
529 clock_.AdvanceTimeMilliseconds(5);
530 // Retransmit last packet.
Niels Möller1f3206c2018-09-14 08:26:32 +0200531 receive_statistics_->OnRtpPacket(packet2);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000532 expected.transmitted.payload_bytes = kPacketSize1 * 3;
533 expected.transmitted.header_bytes = kHeaderLength * 3;
534 expected.transmitted.padding_bytes = kPaddingLength * 2;
535 expected.transmitted.packets = 3;
536 expected.retransmitted.payload_bytes = kPacketSize1;
537 expected.retransmitted.header_bytes = kHeaderLength;
538 expected.retransmitted.padding_bytes = kPaddingLength;
539 expected.retransmitted.packets = 1;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000540 callback.Matches(3, kSsrc1, expected);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000541
asapersson@webrtc.org273fbbb2015-01-27 12:17:29 +0000542 // One FEC packet.
Niels Möller1f3206c2018-09-14 08:26:32 +0200543 packet1.SetSequenceNumber(packet2.SequenceNumber() + 1);
544 clock_.AdvanceTimeMilliseconds(5);
545 receive_statistics_->OnRtpPacket(packet1);
546 receive_statistics_->FecPacketReceived(packet1);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000547 expected.transmitted.payload_bytes = kPacketSize1 * 4;
548 expected.transmitted.header_bytes = kHeaderLength * 4;
549 expected.transmitted.packets = 4;
asapersson@webrtc.org273fbbb2015-01-27 12:17:29 +0000550 expected.fec.payload_bytes = kPacketSize1;
551 expected.fec.header_bytes = kHeaderLength;
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000552 expected.fec.packets = 1;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000553 callback.Matches(5, kSsrc1, expected);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000554}
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000555
Henrik Boströmcb755b02019-04-02 15:11:48 +0200556TEST_F(ReceiveStatisticsTest, LastPacketReceivedTimestamp) {
557 RtpTestCallback callback;
Niels Möller12ebfa62019-08-06 16:04:12 +0200558 receive_statistics_ = ReceiveStatistics::Create(&clock_, &callback);
Henrik Boströmcb755b02019-04-02 15:11:48 +0200559
560 clock_.AdvanceTimeMilliseconds(42);
561 receive_statistics_->OnRtpPacket(packet1_);
562 EXPECT_EQ(42, callback.stats_.last_packet_received_timestamp_ms);
563
564 clock_.AdvanceTimeMilliseconds(3);
565 receive_statistics_->OnRtpPacket(packet1_);
566 EXPECT_EQ(45, callback.stats_.last_packet_received_timestamp_ms);
567}
568
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000569TEST_F(ReceiveStatisticsTest, RtpCallbacksFecFirst) {
570 RtpTestCallback callback;
Niels Möller12ebfa62019-08-06 16:04:12 +0200571 receive_statistics_ = ReceiveStatistics::Create(&clock_, &callback);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000572
573 const uint32_t kHeaderLength = 20;
Niels Möller1f3206c2018-09-14 08:26:32 +0200574 RtpPacketReceived packet =
575 CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 0);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000576 // If first packet is FEC, ignore it.
Niels Möller1f3206c2018-09-14 08:26:32 +0200577 receive_statistics_->FecPacketReceived(packet);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000578 EXPECT_EQ(0u, callback.num_calls_);
579
Niels Möller1f3206c2018-09-14 08:26:32 +0200580 receive_statistics_->OnRtpPacket(packet);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000581 StreamDataCounters expected;
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000582 expected.transmitted.payload_bytes = kPacketSize1;
583 expected.transmitted.header_bytes = kHeaderLength;
584 expected.transmitted.padding_bytes = 0;
585 expected.transmitted.packets = 1;
586 expected.fec.packets = 0;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000587 callback.Matches(1, kSsrc1, expected);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000588
Niels Möller1f3206c2018-09-14 08:26:32 +0200589 receive_statistics_->FecPacketReceived(packet);
asapersson@webrtc.org273fbbb2015-01-27 12:17:29 +0000590 expected.fec.payload_bytes = kPacketSize1;
591 expected.fec.header_bytes = kHeaderLength;
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000592 expected.fec.packets = 1;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000593 callback.Matches(2, kSsrc1, expected);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000594}
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100595
596} // namespace
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000597} // namespace webrtc