1 /*
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
11 #include "modules/rtp_rtcp/include/receive_statistics.h"
12
13 #include <memory>
14 #include <vector>
15
16 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
17 #include "rtc_base/random.h"
18 #include "system_wrappers/include/clock.h"
19 #include "test/gmock.h"
20 #include "test/gtest.h"
21
22 namespace webrtc {
23 namespace {
24
25 using ::testing::SizeIs;
26 using ::testing::UnorderedElementsAre;
27
28 const size_t kPacketSize1 = 100;
29 const size_t kPacketSize2 = 300;
30 const uint32_t kSsrc1 = 101;
31 const uint32_t kSsrc2 = 202;
32 const uint32_t kSsrc3 = 203;
33 const uint32_t kSsrc4 = 304;
34
CreateRtpPacket(uint32_t ssrc,size_t header_size,size_t payload_size,size_t padding_size)35 RtpPacketReceived 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);
52 packet.SetPadding(padding_size);
53 return packet;
54 }
55
CreateRtpPacket(uint32_t ssrc,size_t packet_size)56 RtpPacketReceived CreateRtpPacket(uint32_t ssrc, size_t packet_size) {
57 return CreateRtpPacket(ssrc, 12, packet_size - 12, 0);
58 }
59
IncrementSequenceNumber(RtpPacketReceived * packet,uint16_t incr)60 void IncrementSequenceNumber(RtpPacketReceived* packet, uint16_t incr) {
61 packet->SetSequenceNumber(packet->SequenceNumber() + incr);
62 }
63
IncrementSequenceNumber(RtpPacketReceived * packet)64 void IncrementSequenceNumber(RtpPacketReceived* packet) {
65 IncrementSequenceNumber(packet, 1);
66 }
67
68 class ReceiveStatisticsTest : public ::testing::Test {
69 public:
ReceiveStatisticsTest()70 ReceiveStatisticsTest()
71 : clock_(0), receive_statistics_(ReceiveStatistics::Create(&clock_)) {
72 packet1_ = CreateRtpPacket(kSsrc1, kPacketSize1);
73 packet2_ = CreateRtpPacket(kSsrc2, kPacketSize2);
74 }
75
76 protected:
77 SimulatedClock clock_;
78 std::unique_ptr<ReceiveStatistics> receive_statistics_;
79 RtpPacketReceived packet1_;
80 RtpPacketReceived packet2_;
81 };
82
TEST_F(ReceiveStatisticsTest,TwoIncomingSsrcs)83 TEST_F(ReceiveStatisticsTest, TwoIncomingSsrcs) {
84 receive_statistics_->OnRtpPacket(packet1_);
85 IncrementSequenceNumber(&packet1_);
86 receive_statistics_->OnRtpPacket(packet2_);
87 IncrementSequenceNumber(&packet2_);
88 clock_.AdvanceTimeMilliseconds(100);
89 receive_statistics_->OnRtpPacket(packet1_);
90 IncrementSequenceNumber(&packet1_);
91 receive_statistics_->OnRtpPacket(packet2_);
92 IncrementSequenceNumber(&packet2_);
93
94 StreamStatistician* statistician =
95 receive_statistics_->GetStatistician(kSsrc1);
96 ASSERT_TRUE(statistician != NULL);
97 EXPECT_GT(statistician->BitrateReceived(), 0u);
98 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);
103
104 statistician = receive_statistics_->GetStatistician(kSsrc2);
105 ASSERT_TRUE(statistician != NULL);
106 EXPECT_GT(statistician->BitrateReceived(), 0u);
107 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);
112
113 EXPECT_EQ(2u, receive_statistics_->RtcpReportBlocks(3).size());
114 // Add more incoming packets and verify that they are registered in both
115 // access methods.
116 receive_statistics_->OnRtpPacket(packet1_);
117 IncrementSequenceNumber(&packet1_);
118 receive_statistics_->OnRtpPacket(packet2_);
119 IncrementSequenceNumber(&packet2_);
120
121 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);
134 }
135
TEST_F(ReceiveStatisticsTest,RtcpReportBlocksReturnsMaxBlocksWhenThereAreMoreStatisticians)136 TEST_F(ReceiveStatisticsTest,
137 RtcpReportBlocksReturnsMaxBlocksWhenThereAreMoreStatisticians) {
138 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);
144
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
TEST_F(ReceiveStatisticsTest,RtcpReportBlocksReturnsAllObservedSsrcsWithMultipleCalls)150 TEST_F(ReceiveStatisticsTest,
151 RtcpReportBlocksReturnsAllObservedSsrcsWithMultipleCalls) {
152 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);
160
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
TEST_F(ReceiveStatisticsTest,ActiveStatisticians)177 TEST_F(ReceiveStatisticsTest, ActiveStatisticians) {
178 receive_statistics_->OnRtpPacket(packet1_);
179 IncrementSequenceNumber(&packet1_);
180 clock_.AdvanceTimeMilliseconds(1000);
181 receive_statistics_->OnRtpPacket(packet2_);
182 IncrementSequenceNumber(&packet2_);
183 // Nothing should time out since only 1000 ms has passed since the first
184 // packet came in.
185 EXPECT_EQ(2u, receive_statistics_->RtcpReportBlocks(3).size());
186
187 clock_.AdvanceTimeMilliseconds(7000);
188 // kSsrc1 should have timed out.
189 EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size());
190
191 clock_.AdvanceTimeMilliseconds(1000);
192 // kSsrc2 should have timed out.
193 EXPECT_EQ(0u, receive_statistics_->RtcpReportBlocks(3).size());
194
195 receive_statistics_->OnRtpPacket(packet1_);
196 IncrementSequenceNumber(&packet1_);
197 // kSsrc1 should be active again and the data counters should have survived.
198 EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size());
199 StreamStatistician* statistician =
200 receive_statistics_->GetStatistician(kSsrc1);
201 ASSERT_TRUE(statistician != NULL);
202 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);
207 }
208
TEST_F(ReceiveStatisticsTest,DoesntCreateRtcpReportBlockUntilFirstReceivedPacketForSsrc)209 TEST_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
216 receive_statistics_->OnRtpPacket(packet1_);
217 EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size());
218 }
219
TEST_F(ReceiveStatisticsTest,GetReceiveStreamDataCounters)220 TEST_F(ReceiveStatisticsTest, GetReceiveStreamDataCounters) {
221 receive_statistics_->OnRtpPacket(packet1_);
222 StreamStatistician* statistician =
223 receive_statistics_->GetStatistician(kSsrc1);
224 ASSERT_TRUE(statistician != NULL);
225
226 StreamDataCounters counters = statistician->GetReceiveStreamDataCounters();
227 EXPECT_GT(counters.first_packet_time_ms, -1);
228 EXPECT_EQ(1u, counters.transmitted.packets);
229
230 receive_statistics_->OnRtpPacket(packet1_);
231 counters = statistician->GetReceiveStreamDataCounters();
232 EXPECT_GT(counters.first_packet_time_ms, -1);
233 EXPECT_EQ(2u, counters.transmitted.packets);
234 }
235
TEST_F(ReceiveStatisticsTest,SimpleLossComputation)236 TEST_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
246 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());
254 StreamStatistician* statistician =
255 receive_statistics_->GetStatistician(kSsrc1);
256 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
257 }
258
TEST_F(ReceiveStatisticsTest,LossComputationWithReordering)259 TEST_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
269 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());
277 StreamStatistician* statistician =
278 receive_statistics_->GetStatistician(kSsrc1);
279 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
280 }
281
TEST_F(ReceiveStatisticsTest,LossComputationWithDuplicates)282 TEST_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
294 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());
302 StreamStatistician* statistician =
303 receive_statistics_->GetStatistician(kSsrc1);
304 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
305 }
306
TEST_F(ReceiveStatisticsTest,LossComputationWithSequenceNumberWrapping)307 TEST_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.
320 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());
328 StreamStatistician* statistician =
329 receive_statistics_->GetStatistician(kSsrc1);
330 EXPECT_EQ(20, statistician->GetFractionLostInPercent());
331
332 // Now test losing one packet *after* the rollover.
333 packet1_.SetSequenceNumber(3);
334 receive_statistics_->OnRtpPacket(packet1_);
335
336 report_blocks = receive_statistics_->RtcpReportBlocks(1);
337 ASSERT_THAT(report_blocks, SizeIs(1));
338 EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
339
340 // 50% = 127/255.
341 EXPECT_EQ(127u, report_blocks[0].fraction_lost());
342 EXPECT_EQ(2, report_blocks[0].cumulative_lost_signed());
343 // 2 packets lost, 7 expected
344 EXPECT_EQ(28, statistician->GetFractionLostInPercent());
345 }
346
TEST_F(ReceiveStatisticsTest,StreamRestartDoesntCountAsLoss)347 TEST_F(ReceiveStatisticsTest, StreamRestartDoesntCountAsLoss) {
348 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
349
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_);
357
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());
365 StreamStatistician* statistician =
366 receive_statistics_->GetStatistician(kSsrc1);
367 EXPECT_EQ(0, statistician->GetFractionLostInPercent());
368
369 packet1_.SetSequenceNumber(401);
370 receive_statistics_->OnRtpPacket(packet1_);
371 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());
377 EXPECT_EQ(0, statistician->GetFractionLostInPercent());
378 }
379
TEST_F(ReceiveStatisticsTest,CountsLossAfterStreamRestart)380 TEST_F(ReceiveStatisticsTest, CountsLossAfterStreamRestart) {
381 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
382
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
395 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
402 StreamStatistician* statistician =
403 receive_statistics_->GetStatistician(kSsrc1);
404 // Is this reasonable? */
405 EXPECT_EQ(0, statistician->GetFractionLostInPercent());
406 }
407
TEST_F(ReceiveStatisticsTest,StreamCanRestartAtSequenceNumberWrapAround)408 TEST_F(ReceiveStatisticsTest, StreamCanRestartAtSequenceNumberWrapAround) {
409 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
410
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
423 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());
429 }
430
TEST_F(ReceiveStatisticsTest,StreamRestartNeedsTwoConsecutivePackets)431 TEST_F(ReceiveStatisticsTest, StreamRestartNeedsTwoConsecutivePackets) {
432 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
433
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_);
443
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());
450
451 packet1_.SetSequenceNumber(4);
452 receive_statistics_->OnRtpPacket(packet1_);
453
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());
459 }
460
TEST_F(ReceiveStatisticsTest,WrapsAroundExtendedHighestSequenceNumber)461 TEST_F(ReceiveStatisticsTest, WrapsAroundExtendedHighestSequenceNumber) {
462 packet1_.SetSequenceNumber(0xffff);
463 receive_statistics_->OnRtpPacket(packet1_);
464
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());
471
472 // Wrap around.
473 packet1_.SetSequenceNumber(1);
474 receive_statistics_->OnRtpPacket(packet1_);
475
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());
481
482 // Should be treated as out of order; shouldn't increment highest extended
483 // sequence number.
484 packet1_.SetSequenceNumber(0x10000 - 6);
485 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());
490
491 // Receive a couple packets then wrap around again.
492 receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
493 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_);
499 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());
504 }
505
TEST_F(ReceiveStatisticsTest,StreamDataCounters)506 TEST_F(ReceiveStatisticsTest, StreamDataCounters) {
507 receive_statistics_ = ReceiveStatistics::Create(&clock_);
508 receive_statistics_->EnableRetransmitDetection(kSsrc1, true);
509
510 const size_t kHeaderLength = 20;
511 const size_t kPaddingLength = 9;
512
513 // One packet with payload size kPacketSize1.
514 RtpPacketReceived packet1 =
515 CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 0);
516 receive_statistics_->OnRtpPacket(packet1);
517 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);
528
529 // Another packet of size kPacketSize1 with 9 bytes padding.
530 RtpPacketReceived packet2 =
531 CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 9);
532 packet2.SetSequenceNumber(packet1.SequenceNumber() + 1);
533 clock_.AdvanceTimeMilliseconds(5);
534 receive_statistics_->OnRtpPacket(packet2);
535 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);
541
542 clock_.AdvanceTimeMilliseconds(5);
543 // Retransmit last packet.
544 receive_statistics_->OnRtpPacket(packet2);
545 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);
555 }
556
TEST_F(ReceiveStatisticsTest,LastPacketReceivedTimestamp)557 TEST_F(ReceiveStatisticsTest, LastPacketReceivedTimestamp) {
558 receive_statistics_ = ReceiveStatistics::Create(&clock_);
559
560 clock_.AdvanceTimeMilliseconds(42);
561 receive_statistics_->OnRtpPacket(packet1_);
562 StreamDataCounters counters = receive_statistics_->GetStatistician(kSsrc1)
563 ->GetReceiveStreamDataCounters();
564
565 EXPECT_EQ(42, counters.last_packet_received_timestamp_ms);
566
567 clock_.AdvanceTimeMilliseconds(3);
568 receive_statistics_->OnRtpPacket(packet1_);
569 counters = receive_statistics_->GetStatistician(kSsrc1)
570 ->GetReceiveStreamDataCounters();
571 EXPECT_EQ(45, counters.last_packet_received_timestamp_ms);
572 }
573
574 } // namespace
575 } // namespace webrtc
576