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}
This commit is contained in:
Niels Möller 2019-08-22 09:40:25 +02:00 committed by Commit Bot
parent 74154e65e8
commit d77cc24f67
12 changed files with 166 additions and 102 deletions

View File

@ -724,34 +724,29 @@ CallReceiveStatistics ChannelReceive::GetRTCPStatistics() const {
// The jitter statistics is updated for each received RTP packet and is // The jitter statistics is updated for each received RTP packet and is
// based on received packets. // based on received packets.
RtcpStatistics statistics; RtpReceiveStats rtp_stats;
StreamStatistician* statistician = StreamStatistician* statistician =
rtp_receive_statistics_->GetStatistician(remote_ssrc_); rtp_receive_statistics_->GetStatistician(remote_ssrc_);
if (statistician) { if (statistician) {
statistician->GetStatistics(&statistics, rtp_stats = statistician->GetStats();
_rtpRtcpModule->RTCP() == RtcpMode::kOff);
} }
stats.cumulativeLost = statistics.packets_lost; stats.cumulativeLost = rtp_stats.packets_lost;
stats.jitterSamples = statistics.jitter; stats.jitterSamples = rtp_stats.jitter;
// --- RTT // --- RTT
stats.rttMs = GetRTT(); stats.rttMs = GetRTT();
// --- Data counters // --- Data counters
if (statistician) { if (statistician) {
StreamDataCounters data_counters =
statistician->GetReceiveStreamDataCounters();
if (use_standard_bytes_stats_) { if (use_standard_bytes_stats_) {
stats.bytesReceived = data_counters.transmitted.payload_bytes; stats.bytesReceived = rtp_stats.packet_counter.payload_bytes;
} else { } else {
stats.bytesReceived = data_counters.transmitted.payload_bytes + stats.bytesReceived = rtp_stats.packet_counter.TotalBytes();
data_counters.transmitted.header_bytes +
data_counters.transmitted.padding_bytes;
} }
stats.packetsReceived = data_counters.transmitted.packets; stats.packetsReceived = rtp_stats.packet_counter.packets;
stats.last_packet_received_timestamp_ms = stats.last_packet_received_timestamp_ms =
data_counters.last_packet_received_timestamp_ms; rtp_stats.last_packet_received_timestamp_ms;
} else { } else {
stats.bytesReceived = 0; stats.bytesReceived = 0;
stats.packetsReceived = 0; stats.packetsReceived = 0;

View File

@ -58,8 +58,7 @@ std::string VideoReceiveStream::Stats::ToString(int64_t time_ms) const {
ss << "jb_emitted_count: " << jitter_buffer_emitted_count << ", "; ss << "jb_emitted_count: " << jitter_buffer_emitted_count << ", ";
ss << "min_playout_delay_ms: " << min_playout_delay_ms << ", "; ss << "min_playout_delay_ms: " << min_playout_delay_ms << ", ";
ss << "sync_offset_ms: " << sync_offset_ms << ", "; ss << "sync_offset_ms: " << sync_offset_ms << ", ";
ss << "cum_loss: " << rtcp_stats.packets_lost << ", "; ss << "cum_loss: " << rtp_stats.packets_lost << ", ";
ss << "max_ext_seq: " << rtcp_stats.extended_highest_sequence_number << ", ";
ss << "nack: " << rtcp_packet_type_counts.nack_packets << ", "; ss << "nack: " << rtcp_packet_type_counts.nack_packets << ", ";
ss << "fir: " << rtcp_packet_type_counts.fir_packets << ", "; ss << "fir: " << rtcp_packet_type_counts.fir_packets << ", ";
ss << "pli: " << rtcp_packet_type_counts.pli_packets; ss << "pli: " << rtcp_packet_type_counts.pli_packets;

View File

@ -110,9 +110,8 @@ class VideoReceiveStream {
uint32_t ssrc = 0; uint32_t ssrc = 0;
std::string c_name; std::string c_name;
StreamDataCounters rtp_stats; RtpReceiveStats rtp_stats;
RtcpPacketTypeCounter rtcp_packet_type_counts; RtcpPacketTypeCounter rtcp_packet_type_counts;
RtcpStatistics rtcp_stats;
// Timing frame info: all important timestamps for a full lifetime of a // Timing frame info: all important timestamps for a full lifetime of a
// single 'timing frame'. // single 'timing frame'.

View File

@ -2795,14 +2795,12 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::GetVideoReceiverInfo(
info.codec_payload_type = stats.current_payload_type; info.codec_payload_type = stats.current_payload_type;
} }
if (use_standard_bytes_stats_) { if (use_standard_bytes_stats_) {
info.bytes_rcvd = stats.rtp_stats.transmitted.payload_bytes; info.bytes_rcvd = stats.rtp_stats.packet_counter.payload_bytes;
} else { } else {
info.bytes_rcvd = stats.rtp_stats.transmitted.payload_bytes + info.bytes_rcvd = stats.rtp_stats.packet_counter.TotalBytes();
stats.rtp_stats.transmitted.header_bytes +
stats.rtp_stats.transmitted.padding_bytes;
} }
info.packets_rcvd = stats.rtp_stats.transmitted.packets; info.packets_rcvd = stats.rtp_stats.packet_counter.packets;
info.packets_lost = stats.rtcp_stats.packets_lost; info.packets_lost = stats.rtp_stats.packets_lost;
info.framerate_rcvd = stats.network_frame_rate; info.framerate_rcvd = stats.network_frame_rate;
info.framerate_decoded = stats.decode_frame_rate; info.framerate_decoded = stats.decode_frame_rate;

View File

@ -5233,21 +5233,20 @@ TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesReceivePacketStatsCorrectly) {
FakeVideoReceiveStream* stream = AddRecvStream(); FakeVideoReceiveStream* stream = AddRecvStream();
webrtc::VideoReceiveStream::Stats stats; webrtc::VideoReceiveStream::Stats stats;
stats.rtp_stats.transmitted.payload_bytes = 2; stats.rtp_stats.packet_counter.payload_bytes = 2;
stats.rtp_stats.transmitted.header_bytes = 3; stats.rtp_stats.packet_counter.header_bytes = 3;
stats.rtp_stats.transmitted.padding_bytes = 4; stats.rtp_stats.packet_counter.padding_bytes = 4;
stats.rtp_stats.transmitted.packets = 5; stats.rtp_stats.packet_counter.packets = 5;
stats.rtcp_stats.packets_lost = 6; stats.rtp_stats.packets_lost = 6;
stats.rtcp_stats.fraction_lost = 7;
stream->SetStats(stats); stream->SetStats(stats);
cricket::VideoMediaInfo info; cricket::VideoMediaInfo info;
ASSERT_TRUE(channel_->GetStats(&info)); ASSERT_TRUE(channel_->GetStats(&info));
EXPECT_EQ(stats.rtp_stats.transmitted.payload_bytes, EXPECT_EQ(stats.rtp_stats.packet_counter.payload_bytes,
rtc::checked_cast<size_t>(info.receivers[0].bytes_rcvd)); rtc::checked_cast<size_t>(info.receivers[0].bytes_rcvd));
EXPECT_EQ(stats.rtp_stats.transmitted.packets, EXPECT_EQ(stats.rtp_stats.packet_counter.packets,
rtc::checked_cast<unsigned int>(info.receivers[0].packets_rcvd)); rtc::checked_cast<unsigned int>(info.receivers[0].packets_rcvd));
EXPECT_EQ(stats.rtcp_stats.packets_lost, info.receivers[0].packets_lost); EXPECT_EQ(stats.rtp_stats.packets_lost, info.receivers[0].packets_lost);
} }
TEST_F(WebRtcVideoChannelTest, TranslatesCallStatsCorrectly) { TEST_F(WebRtcVideoChannelTest, TranslatesCallStatsCorrectly) {

View File

@ -22,6 +22,7 @@
#include "modules/rtp_rtcp/include/rtcp_statistics.h" #include "modules/rtp_rtcp/include/rtcp_statistics.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h" #include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
#include "rtc_base/deprecation.h"
namespace webrtc { namespace webrtc {
@ -40,11 +41,16 @@ class StreamStatistician {
public: public:
virtual ~StreamStatistician(); virtual ~StreamStatistician();
virtual RtpReceiveStats GetStats() const = 0;
// TODO(nisse): Delete, migrate users to the above the GetStats method.
RTC_DEPRECATED
virtual bool GetStatistics(RtcpStatistics* statistics, bool reset) = 0; virtual bool GetStatistics(RtcpStatistics* statistics, bool reset) = 0;
// Returns average over the stream life time. // Returns average over the stream life time.
virtual absl::optional<int> GetFractionLostInPercent() const = 0; virtual absl::optional<int> GetFractionLostInPercent() const = 0;
// TODO(nisse): Delete, migrate users to the above the GetStats method.
// Gets received stream data counters (includes reset counter values). // Gets received stream data counters (includes reset counter values).
virtual StreamDataCounters GetReceiveStreamDataCounters() const = 0; virtual StreamDataCounters GetReceiveStreamDataCounters() const = 0;

View File

@ -444,6 +444,20 @@ class StreamDataCountersCallback {
uint32_t ssrc) = 0; uint32_t ssrc) = 0;
}; };
// Information exposed through the GetStats api.
struct RtpReceiveStats {
// |packets_lost| and |jitter| are defined by RFC 3550, and exposed in the
// RTCReceivedRtpStreamStats dictionary, see
// https://w3c.github.io/webrtc-stats/#receivedrtpstats-dict*
int32_t packets_lost = 0;
uint32_t jitter = 0;
// Timestamp and counters exposed in RTCInboundRtpStreamStats, see
// https://w3c.github.io/webrtc-stats/#inboundrtpstats-dict*
absl::optional<int64_t> last_packet_received_timestamp_ms;
RtpPacketCounter packet_counter;
};
class RtcpAckObserver { class RtcpAckObserver {
public: public:
// This method is called on received report blocks matching the sender ssrc. // This method is called on received report blocks matching the sender ssrc.

View File

@ -166,6 +166,19 @@ void StreamStatisticianImpl::EnableRetransmitDetection(bool enable) {
enable_retransmit_detection_ = enable; 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 StreamStatisticianImpl::GetStatistics(RtcpStatistics* statistics,
bool reset) { bool reset) {
rtc::CritScope cs(&stream_lock_); rtc::CritScope cs(&stream_lock_);

View File

@ -32,6 +32,8 @@ class StreamStatisticianImpl : public StreamStatistician,
int max_reordering_threshold); int max_reordering_threshold);
~StreamStatisticianImpl() override; ~StreamStatisticianImpl() override;
RtpReceiveStats GetStats() const override;
// |reset| here and in next method restarts calculation of fraction_lost stat. // |reset| here and in next method restarts calculation of fraction_lost stat.
bool GetStatistics(RtcpStatistics* statistics, bool reset) override; bool GetStatistics(RtcpStatistics* statistics, bool reset) override;
bool GetActiveStatisticsAndReset(RtcpStatistics* statistics); bool GetActiveStatisticsAndReset(RtcpStatistics* statistics);

View File

@ -243,13 +243,16 @@ TEST_F(ReceiveStatisticsTest, SimpleLossComputation) {
packet1_.SetSequenceNumber(5); packet1_.SetSequenceNumber(5);
receive_statistics_->OnRtpPacket(packet1_); 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 = StreamStatistician* statistician =
receive_statistics_->GetStatistician(kSsrc1); 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()); EXPECT_EQ(20, statistician->GetFractionLostInPercent());
} }
@ -263,13 +266,16 @@ TEST_F(ReceiveStatisticsTest, LossComputationWithReordering) {
packet1_.SetSequenceNumber(5); packet1_.SetSequenceNumber(5);
receive_statistics_->OnRtpPacket(packet1_); 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 = StreamStatistician* statistician =
receive_statistics_->GetStatistician(kSsrc1); 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()); EXPECT_EQ(20, statistician->GetFractionLostInPercent());
} }
@ -285,13 +291,16 @@ TEST_F(ReceiveStatisticsTest, LossComputationWithDuplicates) {
packet1_.SetSequenceNumber(5); packet1_.SetSequenceNumber(5);
receive_statistics_->OnRtpPacket(packet1_); 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 = StreamStatistician* statistician =
receive_statistics_->GetStatistician(kSsrc1); 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()); EXPECT_EQ(20, statistician->GetFractionLostInPercent());
} }
@ -308,28 +317,34 @@ TEST_F(ReceiveStatisticsTest, LossComputationWithSequenceNumberWrapping) {
receive_statistics_->OnRtpPacket(packet1_); receive_statistics_->OnRtpPacket(packet1_);
// Only one packet was actually lost, 0xffff. // 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 = StreamStatistician* statistician =
receive_statistics_->GetStatistician(kSsrc1); 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()); EXPECT_EQ(20, statistician->GetFractionLostInPercent());
// Now test losing one packet *after* the rollover. // Now test losing one packet *after* the rollover.
packet1_.SetSequenceNumber(3); packet1_.SetSequenceNumber(3);
receive_statistics_->OnRtpPacket(packet1_); 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. // 50% = 127/255.
EXPECT_EQ(127u, statistics.fraction_lost); EXPECT_EQ(127u, report_blocks[0].fraction_lost());
EXPECT_EQ(2, statistics.packets_lost); EXPECT_EQ(2, report_blocks[0].cumulative_lost_signed());
// 2 packets lost, 7 expected // 2 packets lost, 7 expected
EXPECT_EQ(28, statistician->GetFractionLostInPercent()); EXPECT_EQ(28, statistician->GetFractionLostInPercent());
} }
TEST_F(ReceiveStatisticsTest, StreamRestartDoesntCountAsLoss) { TEST_F(ReceiveStatisticsTest, StreamRestartDoesntCountAsLoss) {
RtcpStatistics statistics;
receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200); receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
packet1_.SetSequenceNumber(0); packet1_.SetSequenceNumber(0);
@ -339,23 +354,30 @@ TEST_F(ReceiveStatisticsTest, StreamRestartDoesntCountAsLoss) {
packet1_.SetSequenceNumber(400); packet1_.SetSequenceNumber(400);
receive_statistics_->OnRtpPacket(packet1_); 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 = StreamStatistician* statistician =
receive_statistics_->GetStatistician(kSsrc1); 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()); EXPECT_EQ(0, statistician->GetFractionLostInPercent());
packet1_.SetSequenceNumber(401); packet1_.SetSequenceNumber(401);
receive_statistics_->OnRtpPacket(packet1_); receive_statistics_->OnRtpPacket(packet1_);
statistician->GetStatistics(&statistics, true); report_blocks = receive_statistics_->RtcpReportBlocks(1);
EXPECT_EQ(0, statistics.fraction_lost); ASSERT_THAT(report_blocks, SizeIs(1));
EXPECT_EQ(0, statistics.packets_lost); 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()); EXPECT_EQ(0, statistician->GetFractionLostInPercent());
} }
TEST_F(ReceiveStatisticsTest, CountsLossAfterStreamRestart) { TEST_F(ReceiveStatisticsTest, CountsLossAfterStreamRestart) {
RtcpStatistics statistics;
receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200); receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
packet1_.SetSequenceNumber(0); packet1_.SetSequenceNumber(0);
@ -370,17 +392,20 @@ TEST_F(ReceiveStatisticsTest, CountsLossAfterStreamRestart) {
packet1_.SetSequenceNumber(403); packet1_.SetSequenceNumber(403);
receive_statistics_->OnRtpPacket(packet1_); 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 = StreamStatistician* statistician =
receive_statistics_->GetStatistician(kSsrc1); receive_statistics_->GetStatistician(kSsrc1);
statistician->GetStatistics(&statistics, true);
EXPECT_EQ(1, statistics.packets_lost);
// Is this reasonable? */ // Is this reasonable? */
EXPECT_EQ(0, statistician->GetFractionLostInPercent()); EXPECT_EQ(0, statistician->GetFractionLostInPercent());
} }
TEST_F(ReceiveStatisticsTest, StreamCanRestartAtSequenceNumberWrapAround) { TEST_F(ReceiveStatisticsTest, StreamCanRestartAtSequenceNumberWrapAround) {
RtcpStatistics statistics;
receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200); receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
packet1_.SetSequenceNumber(0xffff - 401); packet1_.SetSequenceNumber(0xffff - 401);
@ -395,13 +420,15 @@ TEST_F(ReceiveStatisticsTest, StreamCanRestartAtSequenceNumberWrapAround) {
packet1_.SetSequenceNumber(2); packet1_.SetSequenceNumber(2);
receive_statistics_->OnRtpPacket(packet1_); receive_statistics_->OnRtpPacket(packet1_);
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics, std::vector<rtcp::ReportBlock> report_blocks =
true); receive_statistics_->RtcpReportBlocks(1);
EXPECT_EQ(1, statistics.packets_lost); 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) { TEST_F(ReceiveStatisticsTest, StreamRestartNeedsTwoConsecutivePackets) {
RtcpStatistics statistics;
receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200); receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
packet1_.SetSequenceNumber(400); packet1_.SetSequenceNumber(400);
@ -413,38 +440,53 @@ TEST_F(ReceiveStatisticsTest, StreamRestartNeedsTwoConsecutivePackets) {
receive_statistics_->OnRtpPacket(packet1_); receive_statistics_->OnRtpPacket(packet1_);
packet1_.SetSequenceNumber(3); packet1_.SetSequenceNumber(3);
receive_statistics_->OnRtpPacket(packet1_); receive_statistics_->OnRtpPacket(packet1_);
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
true); std::vector<rtcp::ReportBlock> report_blocks =
EXPECT_EQ(401u, statistics.extended_highest_sequence_number); 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); packet1_.SetSequenceNumber(4);
receive_statistics_->OnRtpPacket(packet1_); receive_statistics_->OnRtpPacket(packet1_);
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
true); report_blocks = receive_statistics_->RtcpReportBlocks(1);
EXPECT_EQ(4u, statistics.extended_highest_sequence_number); 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) { TEST_F(ReceiveStatisticsTest, WrapsAroundExtendedHighestSequenceNumber) {
RtcpStatistics statistics;
packet1_.SetSequenceNumber(0xffff); packet1_.SetSequenceNumber(0xffff);
receive_statistics_->OnRtpPacket(packet1_); receive_statistics_->OnRtpPacket(packet1_);
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
true); std::vector<rtcp::ReportBlock> report_blocks =
EXPECT_EQ(0xffffu, statistics.extended_highest_sequence_number); 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. // Wrap around.
packet1_.SetSequenceNumber(1); packet1_.SetSequenceNumber(1);
receive_statistics_->OnRtpPacket(packet1_); receive_statistics_->OnRtpPacket(packet1_);
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
true); report_blocks = receive_statistics_->RtcpReportBlocks(1);
EXPECT_EQ(0x10001u, statistics.extended_highest_sequence_number); 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 // Should be treated as out of order; shouldn't increment highest extended
// sequence number. // sequence number.
packet1_.SetSequenceNumber(0x10000 - 6); packet1_.SetSequenceNumber(0x10000 - 6);
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics, report_blocks = receive_statistics_->RtcpReportBlocks(1);
true); ASSERT_THAT(report_blocks, SizeIs(1));
EXPECT_EQ(0x10001u, statistics.extended_highest_sequence_number); 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 a couple packets then wrap around again.
receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200); receive_statistics_->SetMaxReorderingThreshold(kSsrc1, 200);
@ -454,9 +496,11 @@ TEST_F(ReceiveStatisticsTest, WrapsAroundExtendedHighestSequenceNumber) {
} }
packet1_.SetSequenceNumber(1); packet1_.SetSequenceNumber(1);
receive_statistics_->OnRtpPacket(packet1_); receive_statistics_->OnRtpPacket(packet1_);
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics, report_blocks = receive_statistics_->RtcpReportBlocks(1);
true); ASSERT_THAT(report_blocks, SizeIs(1));
EXPECT_EQ(0x20001u, statistics.extended_highest_sequence_number); EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc());
EXPECT_EQ(0x20001u, report_blocks[0].extended_high_seq_num());
} }
TEST_F(ReceiveStatisticsTest, StreamDataCounters) { TEST_F(ReceiveStatisticsTest, StreamDataCounters) {

View File

@ -115,17 +115,13 @@ TEST_F(StatsEndToEndTest, GetStats) {
receive_stats_filled_["FrameRendered"] |= stats.render_frame_rate != 0; receive_stats_filled_["FrameRendered"] |= stats.render_frame_rate != 0;
receive_stats_filled_["StatisticsUpdated"] |= receive_stats_filled_["StatisticsUpdated"] |=
stats.rtcp_stats.packets_lost != 0 || stats.rtp_stats.packets_lost != 0 || stats.rtp_stats.jitter != 0;
stats.rtcp_stats.extended_highest_sequence_number != 0 ||
stats.rtcp_stats.fraction_lost != 0 || stats.rtcp_stats.jitter != 0;
receive_stats_filled_["DataCountersUpdated"] |= receive_stats_filled_["DataCountersUpdated"] |=
stats.rtp_stats.transmitted.payload_bytes != 0 || stats.rtp_stats.packet_counter.payload_bytes != 0 ||
stats.rtp_stats.fec.packets != 0 || stats.rtp_stats.packet_counter.header_bytes != 0 ||
stats.rtp_stats.transmitted.header_bytes != 0 || stats.rtp_stats.packet_counter.packets != 0 ||
stats.rtp_stats.transmitted.packets != 0 || stats.rtp_stats.packet_counter.padding_bytes != 0;
stats.rtp_stats.transmitted.padding_bytes != 0 ||
stats.rtp_stats.retransmitted.packets != 0;
receive_stats_filled_["CodecStats"] |= stats.target_delay_ms != 0; receive_stats_filled_["CodecStats"] |= stats.target_delay_ms != 0;
@ -445,7 +441,7 @@ TEST_F(StatsEndToEndTest, TestReceivedRtpPacketStats) {
Action OnSendRtp(const uint8_t* packet, size_t length) override { Action OnSendRtp(const uint8_t* packet, size_t length) override {
if (sent_rtp_ >= kNumRtpPacketsToSend) { if (sent_rtp_ >= kNumRtpPacketsToSend) {
VideoReceiveStream::Stats stats = receive_stream_->GetStats(); VideoReceiveStream::Stats stats = receive_stream_->GetStats();
if (kNumRtpPacketsToSend == stats.rtp_stats.transmitted.packets) { if (kNumRtpPacketsToSend == stats.rtp_stats.packet_counter.packets) {
observation_complete_.Set(); observation_complete_.Set();
} }
return DROP_PACKET; return DROP_PACKET;

View File

@ -463,8 +463,7 @@ VideoReceiveStream::Stats VideoReceiveStream::GetStats() const {
StreamStatistician* statistician = StreamStatistician* statistician =
rtp_receive_statistics_->GetStatistician(stats.ssrc); rtp_receive_statistics_->GetStatistician(stats.ssrc);
if (statistician) { if (statistician) {
statistician->GetStatistics(&stats.rtcp_stats, /*reset=*/false); stats.rtp_stats = statistician->GetStats();
stats.rtp_stats = statistician->GetReceiveStreamDataCounters();
stats.total_bitrate_bps = statistician->BitrateReceived(); stats.total_bitrate_bps = statistician->BitrateReceived();
} }
if (config_.rtp.rtx_ssrc) { if (config_.rtp.rtx_ssrc) {