New const method StreamStatistician::GetStats

And a corresponding struct RtpReceiveStats. This is intended
to hold the information exposed via GetStats, which is quite
different from the stats reported to the peer via RTCP.

This is a preparation for moving ReceiveStatistics out of the
individual receive stream objects, and instead have a shared instance
owned by RtpStreamReceiverController or maybe Call.

Bug: webrtc:10679,chromium:677543
Change-Id: Ibb52ee769516ddc51da109b7f2319405693be5d5
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/148982
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28943}
diff --git a/modules/rtp_rtcp/source/receive_statistics_impl.cc b/modules/rtp_rtcp/source/receive_statistics_impl.cc
index ab896cb..f4ea2a0 100644
--- a/modules/rtp_rtcp/source/receive_statistics_impl.cc
+++ b/modules/rtp_rtcp/source/receive_statistics_impl.cc
@@ -166,6 +166,19 @@
   enable_retransmit_detection_ = enable;
 }
 
+RtpReceiveStats StreamStatisticianImpl::GetStats() const {
+  rtc::CritScope cs(&stream_lock_);
+  RtpReceiveStats stats;
+  stats.packets_lost = cumulative_loss_;
+  // TODO(nisse): Can we return a float instead?
+  // Note: internal jitter value is in Q4 and needs to be scaled by 1/16.
+  stats.jitter = jitter_q4_ >> 4;
+  stats.last_packet_received_timestamp_ms =
+      receive_counters_.last_packet_received_timestamp_ms;
+  stats.packet_counter = receive_counters_.transmitted;
+  return stats;
+}
+
 bool StreamStatisticianImpl::GetStatistics(RtcpStatistics* statistics,
                                            bool reset) {
   rtc::CritScope cs(&stream_lock_);
diff --git a/modules/rtp_rtcp/source/receive_statistics_impl.h b/modules/rtp_rtcp/source/receive_statistics_impl.h
index 04030d4..d76e431 100644
--- a/modules/rtp_rtcp/source/receive_statistics_impl.h
+++ b/modules/rtp_rtcp/source/receive_statistics_impl.h
@@ -32,6 +32,8 @@
                          int max_reordering_threshold);
   ~StreamStatisticianImpl() override;
 
+  RtpReceiveStats GetStats() const override;
+
   // |reset| here and in next method restarts calculation of fraction_lost stat.
   bool GetStatistics(RtcpStatistics* statistics, bool reset) override;
   bool GetActiveStatisticsAndReset(RtcpStatistics* statistics);
diff --git a/modules/rtp_rtcp/source/receive_statistics_unittest.cc b/modules/rtp_rtcp/source/receive_statistics_unittest.cc
index 44e53cf..81e66b6 100644
--- a/modules/rtp_rtcp/source/receive_statistics_unittest.cc
+++ b/modules/rtp_rtcp/source/receive_statistics_unittest.cc
@@ -243,13 +243,16 @@
   packet1_.SetSequenceNumber(5);
   receive_statistics_->OnRtpPacket(packet1_);
 
+  std::vector<rtcp::ReportBlock> report_blocks =
+      receive_statistics_->RtcpReportBlocks(1);
+  ASSERT_THAT(report_blocks, SizeIs(1));
+  EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
+
+  // 20% = 51/255.
+  EXPECT_EQ(51u, report_blocks[0].fraction_lost());
+  EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed());
   StreamStatistician* statistician =
       receive_statistics_->GetStatistician(kSsrc1);
-  RtcpStatistics statistics;
-  statistician->GetStatistics(&statistics, true);
-  // 20% = 51/255.
-  EXPECT_EQ(51u, statistics.fraction_lost);
-  EXPECT_EQ(1, statistics.packets_lost);
   EXPECT_EQ(20, statistician->GetFractionLostInPercent());
 }
 
@@ -263,13 +266,16 @@
   packet1_.SetSequenceNumber(5);
   receive_statistics_->OnRtpPacket(packet1_);
 
+  std::vector<rtcp::ReportBlock> report_blocks =
+      receive_statistics_->RtcpReportBlocks(1);
+  ASSERT_THAT(report_blocks, SizeIs(1));
+  EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
+
+  // 20% = 51/255.
+  EXPECT_EQ(51u, report_blocks[0].fraction_lost());
+  EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed());
   StreamStatistician* statistician =
       receive_statistics_->GetStatistician(kSsrc1);
-  RtcpStatistics statistics;
-  statistician->GetStatistics(&statistics, true);
-  // 20% = 51/255.
-  EXPECT_EQ(51u, statistics.fraction_lost);
-  EXPECT_EQ(1, statistics.packets_lost);
   EXPECT_EQ(20, statistician->GetFractionLostInPercent());
 }
 
@@ -285,13 +291,16 @@
   packet1_.SetSequenceNumber(5);
   receive_statistics_->OnRtpPacket(packet1_);
 
+  std::vector<rtcp::ReportBlock> report_blocks =
+      receive_statistics_->RtcpReportBlocks(1);
+  ASSERT_THAT(report_blocks, SizeIs(1));
+  EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
+
+  // 20% = 51/255.
+  EXPECT_EQ(51u, report_blocks[0].fraction_lost());
+  EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed());
   StreamStatistician* statistician =
       receive_statistics_->GetStatistician(kSsrc1);
-  RtcpStatistics statistics;
-  statistician->GetStatistics(&statistics, true);
-  // 20% = 51/255.
-  EXPECT_EQ(51u, statistics.fraction_lost);
-  EXPECT_EQ(1, statistics.packets_lost);
   EXPECT_EQ(20, statistician->GetFractionLostInPercent());
 }
 
@@ -308,28 +317,34 @@
   receive_statistics_->OnRtpPacket(packet1_);
 
   // Only one packet was actually lost, 0xffff.
+  std::vector<rtcp::ReportBlock> report_blocks =
+      receive_statistics_->RtcpReportBlocks(1);
+  ASSERT_THAT(report_blocks, SizeIs(1));
+  EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
+
+  // 20% = 51/255.
+  EXPECT_EQ(51u, report_blocks[0].fraction_lost());
+  EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed());
   StreamStatistician* statistician =
       receive_statistics_->GetStatistician(kSsrc1);
-  RtcpStatistics statistics;
-  statistician->GetStatistics(&statistics, true);
-  // 20% = 51/255.
-  EXPECT_EQ(51u, statistics.fraction_lost);
-  EXPECT_EQ(1, statistics.packets_lost);
   EXPECT_EQ(20, statistician->GetFractionLostInPercent());
 
   // Now test losing one packet *after* the rollover.
   packet1_.SetSequenceNumber(3);
   receive_statistics_->OnRtpPacket(packet1_);
-  statistician->GetStatistics(&statistics, true);
+
+  report_blocks = receive_statistics_->RtcpReportBlocks(1);
+  ASSERT_THAT(report_blocks, SizeIs(1));
+  EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
+
   // 50% = 127/255.
-  EXPECT_EQ(127u, statistics.fraction_lost);
-  EXPECT_EQ(2, statistics.packets_lost);
+  EXPECT_EQ(127u, report_blocks[0].fraction_lost());
+  EXPECT_EQ(2, report_blocks[0].cumulative_lost_signed());
   // 2 packets lost, 7 expected
   EXPECT_EQ(28, statistician->GetFractionLostInPercent());
 }
 
 TEST_F(ReceiveStatisticsTest, StreamRestartDoesntCountAsLoss) {
-  RtcpStatistics statistics;
   receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
 
   packet1_.SetSequenceNumber(0);
@@ -339,23 +354,30 @@
 
   packet1_.SetSequenceNumber(400);
   receive_statistics_->OnRtpPacket(packet1_);
+
+  std::vector<rtcp::ReportBlock> report_blocks =
+      receive_statistics_->RtcpReportBlocks(1);
+  ASSERT_THAT(report_blocks, SizeIs(1));
+  EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
+
+  EXPECT_EQ(0, report_blocks[0].fraction_lost());
+  EXPECT_EQ(0, report_blocks[0].cumulative_lost_signed());
   StreamStatistician* statistician =
       receive_statistics_->GetStatistician(kSsrc1);
-  statistician->GetStatistics(&statistics, true);
-  EXPECT_EQ(0, statistics.fraction_lost);
-  EXPECT_EQ(0, statistics.packets_lost);
   EXPECT_EQ(0, statistician->GetFractionLostInPercent());
 
   packet1_.SetSequenceNumber(401);
   receive_statistics_->OnRtpPacket(packet1_);
-  statistician->GetStatistics(&statistics, true);
-  EXPECT_EQ(0, statistics.fraction_lost);
-  EXPECT_EQ(0, statistics.packets_lost);
+  report_blocks = receive_statistics_->RtcpReportBlocks(1);
+  ASSERT_THAT(report_blocks, SizeIs(1));
+  EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
+
+  EXPECT_EQ(0, report_blocks[0].fraction_lost());
+  EXPECT_EQ(0, report_blocks[0].cumulative_lost_signed());
   EXPECT_EQ(0, statistician->GetFractionLostInPercent());
 }
 
 TEST_F(ReceiveStatisticsTest, CountsLossAfterStreamRestart) {
-  RtcpStatistics statistics;
   receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
 
   packet1_.SetSequenceNumber(0);
@@ -370,17 +392,20 @@
   packet1_.SetSequenceNumber(403);
   receive_statistics_->OnRtpPacket(packet1_);
 
+  std::vector<rtcp::ReportBlock> report_blocks =
+      receive_statistics_->RtcpReportBlocks(1);
+  ASSERT_THAT(report_blocks, SizeIs(1));
+  EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
+
+  EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed());
+
   StreamStatistician* statistician =
       receive_statistics_->GetStatistician(kSsrc1);
-
-  statistician->GetStatistics(&statistics, true);
-  EXPECT_EQ(1, statistics.packets_lost);
   // Is this reasonable? */
   EXPECT_EQ(0, statistician->GetFractionLostInPercent());
 }
 
 TEST_F(ReceiveStatisticsTest, StreamCanRestartAtSequenceNumberWrapAround) {
-  RtcpStatistics statistics;
   receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
 
   packet1_.SetSequenceNumber(0xffff - 401);
@@ -395,13 +420,15 @@
   packet1_.SetSequenceNumber(2);
   receive_statistics_->OnRtpPacket(packet1_);
 
-  receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
-                                                              true);
-  EXPECT_EQ(1, statistics.packets_lost);
+  std::vector<rtcp::ReportBlock> report_blocks =
+      receive_statistics_->RtcpReportBlocks(1);
+  ASSERT_THAT(report_blocks, SizeIs(1));
+  EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
+
+  EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed());
 }
 
 TEST_F(ReceiveStatisticsTest, StreamRestartNeedsTwoConsecutivePackets) {
-  RtcpStatistics statistics;
   receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
 
   packet1_.SetSequenceNumber(400);
@@ -413,38 +440,53 @@
   receive_statistics_->OnRtpPacket(packet1_);
   packet1_.SetSequenceNumber(3);
   receive_statistics_->OnRtpPacket(packet1_);
-  receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
-                                                              true);
-  EXPECT_EQ(401u, statistics.extended_highest_sequence_number);
+
+  std::vector<rtcp::ReportBlock> report_blocks =
+      receive_statistics_->RtcpReportBlocks(1);
+  ASSERT_THAT(report_blocks, SizeIs(1));
+  EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
+
+  EXPECT_EQ(401u, report_blocks[0].extended_high_seq_num());
 
   packet1_.SetSequenceNumber(4);
   receive_statistics_->OnRtpPacket(packet1_);
-  receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
-                                                              true);
-  EXPECT_EQ(4u, statistics.extended_highest_sequence_number);
+
+  report_blocks = receive_statistics_->RtcpReportBlocks(1);
+  ASSERT_THAT(report_blocks, SizeIs(1));
+  EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
+
+  EXPECT_EQ(4u, report_blocks[0].extended_high_seq_num());
 }
 
 TEST_F(ReceiveStatisticsTest, WrapsAroundExtendedHighestSequenceNumber) {
-  RtcpStatistics statistics;
   packet1_.SetSequenceNumber(0xffff);
   receive_statistics_->OnRtpPacket(packet1_);
-  receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
-                                                              true);
-  EXPECT_EQ(0xffffu, statistics.extended_highest_sequence_number);
+
+  std::vector<rtcp::ReportBlock> report_blocks =
+      receive_statistics_->RtcpReportBlocks(1);
+  ASSERT_THAT(report_blocks, SizeIs(1));
+  EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
+
+  EXPECT_EQ(0xffffu, report_blocks[0].extended_high_seq_num());
 
   // Wrap around.
   packet1_.SetSequenceNumber(1);
   receive_statistics_->OnRtpPacket(packet1_);
-  receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
-                                                              true);
-  EXPECT_EQ(0x10001u, statistics.extended_highest_sequence_number);
+
+  report_blocks = receive_statistics_->RtcpReportBlocks(1);
+  ASSERT_THAT(report_blocks, SizeIs(1));
+  EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
+
+  EXPECT_EQ(0x10001u, report_blocks[0].extended_high_seq_num());
 
   // Should be treated as out of order; shouldn't increment highest extended
   // sequence number.
   packet1_.SetSequenceNumber(0x10000 - 6);
-  receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
-                                                              true);
-  EXPECT_EQ(0x10001u, statistics.extended_highest_sequence_number);
+  report_blocks = receive_statistics_->RtcpReportBlocks(1);
+  ASSERT_THAT(report_blocks, SizeIs(1));
+  EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
+
+  EXPECT_EQ(0x10001u, report_blocks[0].extended_high_seq_num());
 
   // Receive a couple packets then wrap around again.
   receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
@@ -454,9 +496,11 @@
   }
   packet1_.SetSequenceNumber(1);
   receive_statistics_->OnRtpPacket(packet1_);
-  receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
-                                                              true);
-  EXPECT_EQ(0x20001u, statistics.extended_highest_sequence_number);
+  report_blocks = receive_statistics_->RtcpReportBlocks(1);
+  ASSERT_THAT(report_blocks, SizeIs(1));
+  EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
+
+  EXPECT_EQ(0x20001u, report_blocks[0].extended_high_seq_num());
 }
 
 TEST_F(ReceiveStatisticsTest, StreamDataCounters) {