Move RTP stats histograms from VieChannel to SendStatisticsProxy.
Also slice for screensharing. BUG= R=mflodman@webrtc.org, pbos@webrtc.org Review URL: https://codereview.webrtc.org/1734933002 . Cr-Commit-Position: refs/heads/master@{#11822}
This commit is contained in:
parent
681e20e008
commit
22c2b4814a
@ -11,6 +11,7 @@
|
||||
#ifndef WEBRTC_COMMON_TYPES_H_
|
||||
#define WEBRTC_COMMON_TYPES_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -791,6 +792,17 @@ struct RtpPacketCounter {
|
||||
packets += other.packets;
|
||||
}
|
||||
|
||||
void Subtract(const RtpPacketCounter& other) {
|
||||
assert(header_bytes >= other.header_bytes);
|
||||
header_bytes -= other.header_bytes;
|
||||
assert(payload_bytes >= other.payload_bytes);
|
||||
payload_bytes -= other.payload_bytes;
|
||||
assert(padding_bytes >= other.padding_bytes);
|
||||
padding_bytes -= other.padding_bytes;
|
||||
assert(packets >= other.packets);
|
||||
packets -= other.packets;
|
||||
}
|
||||
|
||||
void AddPacket(size_t packet_length, const RTPHeader& header) {
|
||||
++packets;
|
||||
header_bytes += header.headerLength;
|
||||
@ -825,6 +837,18 @@ struct StreamDataCounters {
|
||||
}
|
||||
}
|
||||
|
||||
void Subtract(const StreamDataCounters& other) {
|
||||
transmitted.Subtract(other.transmitted);
|
||||
retransmitted.Subtract(other.retransmitted);
|
||||
fec.Subtract(other.fec);
|
||||
if (other.first_packet_time_ms != -1 &&
|
||||
(other.first_packet_time_ms > first_packet_time_ms ||
|
||||
first_packet_time_ms == -1)) {
|
||||
// Use youngest time.
|
||||
first_packet_time_ms = other.first_packet_time_ms;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t TimeSinceFirstPacketInMs(int64_t now_ms) const {
|
||||
return (first_packet_time_ms == -1) ? -1 : (now_ms - first_packet_time_ms);
|
||||
}
|
||||
|
||||
@ -2246,20 +2246,19 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx,
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(video_prefix + "EncodeTimeInMs"));
|
||||
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.DecodeTimeInMs"));
|
||||
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(
|
||||
"WebRTC.Video.BitrateSentInKbps"));
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(video_prefix + "BitrateSentInKbps"));
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(
|
||||
"WebRTC.Video.BitrateReceivedInKbps"));
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(
|
||||
"WebRTC.Video.MediaBitrateSentInKbps"));
|
||||
EXPECT_EQ(1,
|
||||
test::NumHistogramSamples(video_prefix + "MediaBitrateSentInKbps"));
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(
|
||||
"WebRTC.Video.MediaBitrateReceivedInKbps"));
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(
|
||||
"WebRTC.Video.PaddingBitrateSentInKbps"));
|
||||
EXPECT_EQ(
|
||||
1, test::NumHistogramSamples(video_prefix + "PaddingBitrateSentInKbps"));
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(
|
||||
"WebRTC.Video.PaddingBitrateReceivedInKbps"));
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(
|
||||
"WebRTC.Video.RetransmittedBitrateSentInKbps"));
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(video_prefix +
|
||||
"RetransmittedBitrateSentInKbps"));
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(
|
||||
"WebRTC.Video.RetransmittedBitrateReceivedInKbps"));
|
||||
|
||||
|
||||
@ -98,10 +98,26 @@ SendStatisticsProxy::UmaSamplesContainer::UmaSamplesContainer(
|
||||
input_frame_rate_tracker_(100u, 10u),
|
||||
sent_frame_rate_tracker_(100u, 10u),
|
||||
first_rtcp_stats_time_ms_(-1),
|
||||
first_rtp_stats_time_ms_(-1),
|
||||
start_stats_(stats) {}
|
||||
|
||||
SendStatisticsProxy::UmaSamplesContainer::~UmaSamplesContainer() {}
|
||||
|
||||
void AccumulateRtpStats(const VideoSendStream::Stats& stats,
|
||||
const VideoSendStream::Config& config,
|
||||
StreamDataCounters* total_rtp_stats,
|
||||
StreamDataCounters* rtx_stats) {
|
||||
for (auto it : stats.substreams) {
|
||||
const std::vector<uint32_t> rtx_ssrcs = config.rtp.rtx.ssrcs;
|
||||
if (std::find(rtx_ssrcs.begin(), rtx_ssrcs.end(), it.first) !=
|
||||
rtx_ssrcs.end()) {
|
||||
rtx_stats->Add(it.second.rtp_stats);
|
||||
} else {
|
||||
total_rtp_stats->Add(it.second.rtp_stats);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms(
|
||||
const VideoSendStream::Config& config,
|
||||
const VideoSendStream::Stats& current_stats) {
|
||||
@ -223,6 +239,51 @@ void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (first_rtp_stats_time_ms_ != -1) {
|
||||
int64_t elapsed_sec =
|
||||
(clock_->TimeInMilliseconds() - first_rtp_stats_time_ms_) / 1000;
|
||||
if (elapsed_sec >= metrics::kMinRunTimeInSeconds) {
|
||||
StreamDataCounters rtp;
|
||||
StreamDataCounters rtx;
|
||||
AccumulateRtpStats(current_stats, config, &rtp, &rtx);
|
||||
StreamDataCounters start_rtp;
|
||||
StreamDataCounters start_rtx;
|
||||
AccumulateRtpStats(start_stats_, config, &start_rtp, &start_rtx);
|
||||
rtp.Subtract(start_rtp);
|
||||
rtx.Subtract(start_rtx);
|
||||
StreamDataCounters rtp_rtx = rtp;
|
||||
rtp_rtx.Add(rtx);
|
||||
|
||||
RTC_HISTOGRAMS_COUNTS_10000(
|
||||
kIndex, uma_prefix_ + "BitrateSentInKbps",
|
||||
static_cast<int>(rtp_rtx.transmitted.TotalBytes() * 8 / elapsed_sec /
|
||||
1000));
|
||||
RTC_HISTOGRAMS_COUNTS_10000(
|
||||
kIndex, uma_prefix_ + "MediaBitrateSentInKbps",
|
||||
static_cast<int>(rtp.MediaPayloadBytes() * 8 / elapsed_sec / 1000));
|
||||
RTC_HISTOGRAMS_COUNTS_10000(
|
||||
kIndex, uma_prefix_ + "PaddingBitrateSentInKbps",
|
||||
static_cast<int>(rtp_rtx.transmitted.padding_bytes * 8 / elapsed_sec /
|
||||
1000));
|
||||
RTC_HISTOGRAMS_COUNTS_10000(
|
||||
kIndex, uma_prefix_ + "RetransmittedBitrateSentInKbps",
|
||||
static_cast<int>(rtp_rtx.retransmitted.TotalBytes() * 8 /
|
||||
elapsed_sec / 1000));
|
||||
if (!config.rtp.rtx.ssrcs.empty()) {
|
||||
RTC_HISTOGRAMS_COUNTS_10000(
|
||||
kIndex, uma_prefix_ + "RtxBitrateSentInKbps",
|
||||
static_cast<int>(rtx.transmitted.TotalBytes() * 8 / elapsed_sec /
|
||||
1000));
|
||||
}
|
||||
if (config.rtp.fec.red_payload_type != -1) {
|
||||
RTC_HISTOGRAMS_COUNTS_10000(kIndex,
|
||||
uma_prefix_ + "FecBitrateSentInKbps",
|
||||
static_cast<int>(rtp_rtx.fec.TotalBytes() *
|
||||
8 / elapsed_sec / 1000));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SendStatisticsProxy::SetContentType(
|
||||
@ -429,6 +490,8 @@ void SendStatisticsProxy::DataCountersUpdated(
|
||||
<< "DataCountersUpdated reported for unknown ssrc: " << ssrc;
|
||||
|
||||
stats->rtp_stats = counters;
|
||||
if (uma_container_->first_rtp_stats_time_ms_ == -1)
|
||||
uma_container_->first_rtp_stats_time_ms_ = clock_->TimeInMilliseconds();
|
||||
}
|
||||
|
||||
void SendStatisticsProxy::Notify(const BitrateStatistics& total_stats,
|
||||
|
||||
@ -169,6 +169,7 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver,
|
||||
rtc::RateTracker input_frame_rate_tracker_;
|
||||
rtc::RateTracker sent_frame_rate_tracker_;
|
||||
int64_t first_rtcp_stats_time_ms_;
|
||||
int64_t first_rtp_stats_time_ms_;
|
||||
ReportBlockStats report_block_stats_;
|
||||
const VideoSendStream::Stats start_stats_;
|
||||
};
|
||||
|
||||
@ -47,6 +47,7 @@ class SendStatisticsProxyTest : public ::testing::Test {
|
||||
config.rtp.ssrcs.push_back(kSecondSsrc);
|
||||
config.rtp.rtx.ssrcs.push_back(kFirstRtxSsrc);
|
||||
config.rtp.rtx.ssrcs.push_back(kSecondRtxSsrc);
|
||||
config.rtp.fec.red_payload_type = 17;
|
||||
return config;
|
||||
}
|
||||
|
||||
@ -525,4 +526,136 @@ TEST_F(SendStatisticsProxyTest, ResetsRtcpCountersOnContentChange) {
|
||||
"WebRTC.Video.Screenshare.UniqueNackRequestsReceivedInPercent"));
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, ResetsRtpCountersOnContentChange) {
|
||||
StreamDataCountersCallback* proxy =
|
||||
static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
|
||||
StreamDataCounters counters;
|
||||
StreamDataCounters rtx_counters;
|
||||
counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
|
||||
proxy->DataCountersUpdated(counters, kFirstSsrc);
|
||||
proxy->DataCountersUpdated(counters, kSecondSsrc);
|
||||
proxy->DataCountersUpdated(rtx_counters, kFirstRtxSsrc);
|
||||
proxy->DataCountersUpdated(rtx_counters, kSecondRtxSsrc);
|
||||
|
||||
counters.transmitted.header_bytes = 400;
|
||||
counters.transmitted.packets = 20;
|
||||
counters.transmitted.padding_bytes = 1000;
|
||||
counters.transmitted.payload_bytes = 2000;
|
||||
|
||||
counters.retransmitted.header_bytes = 40;
|
||||
counters.retransmitted.packets = 2;
|
||||
counters.retransmitted.padding_bytes = 100;
|
||||
counters.retransmitted.payload_bytes = 200;
|
||||
|
||||
counters.fec = counters.retransmitted;
|
||||
|
||||
rtx_counters.transmitted = counters.transmitted;
|
||||
|
||||
fake_clock_.AdvanceTimeMilliseconds(1000 * metrics::kMinRunTimeInSeconds);
|
||||
proxy->DataCountersUpdated(counters, kFirstSsrc);
|
||||
proxy->DataCountersUpdated(counters, kSecondSsrc);
|
||||
proxy->DataCountersUpdated(rtx_counters, kFirstRtxSsrc);
|
||||
proxy->DataCountersUpdated(rtx_counters, kSecondRtxSsrc);
|
||||
|
||||
// Changing content type causes histograms to be reported.
|
||||
statistics_proxy_->SetContentType(VideoEncoderConfig::ContentType::kScreen);
|
||||
|
||||
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.BitrateSentInKbps"));
|
||||
EXPECT_EQ(static_cast<int>((counters.transmitted.TotalBytes() * 4 * 8) /
|
||||
metrics::kMinRunTimeInSeconds / 1000),
|
||||
test::LastHistogramSample("WebRTC.Video.BitrateSentInKbps"));
|
||||
|
||||
EXPECT_EQ(1,
|
||||
test::NumHistogramSamples("WebRTC.Video.MediaBitrateSentInKbps"));
|
||||
EXPECT_EQ(static_cast<int>((counters.MediaPayloadBytes() * 2 * 8) /
|
||||
metrics::kMinRunTimeInSeconds / 1000),
|
||||
test::LastHistogramSample("WebRTC.Video.MediaBitrateSentInKbps"));
|
||||
|
||||
EXPECT_EQ(1,
|
||||
test::NumHistogramSamples("WebRTC.Video.PaddingBitrateSentInKbps"));
|
||||
EXPECT_EQ(static_cast<int>((counters.transmitted.padding_bytes * 4 * 8) /
|
||||
metrics::kMinRunTimeInSeconds / 1000),
|
||||
test::LastHistogramSample("WebRTC.Video.PaddingBitrateSentInKbps"));
|
||||
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(
|
||||
"WebRTC.Video.RetransmittedBitrateSentInKbps"));
|
||||
EXPECT_EQ(
|
||||
static_cast<int>((counters.retransmitted.TotalBytes() * 2 * 8) /
|
||||
metrics::kMinRunTimeInSeconds / 1000),
|
||||
test::LastHistogramSample("WebRTC.Video.RetransmittedBitrateSentInKbps"));
|
||||
|
||||
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.RtxBitrateSentInKbps"));
|
||||
EXPECT_EQ(static_cast<int>((rtx_counters.transmitted.TotalBytes() * 2 * 8) /
|
||||
metrics::kMinRunTimeInSeconds / 1000),
|
||||
test::LastHistogramSample("WebRTC.Video.RtxBitrateSentInKbps"));
|
||||
|
||||
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.FecBitrateSentInKbps"));
|
||||
EXPECT_EQ(static_cast<int>((rtx_counters.fec.TotalBytes() * 2 * 8) /
|
||||
metrics::kMinRunTimeInSeconds / 1000),
|
||||
test::LastHistogramSample("WebRTC.Video.FecBitrateSentInKbps"));
|
||||
|
||||
// New start time but same counter values.
|
||||
proxy->DataCountersUpdated(counters, kFirstSsrc);
|
||||
proxy->DataCountersUpdated(counters, kSecondSsrc);
|
||||
proxy->DataCountersUpdated(rtx_counters, kFirstRtxSsrc);
|
||||
proxy->DataCountersUpdated(rtx_counters, kSecondRtxSsrc);
|
||||
|
||||
// Double counter values, this should result in the same counts as before but
|
||||
// with new histogram names.
|
||||
StreamDataCounters new_counters = counters;
|
||||
new_counters.Add(counters);
|
||||
StreamDataCounters new_rtx_counters = rtx_counters;
|
||||
new_rtx_counters.Add(rtx_counters);
|
||||
|
||||
fake_clock_.AdvanceTimeMilliseconds(1000 * metrics::kMinRunTimeInSeconds);
|
||||
proxy->DataCountersUpdated(new_counters, kFirstSsrc);
|
||||
proxy->DataCountersUpdated(new_counters, kSecondSsrc);
|
||||
proxy->DataCountersUpdated(new_rtx_counters, kFirstRtxSsrc);
|
||||
proxy->DataCountersUpdated(new_rtx_counters, kSecondRtxSsrc);
|
||||
|
||||
SetUp(); // Reset stats proxy also causes histograms to be reported.
|
||||
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(
|
||||
"WebRTC.Video.Screenshare.BitrateSentInKbps"));
|
||||
EXPECT_EQ(
|
||||
static_cast<int>((counters.transmitted.TotalBytes() * 4 * 8) /
|
||||
metrics::kMinRunTimeInSeconds / 1000),
|
||||
test::LastHistogramSample("WebRTC.Video.Screenshare.BitrateSentInKbps"));
|
||||
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(
|
||||
"WebRTC.Video.Screenshare.MediaBitrateSentInKbps"));
|
||||
EXPECT_EQ(static_cast<int>((counters.MediaPayloadBytes() * 2 * 8) /
|
||||
metrics::kMinRunTimeInSeconds / 1000),
|
||||
test::LastHistogramSample(
|
||||
"WebRTC.Video.Screenshare.MediaBitrateSentInKbps"));
|
||||
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(
|
||||
"WebRTC.Video.Screenshare.PaddingBitrateSentInKbps"));
|
||||
EXPECT_EQ(static_cast<int>((counters.transmitted.padding_bytes * 4 * 8) /
|
||||
metrics::kMinRunTimeInSeconds / 1000),
|
||||
test::LastHistogramSample(
|
||||
"WebRTC.Video.Screenshare.PaddingBitrateSentInKbps"));
|
||||
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(
|
||||
"WebRTC.Video.Screenshare.RetransmittedBitrateSentInKbps"));
|
||||
EXPECT_EQ(static_cast<int>((counters.retransmitted.TotalBytes() * 2 * 8) /
|
||||
metrics::kMinRunTimeInSeconds / 1000),
|
||||
test::LastHistogramSample(
|
||||
"WebRTC.Video.Screenshare.RetransmittedBitrateSentInKbps"));
|
||||
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(
|
||||
"WebRTC.Video.Screenshare.RtxBitrateSentInKbps"));
|
||||
EXPECT_EQ(static_cast<int>((rtx_counters.transmitted.TotalBytes() * 2 * 8) /
|
||||
metrics::kMinRunTimeInSeconds / 1000),
|
||||
test::LastHistogramSample(
|
||||
"WebRTC.Video.Screenshare.RtxBitrateSentInKbps"));
|
||||
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(
|
||||
"WebRTC.Video.Screenshare.FecBitrateSentInKbps"));
|
||||
EXPECT_EQ(static_cast<int>((rtx_counters.fec.TotalBytes() * 2 * 8) /
|
||||
metrics::kMinRunTimeInSeconds / 1000),
|
||||
test::LastHistogramSample(
|
||||
"WebRTC.Video.Screenshare.FecBitrateSentInKbps"));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -163,7 +163,6 @@ int32_t ViEChannel::Init() {
|
||||
}
|
||||
|
||||
ViEChannel::~ViEChannel() {
|
||||
UpdateHistograms();
|
||||
// Make sure we don't get more callbacks from the RTP module.
|
||||
module_process_thread_->DeRegisterModule(
|
||||
vie_receiver_.GetReceiveStatistics());
|
||||
@ -177,52 +176,6 @@ ViEChannel::~ViEChannel() {
|
||||
}
|
||||
}
|
||||
|
||||
void ViEChannel::UpdateHistograms() {
|
||||
if (sender_) {
|
||||
StreamDataCounters rtp;
|
||||
StreamDataCounters rtx;
|
||||
GetSendStreamDataCounters(&rtp, &rtx);
|
||||
StreamDataCounters rtp_rtx = rtp;
|
||||
rtp_rtx.Add(rtx);
|
||||
int64_t elapsed_sec = rtp_rtx.TimeSinceFirstPacketInMs(
|
||||
Clock::GetRealTimeClock()->TimeInMilliseconds()) /
|
||||
1000;
|
||||
if (elapsed_sec > metrics::kMinRunTimeInSeconds) {
|
||||
RTC_HISTOGRAM_COUNTS_100000(
|
||||
"WebRTC.Video.BitrateSentInKbps",
|
||||
static_cast<int>(rtp_rtx.transmitted.TotalBytes() * 8 / elapsed_sec /
|
||||
1000));
|
||||
RTC_HISTOGRAM_COUNTS_10000(
|
||||
"WebRTC.Video.MediaBitrateSentInKbps",
|
||||
static_cast<int>(rtp.MediaPayloadBytes() * 8 / elapsed_sec / 1000));
|
||||
RTC_HISTOGRAM_COUNTS_10000(
|
||||
"WebRTC.Video.PaddingBitrateSentInKbps",
|
||||
static_cast<int>(rtp_rtx.transmitted.padding_bytes * 8 / elapsed_sec /
|
||||
1000));
|
||||
RTC_HISTOGRAM_COUNTS_10000(
|
||||
"WebRTC.Video.RetransmittedBitrateSentInKbps",
|
||||
static_cast<int>(rtp_rtx.retransmitted.TotalBytes() * 8 /
|
||||
elapsed_sec / 1000));
|
||||
if (rtp_rtcp_modules_[0]->RtxSendStatus() != kRtxOff) {
|
||||
RTC_HISTOGRAM_COUNTS_10000(
|
||||
"WebRTC.Video.RtxBitrateSentInKbps",
|
||||
static_cast<int>(rtx.transmitted.TotalBytes() * 8 / elapsed_sec /
|
||||
1000));
|
||||
}
|
||||
bool fec_enabled = false;
|
||||
uint8_t pltype_red;
|
||||
uint8_t pltype_fec;
|
||||
rtp_rtcp_modules_[0]->GenericFECStatus(&fec_enabled, &pltype_red,
|
||||
&pltype_fec);
|
||||
if (fec_enabled) {
|
||||
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FecBitrateSentInKbps",
|
||||
static_cast<int>(rtp_rtx.fec.TotalBytes() *
|
||||
8 / elapsed_sec / 1000));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
|
||||
bool new_stream) {
|
||||
RTC_DCHECK(sender_);
|
||||
|
||||
@ -200,8 +200,6 @@ class ViEChannel : public VCMFrameTypeCallback,
|
||||
// Compute NACK list parameters for the buffering mode.
|
||||
int GetRequiredNackListSize(int target_delay_ms);
|
||||
|
||||
void UpdateHistograms();
|
||||
|
||||
// ViEChannel exposes methods that allow to modify observers and callbacks
|
||||
// to be modified. Such an API-style is cumbersome to implement and maintain
|
||||
// at all the levels when comparing to only setting them at construction. As
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user