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) {