• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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