Exclude initial adapt downs in stats for quality adapt changes per minute.
Make WebRTC.Video.AdaptChangesPerMinute.Quality stats only based on changes during a call. Discard initial quality adapt changes due to bitrate (MaximumFrameSizeForBitrate). Makes stats only based on changes determined by the quality scaler. Bug: none Change-Id: I461b65e65634565ade87b1336cf5206aa14926ff Reviewed-on: https://webrtc-review.googlesource.com/37660 Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> Commit-Queue: Åsa Persson <asapersson@webrtc.org> Cr-Commit-Position: refs/heads/master@{#21585}
This commit is contained in:
parent
34814c728f
commit
875841d9d8
@ -439,6 +439,11 @@ void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms(
|
||||
if (elapsed_sec >= metrics::kMinRunTimeInSeconds) {
|
||||
int quality_changes = current_stats.number_of_quality_adapt_changes -
|
||||
start_stats_.number_of_quality_adapt_changes;
|
||||
// Only base stats on changes during a call, discard initial changes.
|
||||
int initial_changes =
|
||||
initial_quality_changes_.down + initial_quality_changes_.up;
|
||||
if (initial_changes <= quality_changes)
|
||||
quality_changes -= initial_changes;
|
||||
RTC_HISTOGRAMS_COUNTS_100(kIndex,
|
||||
uma_prefix_ + "AdaptChangesPerMinute.Quality",
|
||||
quality_changes * 60 / elapsed_sec);
|
||||
@ -987,6 +992,7 @@ void SendStatisticsProxy::OnQualityAdaptationChanged(
|
||||
const VideoStreamEncoder::AdaptCounts& cpu_counts,
|
||||
const VideoStreamEncoder::AdaptCounts& quality_counts) {
|
||||
rtc::CritScope lock(&crit_);
|
||||
TryUpdateInitialQualityResolutionAdaptUp(quality_counts);
|
||||
++stats_.number_of_quality_adapt_changes;
|
||||
UpdateAdaptationStats(cpu_counts, quality_counts);
|
||||
}
|
||||
@ -1003,6 +1009,27 @@ void SendStatisticsProxy::UpdateAdaptationStats(
|
||||
stats_.bw_limited_framerate = quality_counts.fps > 0;
|
||||
}
|
||||
|
||||
// TODO(asapersson): Include fps changes.
|
||||
void SendStatisticsProxy::OnInitialQualityResolutionAdaptDown() {
|
||||
rtc::CritScope lock(&crit_);
|
||||
++uma_container_->initial_quality_changes_.down;
|
||||
}
|
||||
|
||||
void SendStatisticsProxy::TryUpdateInitialQualityResolutionAdaptUp(
|
||||
const VideoStreamEncoder::AdaptCounts& quality_counts) {
|
||||
if (uma_container_->initial_quality_changes_.down == 0)
|
||||
return;
|
||||
|
||||
if (quality_downscales_ > 0 &&
|
||||
quality_counts.resolution < quality_downscales_) {
|
||||
// Adapting up in quality.
|
||||
if (uma_container_->initial_quality_changes_.down >
|
||||
uma_container_->initial_quality_changes_.up) {
|
||||
++uma_container_->initial_quality_changes_.up;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SendStatisticsProxy::SetAdaptTimer(
|
||||
const VideoStreamEncoder::AdaptCounts& counts,
|
||||
StatsTimer* timer) {
|
||||
|
||||
@ -74,6 +74,7 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver,
|
||||
const VideoStreamEncoder::AdaptCounts& cpu_counts,
|
||||
const VideoStreamEncoder::AdaptCounts& quality_counts);
|
||||
void OnMinPixelLimitReached();
|
||||
void OnInitialQualityResolutionAdaptDown();
|
||||
|
||||
void OnSuspendChange(bool is_suspended);
|
||||
void OnInactiveSsrc(uint32_t ssrc);
|
||||
@ -181,6 +182,10 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver,
|
||||
SampleCounter vp9; // QP range: 0-255.
|
||||
SampleCounter h264; // QP range: 0-51.
|
||||
};
|
||||
struct AdaptChanges {
|
||||
int down = 0;
|
||||
int up = 0;
|
||||
};
|
||||
|
||||
// Map holding encoded frames (mapped by timestamp).
|
||||
// If simulcast layers are encoded on different threads, there is no guarantee
|
||||
@ -217,6 +222,9 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver,
|
||||
const VideoStreamEncoder::AdaptCounts& cpu_counts,
|
||||
const VideoStreamEncoder::AdaptCounts& quality_counts)
|
||||
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
||||
void TryUpdateInitialQualityResolutionAdaptUp(
|
||||
const VideoStreamEncoder::AdaptCounts& quality_counts)
|
||||
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
||||
|
||||
void UpdateEncoderFallbackStats(const CodecSpecificInfo* codec_info,
|
||||
int pixels)
|
||||
@ -298,6 +306,7 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver,
|
||||
size_t num_streams_; // Number of configured streams to encoder.
|
||||
size_t num_pixels_highest_stream_;
|
||||
EncodedFrameMap encoded_frames_;
|
||||
AdaptChanges initial_quality_changes_;
|
||||
|
||||
std::map<int, QpCounters>
|
||||
qp_counters_; // QP counters mapped by spatial idx.
|
||||
|
||||
@ -513,6 +513,102 @@ TEST_F(SendStatisticsProxyTest, CpuAdaptChangesReported) {
|
||||
EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Cpu", 6));
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, ExcludesInitialQualityAdaptDownChange) {
|
||||
// First RTP packet sent.
|
||||
UpdateDataCounters(kFirstSsrc);
|
||||
// Enable adaptation.
|
||||
VideoStreamEncoder::AdaptCounts cpu_counts;
|
||||
VideoStreamEncoder::AdaptCounts quality_counts;
|
||||
statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
|
||||
// Adapt changes: 1 (1 initial) = 0, elapsed time: 10 sec => 0 per minute.
|
||||
statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
|
||||
statistics_proxy_->OnInitialQualityResolutionAdaptDown();
|
||||
fake_clock_.AdvanceTimeMilliseconds(10000);
|
||||
statistics_proxy_.reset();
|
||||
EXPECT_EQ(1,
|
||||
metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
|
||||
EXPECT_EQ(
|
||||
1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 0));
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, ExcludesInitialQualityAdaptDownChanges) {
|
||||
// First RTP packet sent.
|
||||
UpdateDataCounters(kFirstSsrc);
|
||||
// Enable adaptation.
|
||||
VideoStreamEncoder::AdaptCounts cpu_counts;
|
||||
VideoStreamEncoder::AdaptCounts quality_counts;
|
||||
statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
|
||||
// Adapt changes: 3 (2 initial) = 1, elapsed time: 10 sec => 6 per minute.
|
||||
quality_counts.resolution = 1;
|
||||
statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
|
||||
statistics_proxy_->OnInitialQualityResolutionAdaptDown();
|
||||
quality_counts.resolution = 2;
|
||||
statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
|
||||
statistics_proxy_->OnInitialQualityResolutionAdaptDown();
|
||||
quality_counts.resolution = 3;
|
||||
statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
|
||||
fake_clock_.AdvanceTimeMilliseconds(10000);
|
||||
statistics_proxy_.reset();
|
||||
EXPECT_EQ(1,
|
||||
metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
|
||||
EXPECT_EQ(
|
||||
1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 6));
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, InitialQualityAdaptChangesNotExcludedOnError) {
|
||||
// First RTP packet sent.
|
||||
UpdateDataCounters(kFirstSsrc);
|
||||
// Enable adaptation.
|
||||
VideoStreamEncoder::AdaptCounts cpu_counts;
|
||||
VideoStreamEncoder::AdaptCounts quality_counts;
|
||||
statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
|
||||
// Adapt changes: 1 (2 initial) = 1, elapsed time: 10 sec => 6 per minute.
|
||||
statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
|
||||
statistics_proxy_->OnInitialQualityResolutionAdaptDown();
|
||||
statistics_proxy_->OnInitialQualityResolutionAdaptDown();
|
||||
fake_clock_.AdvanceTimeMilliseconds(10000);
|
||||
statistics_proxy_.reset();
|
||||
EXPECT_EQ(1,
|
||||
metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
|
||||
EXPECT_EQ(
|
||||
1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 6));
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, ExcludesInitialQualityAdaptDownAndUpChanges) {
|
||||
// First RTP packet sent.
|
||||
UpdateDataCounters(kFirstSsrc);
|
||||
// Enable adaptation.
|
||||
VideoStreamEncoder::AdaptCounts cpu_counts;
|
||||
VideoStreamEncoder::AdaptCounts quality_counts;
|
||||
statistics_proxy_->SetAdaptationStats(cpu_counts, quality_counts);
|
||||
// Adapt changes: 8 (4 initial) = 4, elapsed time: 10 sec => 24 per minute.
|
||||
quality_counts.resolution = 1;
|
||||
statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
|
||||
statistics_proxy_->OnInitialQualityResolutionAdaptDown();
|
||||
quality_counts.resolution = 2;
|
||||
statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
|
||||
statistics_proxy_->OnInitialQualityResolutionAdaptDown();
|
||||
quality_counts.resolution = 3;
|
||||
statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
|
||||
quality_counts.fps = 1;
|
||||
statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
|
||||
quality_counts.fps = 0;
|
||||
statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
|
||||
quality_counts.resolution = 2; // Initial resolution up.
|
||||
statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
|
||||
quality_counts.resolution = 1; // Initial resolution up.
|
||||
statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
|
||||
quality_counts.resolution = 0;
|
||||
statistics_proxy_->OnQualityAdaptationChanged(cpu_counts, quality_counts);
|
||||
|
||||
fake_clock_.AdvanceTimeMilliseconds(10000);
|
||||
statistics_proxy_.reset();
|
||||
EXPECT_EQ(1,
|
||||
metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
|
||||
EXPECT_EQ(
|
||||
1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 24));
|
||||
}
|
||||
|
||||
TEST_F(SendStatisticsProxyTest, AdaptChangesStatsExcludesDisabledTime) {
|
||||
// First RTP packet sent.
|
||||
UpdateDataCounters(kFirstSsrc);
|
||||
|
||||
@ -767,7 +767,11 @@ void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame,
|
||||
video_frame.size() >
|
||||
MaximumFrameSizeForBitrate(encoder_start_bitrate_bps_ / 1000)) {
|
||||
RTC_LOG(LS_INFO) << "Dropping frame. Too large for target bitrate.";
|
||||
int count = GetConstAdaptCounter().ResolutionCount(kQuality);
|
||||
AdaptDown(kQuality);
|
||||
if (GetConstAdaptCounter().ResolutionCount(kQuality) > count) {
|
||||
stats_proxy_->OnInitialQualityResolutionAdaptDown();
|
||||
}
|
||||
++initial_rampup_;
|
||||
return;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user