Use RateCounter for input/sent fps stats. Reports average of periodically computed stats over a call.
Intervals when video is paused is no longer included in the stats: "WebRTC.Video.InputFramesPerSecond" "WebRTC.Video.SentFramesPerSecond" BUG=webrtc:5283 Review-Url: https://codereview.webrtc.org/2536743002 Cr-Commit-Position: refs/heads/master@{#15285}
This commit is contained in:
parent
65e5f5a69f
commit
320e45ad87
@ -106,7 +106,8 @@ SendStatisticsProxy::UmaSamplesContainer::UmaSamplesContainer(
|
||||
max_sent_width_per_timestamp_(0),
|
||||
max_sent_height_per_timestamp_(0),
|
||||
input_frame_rate_tracker_(100, 10u),
|
||||
sent_frame_rate_tracker_(100, 10u),
|
||||
input_fps_counter_(clock, nullptr, true),
|
||||
sent_fps_counter_(clock, nullptr, true),
|
||||
first_rtcp_stats_time_ms_(-1),
|
||||
first_rtp_stats_time_ms_(-1),
|
||||
start_stats_(stats) {}
|
||||
@ -132,28 +133,38 @@ void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms(
|
||||
const VideoSendStream::Stats& current_stats) {
|
||||
RTC_DCHECK(uma_prefix_ == kRealtimePrefix || uma_prefix_ == kScreenPrefix);
|
||||
const int kIndex = uma_prefix_ == kScreenPrefix ? 1 : 0;
|
||||
const int kMinRequiredPeriodicSamples = 6;
|
||||
int in_width = input_width_counter_.Avg(kMinRequiredMetricsSamples);
|
||||
int in_height = input_height_counter_.Avg(kMinRequiredMetricsSamples);
|
||||
int in_fps = round(input_frame_rate_tracker_.ComputeTotalRate());
|
||||
if (in_width != -1) {
|
||||
RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "InputWidthInPixels",
|
||||
in_width);
|
||||
RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "InputHeightInPixels",
|
||||
in_height);
|
||||
RTC_HISTOGRAMS_COUNTS_100(kIndex, uma_prefix_ + "InputFramesPerSecond",
|
||||
in_fps);
|
||||
}
|
||||
AggregatedStats in_fps = input_fps_counter_.GetStats();
|
||||
if (in_fps.num_samples >= kMinRequiredPeriodicSamples) {
|
||||
RTC_HISTOGRAMS_COUNTS_100(kIndex, uma_prefix_ + "InputFramesPerSecond",
|
||||
in_fps.average);
|
||||
LOG(LS_INFO) << uma_prefix_ + "InputFramesPerSecond, " << in_fps.ToString();
|
||||
}
|
||||
|
||||
int sent_width = sent_width_counter_.Avg(kMinRequiredMetricsSamples);
|
||||
int sent_height = sent_height_counter_.Avg(kMinRequiredMetricsSamples);
|
||||
int sent_fps = round(sent_frame_rate_tracker_.ComputeTotalRate());
|
||||
if (sent_width != -1) {
|
||||
RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "SentWidthInPixels",
|
||||
sent_width);
|
||||
RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "SentHeightInPixels",
|
||||
sent_height);
|
||||
RTC_HISTOGRAMS_COUNTS_100(kIndex, uma_prefix_ + "SentFramesPerSecond",
|
||||
sent_fps);
|
||||
}
|
||||
AggregatedStats sent_fps = sent_fps_counter_.GetStats();
|
||||
if (sent_fps.num_samples >= kMinRequiredPeriodicSamples) {
|
||||
RTC_HISTOGRAMS_COUNTS_100(kIndex, uma_prefix_ + "SentFramesPerSecond",
|
||||
sent_fps.average);
|
||||
LOG(LS_INFO) << uma_prefix_ + "SentFramesPerSecond, "
|
||||
<< sent_fps.ToString();
|
||||
}
|
||||
|
||||
int encode_ms = encode_time_counter_.Avg(kMinRequiredMetricsSamples);
|
||||
if (encode_ms != -1) {
|
||||
RTC_HISTOGRAMS_COUNTS_1000(kIndex, uma_prefix_ + "EncodeTimeInMs",
|
||||
@ -389,6 +400,11 @@ void SendStatisticsProxy::OnEncodedFrameTimeMeasured(
|
||||
void SendStatisticsProxy::OnSuspendChange(bool is_suspended) {
|
||||
rtc::CritScope lock(&crit_);
|
||||
stats_.suspended = is_suspended;
|
||||
// Pause framerate stats.
|
||||
if (is_suspended) {
|
||||
uma_container_->input_fps_counter_.ProcessAndPause();
|
||||
uma_container_->sent_fps_counter_.ProcessAndPause();
|
||||
}
|
||||
}
|
||||
|
||||
VideoSendStream::Stats SendStatisticsProxy::GetStats() {
|
||||
@ -541,7 +557,7 @@ void SendStatisticsProxy::OnSendEncodedImage(
|
||||
// are encoded before the next start.
|
||||
if (last_sent_frame_timestamp_ > 0 &&
|
||||
encoded_image._timeStamp != last_sent_frame_timestamp_) {
|
||||
uma_container_->sent_frame_rate_tracker_.AddSamples(1);
|
||||
uma_container_->sent_fps_counter_.Add(1);
|
||||
uma_container_->sent_width_counter_.Add(
|
||||
uma_container_->max_sent_width_per_timestamp_);
|
||||
uma_container_->sent_height_counter_.Add(
|
||||
@ -566,6 +582,7 @@ int SendStatisticsProxy::GetSendFrameRate() const {
|
||||
void SendStatisticsProxy::OnIncomingFrame(int width, int height) {
|
||||
rtc::CritScope lock(&crit_);
|
||||
uma_container_->input_frame_rate_tracker_.AddSamples(1);
|
||||
uma_container_->input_fps_counter_.Add(1);
|
||||
uma_container_->input_width_counter_.Add(width);
|
||||
uma_container_->input_height_counter_.Add(height);
|
||||
uma_container_->cpu_limited_frame_counter_.Add(stats_.cpu_limited_resolution);
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include "webrtc/system_wrappers/include/clock.h"
|
||||
#include "webrtc/video/overuse_frame_detector.h"
|
||||
#include "webrtc/video/report_block_stats.h"
|
||||
#include "webrtc/video/stats_counter.h"
|
||||
#include "webrtc/video/vie_encoder.h"
|
||||
#include "webrtc/video_send_stream.h"
|
||||
|
||||
@ -187,7 +188,8 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver,
|
||||
SampleCounter delay_counter_;
|
||||
SampleCounter max_delay_counter_;
|
||||
rtc::RateTracker input_frame_rate_tracker_;
|
||||
rtc::RateTracker sent_frame_rate_tracker_;
|
||||
RateCounter input_fps_counter_;
|
||||
RateCounter sent_fps_counter_;
|
||||
int64_t first_rtcp_stats_time_ms_;
|
||||
int64_t first_rtp_stats_time_ms_;
|
||||
ReportBlockStats report_block_stats_;
|
||||
|
||||
@ -26,7 +26,9 @@ const uint32_t kSecondSsrc = 42;
|
||||
const uint32_t kFirstRtxSsrc = 18;
|
||||
const uint32_t kSecondRtxSsrc = 43;
|
||||
const uint32_t kFlexFecSsrc = 55;
|
||||
|
||||
const int kFpsPeriodicIntervalMs = 2000;
|
||||
const int kWidth = 640;
|
||||
const int kHeight = 480;
|
||||
const int kQpIdx0 = 21;
|
||||
const int kQpIdx1 = 39;
|
||||
} // namespace
|
||||
@ -353,9 +355,6 @@ TEST_F(SendStatisticsProxyTest, OnSendEncodedImageWithoutQpQpSumWontExist) {
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, SwitchContentTypeUpdatesHistograms) {
|
||||
const int kWidth = 640;
|
||||
const int kHeight = 480;
|
||||
|
||||
for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
|
||||
statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
|
||||
|
||||
@ -371,10 +370,110 @@ TEST_F(SendStatisticsProxyTest, SwitchContentTypeUpdatesHistograms) {
|
||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputWidthInPixels"));
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, CpuLimitedResolutionUpdated) {
|
||||
const int kWidth = 640;
|
||||
const int kHeight = 480;
|
||||
TEST_F(SendStatisticsProxyTest, InputResolutionHistogramsAreUpdated) {
|
||||
for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
|
||||
statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
|
||||
|
||||
statistics_proxy_.reset();
|
||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputWidthInPixels"));
|
||||
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.InputWidthInPixels", kWidth));
|
||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputHeightInPixels"));
|
||||
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.InputHeightInPixels", kHeight));
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, SentResolutionHistogramsAreUpdated) {
|
||||
EncodedImage encoded_image;
|
||||
encoded_image._encodedWidth = kWidth;
|
||||
encoded_image._encodedHeight = kHeight;
|
||||
for (int i = 0; i <= SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
|
||||
encoded_image._timeStamp = i + 1;
|
||||
statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
|
||||
}
|
||||
statistics_proxy_.reset();
|
||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SentWidthInPixels"));
|
||||
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SentWidthInPixels", kWidth));
|
||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SentHeightInPixels"));
|
||||
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SentHeightInPixels", kHeight));
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, InputFpsHistogramIsUpdated) {
|
||||
const int kFps = 20;
|
||||
const int kMinPeriodicSamples = 6;
|
||||
int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000;
|
||||
for (int i = 0; i <= frames; ++i) {
|
||||
fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
|
||||
statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
|
||||
}
|
||||
statistics_proxy_.reset();
|
||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputFramesPerSecond"));
|
||||
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.InputFramesPerSecond", kFps));
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, SentFpsHistogramIsUpdated) {
|
||||
EncodedImage encoded_image;
|
||||
const int kFps = 20;
|
||||
const int kMinPeriodicSamples = 6;
|
||||
int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000 + 1;
|
||||
for (int i = 0; i <= frames; ++i) {
|
||||
fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
|
||||
encoded_image._timeStamp = i + 1;
|
||||
statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
|
||||
}
|
||||
statistics_proxy_.reset();
|
||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SentFramesPerSecond"));
|
||||
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SentFramesPerSecond", kFps));
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, InputFpsHistogramExcludesSuspendedTime) {
|
||||
const int kFps = 20;
|
||||
const int kSuspendTimeMs = 10000;
|
||||
const int kMinPeriodicSamples = 6;
|
||||
int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000;
|
||||
for (int i = 0; i < frames; ++i) {
|
||||
fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
|
||||
statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
|
||||
}
|
||||
// Suspend.
|
||||
statistics_proxy_->OnSuspendChange(true);
|
||||
fake_clock_.AdvanceTimeMilliseconds(kSuspendTimeMs);
|
||||
|
||||
for (int i = 0; i < frames; ++i) {
|
||||
fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
|
||||
statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
|
||||
}
|
||||
// Suspended time interval should not affect the framerate.
|
||||
statistics_proxy_.reset();
|
||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.InputFramesPerSecond"));
|
||||
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.InputFramesPerSecond", kFps));
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, SentFpsHistogramExcludesSuspendedTime) {
|
||||
EncodedImage encoded_image;
|
||||
const int kFps = 20;
|
||||
const int kSuspendTimeMs = 10000;
|
||||
const int kMinPeriodicSamples = 6;
|
||||
int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000;
|
||||
for (int i = 0; i <= frames; ++i) {
|
||||
fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
|
||||
encoded_image._timeStamp = i + 1;
|
||||
statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
|
||||
}
|
||||
// Suspend.
|
||||
statistics_proxy_->OnSuspendChange(true);
|
||||
fake_clock_.AdvanceTimeMilliseconds(kSuspendTimeMs);
|
||||
|
||||
for (int i = 0; i <= frames; ++i) {
|
||||
fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
|
||||
encoded_image._timeStamp = i + 1;
|
||||
statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
|
||||
}
|
||||
// Suspended time interval should not affect the framerate.
|
||||
statistics_proxy_.reset();
|
||||
EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SentFramesPerSecond"));
|
||||
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SentFramesPerSecond", kFps));
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, CpuLimitedResolutionUpdated) {
|
||||
for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
|
||||
statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user