blob: 81e66b6418f0ec58b8e6c27e540f3f1705841df3 [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öllerd77cc242019-08-22 09:40:25 +0200246 std::vector<rtcp::ReportBlock> report_blocks =
247 receive_statistics_->RtcpReportBlocks(1);
248 ASSERT_THAT(report_blocks, SizeIs(1));
249 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
250
251 // 20% = 51/255.
252 EXPECT_EQ(51u, report_blocks[0].fraction_lost());
253 EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed());
Niels Möller9a9f18a2019-08-02 13:52:37 +0200254 StreamStatistician* statistician =
255 receive_statistics_->GetStatistician(kSsrc1);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200256 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000257}
258
259TEST_F(ReceiveStatisticsTest, LossComputationWithReordering) {
260 packet1_.SetSequenceNumber(1);
261 receive_statistics_->OnRtpPacket(packet1_);
262 packet1_.SetSequenceNumber(3);
263 receive_statistics_->OnRtpPacket(packet1_);
264 packet1_.SetSequenceNumber(2);
265 receive_statistics_->OnRtpPacket(packet1_);
266 packet1_.SetSequenceNumber(5);
267 receive_statistics_->OnRtpPacket(packet1_);
268
Niels Möllerd77cc242019-08-22 09:40:25 +0200269 std::vector<rtcp::ReportBlock> report_blocks =
270 receive_statistics_->RtcpReportBlocks(1);
271 ASSERT_THAT(report_blocks, SizeIs(1));
272 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
273
274 // 20% = 51/255.
275 EXPECT_EQ(51u, report_blocks[0].fraction_lost());
276 EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed());
Niels Möller9a9f18a2019-08-02 13:52:37 +0200277 StreamStatistician* statistician =
278 receive_statistics_->GetStatistician(kSsrc1);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200279 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000280}
281
282TEST_F(ReceiveStatisticsTest, LossComputationWithDuplicates) {
283 // Lose 2 packets, but also receive 1 duplicate. Should actually count as
284 // only 1 packet being lost.
285 packet1_.SetSequenceNumber(1);
286 receive_statistics_->OnRtpPacket(packet1_);
287 packet1_.SetSequenceNumber(4);
288 receive_statistics_->OnRtpPacket(packet1_);
289 packet1_.SetSequenceNumber(4);
290 receive_statistics_->OnRtpPacket(packet1_);
291 packet1_.SetSequenceNumber(5);
292 receive_statistics_->OnRtpPacket(packet1_);
293
Niels Möllerd77cc242019-08-22 09:40:25 +0200294 std::vector<rtcp::ReportBlock> report_blocks =
295 receive_statistics_->RtcpReportBlocks(1);
296 ASSERT_THAT(report_blocks, SizeIs(1));
297 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
298
299 // 20% = 51/255.
300 EXPECT_EQ(51u, report_blocks[0].fraction_lost());
301 EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed());
Niels Möller9a9f18a2019-08-02 13:52:37 +0200302 StreamStatistician* statistician =
303 receive_statistics_->GetStatistician(kSsrc1);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200304 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000305}
306
307TEST_F(ReceiveStatisticsTest, LossComputationWithSequenceNumberWrapping) {
308 // First, test loss computation over a period that included a sequence number
309 // rollover.
310 packet1_.SetSequenceNumber(0xfffd);
311 receive_statistics_->OnRtpPacket(packet1_);
312 packet1_.SetSequenceNumber(0);
313 receive_statistics_->OnRtpPacket(packet1_);
314 packet1_.SetSequenceNumber(0xfffe);
315 receive_statistics_->OnRtpPacket(packet1_);
316 packet1_.SetSequenceNumber(1);
317 receive_statistics_->OnRtpPacket(packet1_);
318
319 // Only one packet was actually lost, 0xffff.
Niels Möllerd77cc242019-08-22 09:40:25 +0200320 std::vector<rtcp::ReportBlock> report_blocks =
321 receive_statistics_->RtcpReportBlocks(1);
322 ASSERT_THAT(report_blocks, SizeIs(1));
323 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
324
325 // 20% = 51/255.
326 EXPECT_EQ(51u, report_blocks[0].fraction_lost());
327 EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed());
Niels Möller9a9f18a2019-08-02 13:52:37 +0200328 StreamStatistician* statistician =
329 receive_statistics_->GetStatistician(kSsrc1);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200330 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000331
332 // Now test losing one packet *after* the rollover.
333 packet1_.SetSequenceNumber(3);
334 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd77cc242019-08-22 09:40:25 +0200335
336 report_blocks = receive_statistics_->RtcpReportBlocks(1);
337 ASSERT_THAT(report_blocks, SizeIs(1));
338 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
339
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000340 // 50% = 127/255.
Niels Möllerd77cc242019-08-22 09:40:25 +0200341 EXPECT_EQ(127u, report_blocks[0].fraction_lost());
342 EXPECT_EQ(2, report_blocks[0].cumulative_lost_signed());
Niels Möller9a9f18a2019-08-02 13:52:37 +0200343 // 2 packets lost, 7 expected
344 EXPECT_EQ(28, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000345}
346
347TEST_F(ReceiveStatisticsTest, StreamRestartDoesntCountAsLoss) {
Niels Möller87da1092019-05-24 14:04:28 +0200348 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000349
350 packet1_.SetSequenceNumber(0);
351 receive_statistics_->OnRtpPacket(packet1_);
352 packet1_.SetSequenceNumber(1);
353 receive_statistics_->OnRtpPacket(packet1_);
354
355 packet1_.SetSequenceNumber(400);
356 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd77cc242019-08-22 09:40:25 +0200357
358 std::vector<rtcp::ReportBlock> report_blocks =
359 receive_statistics_->RtcpReportBlocks(1);
360 ASSERT_THAT(report_blocks, SizeIs(1));
361 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
362
363 EXPECT_EQ(0, report_blocks[0].fraction_lost());
364 EXPECT_EQ(0, report_blocks[0].cumulative_lost_signed());
Niels Möller9a9f18a2019-08-02 13:52:37 +0200365 StreamStatistician* statistician =
366 receive_statistics_->GetStatistician(kSsrc1);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200367 EXPECT_EQ(0, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000368
369 packet1_.SetSequenceNumber(401);
370 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd77cc242019-08-22 09:40:25 +0200371 report_blocks = receive_statistics_->RtcpReportBlocks(1);
372 ASSERT_THAT(report_blocks, SizeIs(1));
373 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
374
375 EXPECT_EQ(0, report_blocks[0].fraction_lost());
376 EXPECT_EQ(0, report_blocks[0].cumulative_lost_signed());
Niels Möller9a9f18a2019-08-02 13:52:37 +0200377 EXPECT_EQ(0, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000378}
379
380TEST_F(ReceiveStatisticsTest, CountsLossAfterStreamRestart) {
Niels Möller87da1092019-05-24 14:04:28 +0200381 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000382
383 packet1_.SetSequenceNumber(0);
384 receive_statistics_->OnRtpPacket(packet1_);
385 packet1_.SetSequenceNumber(1);
386 receive_statistics_->OnRtpPacket(packet1_);
387
388 packet1_.SetSequenceNumber(400);
389 receive_statistics_->OnRtpPacket(packet1_);
390 packet1_.SetSequenceNumber(401);
391 receive_statistics_->OnRtpPacket(packet1_);
392 packet1_.SetSequenceNumber(403);
393 receive_statistics_->OnRtpPacket(packet1_);
394
Niels Möllerd77cc242019-08-22 09:40:25 +0200395 std::vector<rtcp::ReportBlock> report_blocks =
396 receive_statistics_->RtcpReportBlocks(1);
397 ASSERT_THAT(report_blocks, SizeIs(1));
398 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
399
400 EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed());
401
Niels Möller9a9f18a2019-08-02 13:52:37 +0200402 StreamStatistician* statistician =
403 receive_statistics_->GetStatistician(kSsrc1);
Niels Möller9a9f18a2019-08-02 13:52:37 +0200404 // Is this reasonable? */
405 EXPECT_EQ(0, statistician->GetFractionLostInPercent());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000406}
407
408TEST_F(ReceiveStatisticsTest, StreamCanRestartAtSequenceNumberWrapAround) {
Niels Möller87da1092019-05-24 14:04:28 +0200409 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000410
411 packet1_.SetSequenceNumber(0xffff - 401);
412 receive_statistics_->OnRtpPacket(packet1_);
413 packet1_.SetSequenceNumber(0xffff - 400);
414 receive_statistics_->OnRtpPacket(packet1_);
415
416 packet1_.SetSequenceNumber(0xffff);
417 receive_statistics_->OnRtpPacket(packet1_);
418 packet1_.SetSequenceNumber(0);
419 receive_statistics_->OnRtpPacket(packet1_);
420 packet1_.SetSequenceNumber(2);
421 receive_statistics_->OnRtpPacket(packet1_);
422
Niels Möllerd77cc242019-08-22 09:40:25 +0200423 std::vector<rtcp::ReportBlock> report_blocks =
424 receive_statistics_->RtcpReportBlocks(1);
425 ASSERT_THAT(report_blocks, SizeIs(1));
426 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
427
428 EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000429}
430
431TEST_F(ReceiveStatisticsTest, StreamRestartNeedsTwoConsecutivePackets) {
Niels Möller87da1092019-05-24 14:04:28 +0200432 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000433
434 packet1_.SetSequenceNumber(400);
435 receive_statistics_->OnRtpPacket(packet1_);
436 packet1_.SetSequenceNumber(401);
437 receive_statistics_->OnRtpPacket(packet1_);
438
439 packet1_.SetSequenceNumber(1);
440 receive_statistics_->OnRtpPacket(packet1_);
441 packet1_.SetSequenceNumber(3);
442 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd77cc242019-08-22 09:40:25 +0200443
444 std::vector<rtcp::ReportBlock> report_blocks =
445 receive_statistics_->RtcpReportBlocks(1);
446 ASSERT_THAT(report_blocks, SizeIs(1));
447 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
448
449 EXPECT_EQ(401u, report_blocks[0].extended_high_seq_num());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000450
451 packet1_.SetSequenceNumber(4);
452 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd77cc242019-08-22 09:40:25 +0200453
454 report_blocks = receive_statistics_->RtcpReportBlocks(1);
455 ASSERT_THAT(report_blocks, SizeIs(1));
456 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
457
458 EXPECT_EQ(4u, report_blocks[0].extended_high_seq_num());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000459}
460
461TEST_F(ReceiveStatisticsTest, WrapsAroundExtendedHighestSequenceNumber) {
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000462 packet1_.SetSequenceNumber(0xffff);
463 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd77cc242019-08-22 09:40:25 +0200464
465 std::vector<rtcp::ReportBlock> report_blocks =
466 receive_statistics_->RtcpReportBlocks(1);
467 ASSERT_THAT(report_blocks, SizeIs(1));
468 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
469
470 EXPECT_EQ(0xffffu, report_blocks[0].extended_high_seq_num());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000471
472 // Wrap around.
473 packet1_.SetSequenceNumber(1);
474 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd77cc242019-08-22 09:40:25 +0200475
476 report_blocks = receive_statistics_->RtcpReportBlocks(1);
477 ASSERT_THAT(report_blocks, SizeIs(1));
478 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
479
480 EXPECT_EQ(0x10001u, report_blocks[0].extended_high_seq_num());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000481
482 // Should be treated as out of order; shouldn't increment highest extended
483 // sequence number.
484 packet1_.SetSequenceNumber(0x10000 - 6);
Niels Möllerd77cc242019-08-22 09:40:25 +0200485 report_blocks = receive_statistics_->RtcpReportBlocks(1);
486 ASSERT_THAT(report_blocks, SizeIs(1));
487 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
488
489 EXPECT_EQ(0x10001u, report_blocks[0].extended_high_seq_num());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000490
491 // Receive a couple packets then wrap around again.
Niels Möller87da1092019-05-24 14:04:28 +0200492 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000493 for (int i = 10; i < 0xffff; i += 150) {
494 packet1_.SetSequenceNumber(i);
495 receive_statistics_->OnRtpPacket(packet1_);
496 }
497 packet1_.SetSequenceNumber(1);
498 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd77cc242019-08-22 09:40:25 +0200499 report_blocks = receive_statistics_->RtcpReportBlocks(1);
500 ASSERT_THAT(report_blocks, SizeIs(1));
501 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
502
503 EXPECT_EQ(0x20001u, report_blocks[0].extended_high_seq_num());
Danil Chapovalovb438b5a2018-12-05 14:55:46 +0000504}
505
Niels Möllerd7819652019-08-13 14:43:02 +0200506TEST_F(ReceiveStatisticsTest, StreamDataCounters) {
507 receive_statistics_ = ReceiveStatistics::Create(&clock_);
Niels Möller5304a322018-08-27 13:27:05 +0200508 receive_statistics_->EnableRetransmitDetection(kSsrc1, true);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000509
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000510 const size_t kHeaderLength = 20;
511 const size_t kPaddingLength = 9;
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000512
Niels Möller1f3206c2018-09-14 08:26:32 +0200513 // One packet with payload size kPacketSize1.
514 RtpPacketReceived packet1 =
515 CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 0);
516 receive_statistics_->OnRtpPacket(packet1);
Niels Möllerd7819652019-08-13 14:43:02 +0200517 StreamDataCounters counters = receive_statistics_->GetStatistician(kSsrc1)
518 ->GetReceiveStreamDataCounters();
519 EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1);
520 EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength);
521 EXPECT_EQ(counters.transmitted.padding_bytes, 0u);
522 EXPECT_EQ(counters.transmitted.packets, 1u);
523 EXPECT_EQ(counters.retransmitted.payload_bytes, 0u);
524 EXPECT_EQ(counters.retransmitted.header_bytes, 0u);
525 EXPECT_EQ(counters.retransmitted.padding_bytes, 0u);
526 EXPECT_EQ(counters.retransmitted.packets, 0u);
527 EXPECT_EQ(counters.fec.packets, 0u);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000528
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000529 // Another packet of size kPacketSize1 with 9 bytes padding.
Niels Möller1f3206c2018-09-14 08:26:32 +0200530 RtpPacketReceived packet2 =
531 CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 9);
532 packet2.SetSequenceNumber(packet1.SequenceNumber() + 1);
533 clock_.AdvanceTimeMilliseconds(5);
534 receive_statistics_->OnRtpPacket(packet2);
Niels Möllerd7819652019-08-13 14:43:02 +0200535 counters = receive_statistics_->GetStatistician(kSsrc1)
536 ->GetReceiveStreamDataCounters();
537 EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1 * 2);
538 EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength * 2);
539 EXPECT_EQ(counters.transmitted.padding_bytes, kPaddingLength);
540 EXPECT_EQ(counters.transmitted.packets, 2u);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000541
542 clock_.AdvanceTimeMilliseconds(5);
543 // Retransmit last packet.
Niels Möller1f3206c2018-09-14 08:26:32 +0200544 receive_statistics_->OnRtpPacket(packet2);
Niels Möllerd7819652019-08-13 14:43:02 +0200545 counters = receive_statistics_->GetStatistician(kSsrc1)
546 ->GetReceiveStreamDataCounters();
547 EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1 * 3);
548 EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength * 3);
549 EXPECT_EQ(counters.transmitted.padding_bytes, kPaddingLength * 2);
550 EXPECT_EQ(counters.transmitted.packets, 3u);
551 EXPECT_EQ(counters.retransmitted.payload_bytes, kPacketSize1);
552 EXPECT_EQ(counters.retransmitted.header_bytes, kHeaderLength);
553 EXPECT_EQ(counters.retransmitted.padding_bytes, kPaddingLength);
554 EXPECT_EQ(counters.retransmitted.packets, 1u);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000555
asapersson@webrtc.org273fbbb2015-01-27 12:17:29 +0000556 // One FEC packet.
Niels Möller1f3206c2018-09-14 08:26:32 +0200557 packet1.SetSequenceNumber(packet2.SequenceNumber() + 1);
558 clock_.AdvanceTimeMilliseconds(5);
559 receive_statistics_->OnRtpPacket(packet1);
560 receive_statistics_->FecPacketReceived(packet1);
Niels Möllerd7819652019-08-13 14:43:02 +0200561 counters = receive_statistics_->GetStatistician(kSsrc1)
562 ->GetReceiveStreamDataCounters();
563 EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1 * 4);
564 EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength * 4);
565 EXPECT_EQ(counters.transmitted.packets, 4u);
566 EXPECT_EQ(counters.fec.payload_bytes, kPacketSize1);
567 EXPECT_EQ(counters.fec.header_bytes, kHeaderLength);
568 EXPECT_EQ(counters.fec.packets, 1u);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000569}
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000570
Henrik Boströmcb755b02019-04-02 15:11:48 +0200571TEST_F(ReceiveStatisticsTest, LastPacketReceivedTimestamp) {
Niels Möllerd7819652019-08-13 14:43:02 +0200572 receive_statistics_ = ReceiveStatistics::Create(&clock_);
Henrik Boströmcb755b02019-04-02 15:11:48 +0200573
574 clock_.AdvanceTimeMilliseconds(42);
575 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd7819652019-08-13 14:43:02 +0200576 StreamDataCounters counters = receive_statistics_->GetStatistician(kSsrc1)
577 ->GetReceiveStreamDataCounters();
578
579 EXPECT_EQ(42, counters.last_packet_received_timestamp_ms);
Henrik Boströmcb755b02019-04-02 15:11:48 +0200580
581 clock_.AdvanceTimeMilliseconds(3);
582 receive_statistics_->OnRtpPacket(packet1_);
Niels Möllerd7819652019-08-13 14:43:02 +0200583 counters = receive_statistics_->GetStatistician(kSsrc1)
584 ->GetReceiveStreamDataCounters();
585 EXPECT_EQ(45, counters.last_packet_received_timestamp_ms);
Henrik Boströmcb755b02019-04-02 15:11:48 +0200586}
587
Niels Möllerd7819652019-08-13 14:43:02 +0200588TEST_F(ReceiveStatisticsTest, FecFirst) {
589 receive_statistics_ = ReceiveStatistics::Create(&clock_);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000590
591 const uint32_t kHeaderLength = 20;
Niels Möller1f3206c2018-09-14 08:26:32 +0200592 RtpPacketReceived packet =
593 CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 0);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000594 // If first packet is FEC, ignore it.
Niels Möller1f3206c2018-09-14 08:26:32 +0200595 receive_statistics_->FecPacketReceived(packet);
Niels Möllerd7819652019-08-13 14:43:02 +0200596
597 EXPECT_EQ(receive_statistics_->GetStatistician(kSsrc1), nullptr);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000598
Niels Möller1f3206c2018-09-14 08:26:32 +0200599 receive_statistics_->OnRtpPacket(packet);
Niels Möllerd7819652019-08-13 14:43:02 +0200600 StreamDataCounters counters = receive_statistics_->GetStatistician(kSsrc1)
601 ->GetReceiveStreamDataCounters();
602 EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1);
603 EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength);
604 EXPECT_EQ(counters.transmitted.padding_bytes, 0u);
605 EXPECT_EQ(counters.transmitted.packets, 1u);
606 EXPECT_EQ(counters.fec.packets, 0u);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000607
Niels Möller1f3206c2018-09-14 08:26:32 +0200608 receive_statistics_->FecPacketReceived(packet);
Niels Möllerd7819652019-08-13 14:43:02 +0200609 counters = receive_statistics_->GetStatistician(kSsrc1)
610 ->GetReceiveStreamDataCounters();
611 EXPECT_EQ(counters.transmitted.payload_bytes, kPacketSize1);
612 EXPECT_EQ(counters.transmitted.header_bytes, kHeaderLength);
613 EXPECT_EQ(counters.transmitted.padding_bytes, 0u);
614 EXPECT_EQ(counters.transmitted.packets, 1u);
615 EXPECT_EQ(counters.fec.payload_bytes, kPacketSize1);
616 EXPECT_EQ(counters.fec.header_bytes, kHeaderLength);
617 EXPECT_EQ(counters.fec.packets, 1u);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000618}
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100619
620} // namespace
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000621} // namespace webrtc