Remove VideoStreamEncoderObserver::AdaptationReason::kNone

Replaces this with 2 methods instead, adding clarity.

ClearAdaptationStats
- Resets the adaptations statistics to 0. This is done,
when the degredation is reset, for example when the preference
is changed to/from BALANCED.

UpdateAdaptationMaskingSettings
- Updates the settings for adaptation statistics reporting.
This way we don't report quality adaptations if quality scaling
is not enabled (same for resolution/fps scaling).

The adaptation counting inside the SendStatisticsProxy is
now done in a struct that counts the totals, and then masks
out these counts based on the adaptation settings. The
MaskedAdaptationSteps uses optionals to hide the values we
shoudn't report, while the AdaptationSteps always hold the real
totals.

All tests have been updated to use the Reset/Clear method as needed.

Now that AdaptationCounters and AdaptSteps use the same structure,
AdaptationCounters was moved to api/video and replaces AdaptSteps.

The AdaptReason enum is also redundant now, and will be removed
in a follow-up CL.

R=hbos@webrtc.org

Bug: webrtc:11392
Change-Id: Iaed6488581325d341a056b5bbf76a01c19d6c282
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/171685
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Evan Shrubsole <eshr@google.com>
Cr-Commit-Position: refs/heads/master@{#31083}
This commit is contained in:
Evan Shrubsole
2020-04-16 11:34:32 +02:00
committed by Commit Bot
parent d059dfbc06
commit dff792591f
9 changed files with 451 additions and 357 deletions

View File

@ -243,12 +243,12 @@ rtc_source_set("video_stream_encoder") {
visibility = [ "*" ]
sources = [
"video_stream_encoder_interface.h",
"video_stream_encoder_observer.cc",
"video_stream_encoder_observer.h",
"video_stream_encoder_settings.h",
]
deps = [
":video_adaptation",
":video_bitrate_allocation",
":video_bitrate_allocator",
":video_bitrate_allocator_factory",

View File

@ -1,17 +0,0 @@
/*
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "api/video/video_stream_encoder_observer.h"
namespace webrtc {
VideoStreamEncoderObserver::AdaptationSteps::AdaptationSteps() = default;
} // namespace webrtc

View File

@ -15,6 +15,7 @@
#include <vector>
#include "absl/types/optional.h"
#include "api/video/video_adaptation_counters.h"
#include "api/video/video_bitrate_allocation.h"
#include "api/video/video_codec_constants.h"
#include "api/video_codecs/video_encoder.h"
@ -38,22 +39,27 @@ class CpuOveruseMetricsObserver {
class VideoStreamEncoderObserver : public CpuOveruseMetricsObserver {
public:
// Number of resolution and framerate reductions (unset if disabled).
struct AdaptationSteps {
AdaptationSteps();
absl::optional<int> num_resolution_reductions = 0;
absl::optional<int> num_framerate_reductions = 0;
};
// TODO(nisse): There are too many enums to represent this. Besides
// this one, see AdaptationObserverInterface::AdaptReason and
// WebRtcVideoChannel::AdaptReason.
enum class AdaptationReason {
kNone, // Used for reset of counters.
kCpu,
kQuality,
};
struct AdaptationSettings {
AdaptationSettings()
: resolution_scaling_enabled(false), framerate_scaling_enabled(false) {}
AdaptationSettings(bool resolution_scaling_enabled,
bool framerate_scaling_enabled)
: resolution_scaling_enabled(resolution_scaling_enabled),
framerate_scaling_enabled(framerate_scaling_enabled) {}
bool resolution_scaling_enabled;
bool framerate_scaling_enabled;
};
// TODO(nisse): Duplicates enum EncodedImageCallback::DropReason.
enum class DropReason {
kSource,
@ -83,9 +89,15 @@ class VideoStreamEncoderObserver : public CpuOveruseMetricsObserver {
const VideoEncoderConfig& encoder_config,
const std::vector<VideoStream>& streams) = 0;
virtual void OnAdaptationChanged(AdaptationReason reason,
const AdaptationSteps& cpu_steps,
const AdaptationSteps& quality_steps) = 0;
virtual void OnAdaptationChanged(
AdaptationReason reason,
const VideoAdaptationCounters& cpu_steps,
const VideoAdaptationCounters& quality_steps) = 0;
virtual void ClearAdaptationStats() = 0;
virtual void UpdateAdaptationSettings(
AdaptationSettings cpu_settings,
AdaptationSettings quality_settings) = 0;
virtual void OnMinPixelLimitReached() = 0;
virtual void OnInitialQualityResolutionAdaptDown() = 0;

View File

@ -93,6 +93,16 @@ VideoAdaptationCounters ApplyDegradationPreference(
return counters;
}
VideoStreamEncoderObserver::AdaptationReason ToAdaptationReason(
AdaptationObserverInterface::AdaptReason reason) {
switch (reason) {
case AdaptationObserverInterface::kQuality:
return VideoStreamEncoderObserver::AdaptationReason::kQuality;
case AdaptationObserverInterface::kCpu:
return VideoStreamEncoderObserver::AdaptationReason::kCpu;
}
}
} // namespace
class ResourceAdaptationProcessor::InitialFrameDropper {
@ -253,10 +263,13 @@ void ResourceAdaptationProcessor::SetHasInputVideo(bool has_input_video) {
void ResourceAdaptationProcessor::SetDegradationPreference(
DegradationPreference degradation_preference) {
degradation_preference_ = degradation_preference;
UpdateStatsAdaptationSettings();
if (stream_adapter_->SetDegradationPreference(degradation_preference) ==
VideoStreamAdapter::SetDegradationPreferenceResult::
kRestrictionsCleared) {
active_counts_.fill(VideoAdaptationCounters());
encoder_stats_observer_->ClearAdaptationStats();
}
MaybeUpdateVideoSourceRestrictions();
}
@ -293,6 +306,7 @@ void ResourceAdaptationProcessor::SetEncoderRates(
void ResourceAdaptationProcessor::ResetVideoSourceRestrictions() {
stream_adapter_->ClearRestrictions();
active_counts_.fill(VideoAdaptationCounters());
encoder_stats_observer_->ClearAdaptationStats();
MaybeUpdateVideoSourceRestrictions();
}
@ -401,11 +415,7 @@ void ResourceAdaptationProcessor::ConfigureQualityScaler(
quality_scaler_resource_->SetQpThresholds(*thresholds);
}
}
encoder_stats_observer_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone,
GetActiveCounts(AdaptationObserverInterface::AdaptReason::kCpu),
GetActiveCounts(AdaptationObserverInterface::AdaptReason::kQuality));
UpdateStatsAdaptationSettings();
}
ResourceListenerResponse
@ -644,52 +654,24 @@ void ResourceAdaptationProcessor::UpdateAdaptationStats(
OnAdaptationCountChanged(total_counts, &active_count, &other_active);
switch (reason) {
case AdaptationObserverInterface::AdaptReason::kCpu:
encoder_stats_observer_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kCpu,
GetActiveCounts(AdaptationObserverInterface::AdaptReason::kCpu),
GetActiveCounts(AdaptationObserverInterface::AdaptReason::kQuality));
break;
case AdaptationObserverInterface::AdaptReason::kQuality:
encoder_stats_observer_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality,
GetActiveCounts(AdaptationObserverInterface::AdaptReason::kCpu),
GetActiveCounts(AdaptationObserverInterface::AdaptReason::kQuality));
break;
}
encoder_stats_observer_->OnAdaptationChanged(
ToAdaptationReason(reason),
std::get<AdaptationObserverInterface::AdaptReason::kCpu>(active_counts_),
std::get<AdaptationObserverInterface::AdaptReason::kQuality>(
active_counts_));
}
VideoStreamEncoderObserver::AdaptationSteps
ResourceAdaptationProcessor::GetActiveCounts(
AdaptationObserverInterface::AdaptReason reason) {
// TODO(https://crbug.com/webrtc/11392) Ideally this shuold be moved out of
// this class and into the encoder_stats_observer_.
const VideoAdaptationCounters counters = active_counts_[reason];
void ResourceAdaptationProcessor::UpdateStatsAdaptationSettings() const {
VideoStreamEncoderObserver::AdaptationSettings cpu_settings(
IsResolutionScalingEnabled(degradation_preference_),
IsFramerateScalingEnabled(degradation_preference_));
VideoStreamEncoderObserver::AdaptationSteps counts =
VideoStreamEncoderObserver::AdaptationSteps();
counts.num_resolution_reductions = counters.resolution_adaptations;
counts.num_framerate_reductions = counters.fps_adaptations;
switch (reason) {
case AdaptationObserverInterface::AdaptReason::kCpu:
if (!IsFramerateScalingEnabled(degradation_preference_))
counts.num_framerate_reductions = absl::nullopt;
if (!IsResolutionScalingEnabled(degradation_preference_))
counts.num_resolution_reductions = absl::nullopt;
break;
case AdaptationObserverInterface::AdaptReason::kQuality:
if (!IsFramerateScalingEnabled(degradation_preference_) ||
!quality_scaler_resource_->is_started()) {
counts.num_framerate_reductions = absl::nullopt;
}
if (!IsResolutionScalingEnabled(degradation_preference_) ||
!quality_scaler_resource_->is_started()) {
counts.num_resolution_reductions = absl::nullopt;
}
break;
}
return counts;
VideoStreamEncoderObserver::AdaptationSettings quality_settings =
quality_scaler_resource_->is_started()
? cpu_settings
: VideoStreamEncoderObserver::AdaptationSettings();
encoder_stats_observer_->UpdateAdaptationSettings(cpu_settings,
quality_settings);
}
VideoStreamAdapter::VideoInputMode

View File

@ -140,8 +140,6 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
CpuOveruseOptions GetCpuOveruseOptions() const;
int LastInputFrameSizeOrDefault() const;
VideoStreamEncoderObserver::AdaptationSteps GetActiveCounts(
AdaptationObserverInterface::AdaptReason reason);
VideoStreamAdapter::VideoInputMode GetVideoInputMode() const;
// Makes |video_source_restrictions_| up-to-date and informs the
@ -157,6 +155,7 @@ class ResourceAdaptationProcessor : public ResourceAdaptationProcessorInterface,
absl::optional<VideoEncoder::QpThresholds> qp_thresholds);
void UpdateAdaptationStats(AdaptationObserverInterface::AdaptReason reason);
void UpdateStatsAdaptationSettings() const;
// Checks to see if we should execute the quality rampup experiment. The
// experiment resets all video restrictions at the start of the call in the

View File

@ -141,8 +141,6 @@ SendStatisticsProxy::SendStatisticsProxy(
content_type_(content_type),
start_ms_(clock->TimeInMilliseconds()),
encode_time_(kEncodeTimeWeigthFactor),
quality_downscales_(-1),
cpu_downscales_(-1),
quality_limitation_reason_tracker_(clock_),
media_byte_rate_tracker_(kBucketSizeMs, kBucketCount),
encoded_frame_rate_tracker_(kBucketSizeMs, kBucketCount),
@ -719,9 +717,9 @@ void SendStatisticsProxy::OnSuspendChange(bool is_suspended) {
uma_container_->quality_adapt_timer_.Stop(now_ms);
} else {
// Start adaptation stats if scaling is enabled.
if (cpu_downscales_ >= 0)
if (adaptations_.MaskedCpuCounts().resolution_adaptations.has_value())
uma_container_->cpu_adapt_timer_.Start(now_ms);
if (quality_downscales_ >= 0)
if (adaptations_.MaskedQualityCounts().resolution_adaptations.has_value())
uma_container_->quality_adapt_timer_.Start(now_ms);
// Stop pause explicitly for stats that may be zero/not updated for some
// time.
@ -1012,12 +1010,15 @@ void SendStatisticsProxy::OnSendEncodedImage(
encoded_frame_rate_tracker_.AddSamples(1);
}
stats_.bw_limited_resolution |= quality_downscales_ > 0;
absl::optional<int> downscales =
adaptations_.MaskedQualityCounts().resolution_adaptations;
stats_.bw_limited_resolution |=
(downscales.has_value() && downscales.value() > 0);
if (quality_downscales_ != -1) {
uma_container_->quality_limited_frame_counter_.Add(quality_downscales_ > 0);
if (quality_downscales_ > 0)
uma_container_->quality_downscales_counter_.Add(quality_downscales_);
if (downscales.has_value()) {
uma_container_->quality_limited_frame_counter_.Add(downscales.value() > 0);
if (downscales.value() > 0)
uma_container_->quality_downscales_counter_.Add(downscales.value());
}
}
@ -1045,7 +1046,7 @@ void SendStatisticsProxy::OnIncomingFrame(int width, int height) {
uma_container_->input_fps_counter_.Add(1);
uma_container_->input_width_counter_.Add(width);
uma_container_->input_height_counter_.Add(height);
if (cpu_downscales_ >= 0) {
if (adaptations_.MaskedCpuCounts().resolution_adaptations.has_value()) {
uma_container_->cpu_limited_frame_counter_.Add(
stats_.cpu_limited_resolution);
}
@ -1077,39 +1078,56 @@ void SendStatisticsProxy::OnFrameDropped(DropReason reason) {
}
}
void SendStatisticsProxy::ClearAdaptationStats() {
rtc::CritScope lock(&crit_);
adaptations_.set_cpu_counts(VideoAdaptationCounters());
adaptations_.set_quality_counts(VideoAdaptationCounters());
UpdateAdaptationStats();
}
void SendStatisticsProxy::UpdateAdaptationSettings(
VideoStreamEncoderObserver::AdaptationSettings cpu_settings,
VideoStreamEncoderObserver::AdaptationSettings quality_settings) {
rtc::CritScope lock(&crit_);
adaptations_.UpdateMaskingSettings(cpu_settings, quality_settings);
SetAdaptTimer(adaptations_.MaskedCpuCounts(),
&uma_container_->cpu_adapt_timer_);
SetAdaptTimer(adaptations_.MaskedQualityCounts(),
&uma_container_->quality_adapt_timer_);
UpdateAdaptationStats();
}
void SendStatisticsProxy::OnAdaptationChanged(
AdaptationReason reason,
const AdaptationSteps& cpu_counts,
const AdaptationSteps& quality_counts) {
const VideoAdaptationCounters& cpu_counters,
const VideoAdaptationCounters& quality_counters) {
rtc::CritScope lock(&crit_);
MaskedAdaptationCounts receiver = adaptations_.MaskedQualityCounts();
adaptations_.set_cpu_counts(cpu_counters);
adaptations_.set_quality_counts(quality_counters);
switch (reason) {
case AdaptationReason::kNone:
SetAdaptTimer(cpu_counts, &uma_container_->cpu_adapt_timer_);
SetAdaptTimer(quality_counts, &uma_container_->quality_adapt_timer_);
break;
case AdaptationReason::kCpu:
++stats_.number_of_cpu_adapt_changes;
break;
case AdaptationReason::kQuality:
TryUpdateInitialQualityResolutionAdaptUp(quality_counts);
TryUpdateInitialQualityResolutionAdaptUp(
receiver.resolution_adaptations,
adaptations_.MaskedQualityCounts().resolution_adaptations);
++stats_.number_of_quality_adapt_changes;
break;
}
cpu_downscales_ = cpu_counts.num_resolution_reductions.value_or(-1);
quality_downscales_ = quality_counts.num_resolution_reductions.value_or(-1);
cpu_counts_ = cpu_counts;
quality_counts_ = quality_counts;
UpdateAdaptationStats();
}
void SendStatisticsProxy::UpdateAdaptationStats() {
bool is_cpu_limited = cpu_counts_.num_resolution_reductions > 0 ||
cpu_counts_.num_framerate_reductions > 0;
bool is_bandwidth_limited = quality_counts_.num_resolution_reductions > 0 ||
quality_counts_.num_framerate_reductions > 0 ||
auto cpu_counts = adaptations_.MaskedCpuCounts();
auto quality_counts = adaptations_.MaskedQualityCounts();
bool is_cpu_limited = cpu_counts.resolution_adaptations > 0 ||
cpu_counts.num_framerate_reductions > 0;
bool is_bandwidth_limited = quality_counts.resolution_adaptations > 0 ||
quality_counts.num_framerate_reductions > 0 ||
bw_limited_layers_ || internal_encoder_scaler_;
if (is_bandwidth_limited) {
// We may be both CPU limited and bandwidth limited at the same time but
@ -1126,10 +1144,10 @@ void SendStatisticsProxy::UpdateAdaptationStats() {
QualityLimitationReason::kNone);
}
stats_.cpu_limited_resolution = cpu_counts_.num_resolution_reductions > 0;
stats_.cpu_limited_framerate = cpu_counts_.num_framerate_reductions > 0;
stats_.bw_limited_resolution = quality_counts_.num_resolution_reductions > 0;
stats_.bw_limited_framerate = quality_counts_.num_framerate_reductions > 0;
stats_.cpu_limited_resolution = cpu_counts.resolution_adaptations > 0;
stats_.cpu_limited_framerate = cpu_counts.num_framerate_reductions > 0;
stats_.bw_limited_resolution = quality_counts.resolution_adaptations > 0;
stats_.bw_limited_framerate = quality_counts.num_framerate_reductions > 0;
// If bitrate allocator has disabled some layers frame-rate or resolution are
// limited depending on the encoder configuration.
if (bw_limited_layers_) {
@ -1211,13 +1229,15 @@ void SendStatisticsProxy::OnInitialQualityResolutionAdaptDown() {
}
void SendStatisticsProxy::TryUpdateInitialQualityResolutionAdaptUp(
const AdaptationSteps& quality_counts) {
absl::optional<int> old_quality_downscales,
absl::optional<int> updated_quality_downscales) {
if (uma_container_->initial_quality_changes_.down == 0)
return;
if (quality_downscales_ > 0 &&
quality_counts.num_resolution_reductions.value_or(-1) <
quality_downscales_) {
if (old_quality_downscales.has_value() &&
old_quality_downscales.value() > 0 &&
updated_quality_downscales.value_or(-1) <
old_quality_downscales.value()) {
// Adapting up in quality.
if (uma_container_->initial_quality_changes_.down >
uma_container_->initial_quality_changes_.up) {
@ -1226,9 +1246,9 @@ void SendStatisticsProxy::TryUpdateInitialQualityResolutionAdaptUp(
}
}
void SendStatisticsProxy::SetAdaptTimer(const AdaptationSteps& counts,
void SendStatisticsProxy::SetAdaptTimer(const MaskedAdaptationCounts& counts,
StatsTimer* timer) {
if (counts.num_resolution_reductions || counts.num_framerate_reductions) {
if (counts.resolution_adaptations || counts.num_framerate_reductions) {
// Adaptation enabled.
if (!stats_.suspended)
timer->Start(clock_->TimeInMilliseconds());
@ -1409,4 +1429,45 @@ int SendStatisticsProxy::BoolSampleCounter::Fraction(
return -1;
return static_cast<int>((sum * multiplier / num_samples) + 0.5f);
}
SendStatisticsProxy::MaskedAdaptationCounts
SendStatisticsProxy::Adaptations::MaskedCpuCounts() const {
return Mask(cpu_counts_, cpu_settings_);
}
SendStatisticsProxy::MaskedAdaptationCounts
SendStatisticsProxy::Adaptations::MaskedQualityCounts() const {
return Mask(quality_counts_, quality_settings_);
}
void SendStatisticsProxy::Adaptations::set_cpu_counts(
const VideoAdaptationCounters& cpu_counts) {
cpu_counts_ = cpu_counts;
}
void SendStatisticsProxy::Adaptations::set_quality_counts(
const VideoAdaptationCounters& quality_counts) {
quality_counts_ = quality_counts;
}
void SendStatisticsProxy::Adaptations::UpdateMaskingSettings(
VideoStreamEncoderObserver::AdaptationSettings cpu_settings,
VideoStreamEncoderObserver::AdaptationSettings quality_settings) {
cpu_settings_ = std::move(cpu_settings);
quality_settings_ = std::move(quality_settings);
}
SendStatisticsProxy::MaskedAdaptationCounts
SendStatisticsProxy::Adaptations::Mask(
const VideoAdaptationCounters& counters,
const VideoStreamEncoderObserver::AdaptationSettings& settings) const {
MaskedAdaptationCounts masked_counts;
if (settings.resolution_scaling_enabled) {
masked_counts.resolution_adaptations = counters.resolution_adaptations;
}
if (settings.framerate_scaling_enabled) {
masked_counts.num_framerate_reductions = counters.fps_adaptations;
}
return masked_counts;
}
} // namespace webrtc

View File

@ -70,9 +70,13 @@ class SendStatisticsProxy : public VideoStreamEncoderObserver,
void OnFrameDropped(DropReason) override;
// Adaptation stats.
void OnAdaptationChanged(AdaptationReason reason,
const AdaptationSteps& cpu_counts,
const AdaptationSteps& quality_counts) override;
void OnAdaptationChanged(
AdaptationReason reason,
const VideoAdaptationCounters& cpu_counters,
const VideoAdaptationCounters& quality_counters) override;
void ClearAdaptationStats() override;
void UpdateAdaptationSettings(AdaptationSettings cpu_settings,
AdaptationSettings quality_settings) override;
void OnBitrateAllocationUpdated(
const VideoCodec& codec,
@ -223,11 +227,38 @@ class SendStatisticsProxy : public VideoStreamEncoderObserver,
VideoSendStream::StreamStats* GetStatsEntry(uint32_t ssrc)
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
void SetAdaptTimer(const AdaptationSteps& counts, StatsTimer* timer)
struct MaskedAdaptationCounts {
absl::optional<int> resolution_adaptations = absl::nullopt;
absl::optional<int> num_framerate_reductions = absl::nullopt;
};
struct Adaptations {
public:
MaskedAdaptationCounts MaskedCpuCounts() const;
MaskedAdaptationCounts MaskedQualityCounts() const;
void set_cpu_counts(const VideoAdaptationCounters& cpu_counts);
void set_quality_counts(const VideoAdaptationCounters& quality_counts);
void UpdateMaskingSettings(AdaptationSettings cpu_settings,
AdaptationSettings quality_settings);
private:
VideoAdaptationCounters cpu_counts_;
AdaptationSettings cpu_settings_;
VideoAdaptationCounters quality_counts_;
AdaptationSettings quality_settings_;
MaskedAdaptationCounts Mask(const VideoAdaptationCounters& counters,
const AdaptationSettings& settings) const;
};
void SetAdaptTimer(const MaskedAdaptationCounts& counts, StatsTimer* timer)
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
void UpdateAdaptationStats() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
void TryUpdateInitialQualityResolutionAdaptUp(
const AdaptationSteps& quality_counts)
absl::optional<int> old_quality_downscales,
absl::optional<int> updated_quality_downscales)
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
void UpdateEncoderFallbackStats(const CodecSpecificInfo* codec_info,
@ -250,8 +281,6 @@ class SendStatisticsProxy : public VideoStreamEncoderObserver,
VideoSendStream::Stats stats_ RTC_GUARDED_BY(crit_);
std::map<uint32_t, StatsUpdateTimes> update_times_ RTC_GUARDED_BY(crit_);
rtc::ExpFilter encode_time_ RTC_GUARDED_BY(crit_);
int quality_downscales_ RTC_GUARDED_BY(crit_);
int cpu_downscales_ RTC_GUARDED_BY(crit_);
QualityLimitationReasonTracker quality_limitation_reason_tracker_
RTC_GUARDED_BY(crit_);
rtc::RateTracker media_byte_rate_tracker_ RTC_GUARDED_BY(crit_);
@ -268,8 +297,7 @@ class SendStatisticsProxy : public VideoStreamEncoderObserver,
bool bw_limited_layers_ RTC_GUARDED_BY(crit_);
// Indicastes if the encoder internally downscales input image.
bool internal_encoder_scaler_ RTC_GUARDED_BY(crit_);
AdaptationSteps cpu_counts_ RTC_GUARDED_BY(crit_);
AdaptationSteps quality_counts_ RTC_GUARDED_BY(crit_);
Adaptations adaptations_ RTC_GUARDED_BY(crit_);
struct EncoderChangeEvent {
std::string previous_encoder_implementation;

View File

@ -45,6 +45,16 @@ const CodecSpecificInfo kDefaultCodecInfo = []() {
codec_info.codecType = kVideoCodecVP8;
return codec_info;
}();
const VideoStreamEncoderObserver::AdaptationSettings kScalingEnabled(true,
true);
const VideoStreamEncoderObserver::AdaptationSettings kFramerateScalingDisabled(
true,
false);
const VideoStreamEncoderObserver::AdaptationSettings kResolutionScalingDisabled(
false,
true);
const VideoStreamEncoderObserver::AdaptationSettings kScalingDisabled;
} // namespace
class SendStatisticsProxyTest : public ::testing::Test {
@ -432,81 +442,86 @@ TEST_F(SendStatisticsProxyTest,
}
TEST_F(SendStatisticsProxyTest, GetCpuAdaptationStats) {
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_resolution);
cpu_counts.num_framerate_reductions = 1;
cpu_counts.num_resolution_reductions = 0;
cpu_counts.fps_adaptations = 1;
cpu_counts.resolution_adaptations = 0;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
VideoStreamEncoderObserver::AdaptationReason::kCpu, cpu_counts,
quality_counts);
EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_framerate);
EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_resolution);
cpu_counts.num_framerate_reductions = 0;
cpu_counts.num_resolution_reductions = 1;
cpu_counts.fps_adaptations = 0;
cpu_counts.resolution_adaptations = 1;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
VideoStreamEncoderObserver::AdaptationReason::kCpu, cpu_counts,
quality_counts);
EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_resolution);
cpu_counts.num_framerate_reductions = 1;
cpu_counts.num_resolution_reductions = absl::nullopt;
cpu_counts.fps_adaptations = 1;
statistics_proxy_->UpdateAdaptationSettings(kResolutionScalingDisabled,
kResolutionScalingDisabled);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
VideoStreamEncoderObserver::AdaptationReason::kCpu, cpu_counts,
quality_counts);
EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_framerate);
EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_resolution);
cpu_counts.num_framerate_reductions = absl::nullopt;
cpu_counts.num_resolution_reductions = absl::nullopt;
statistics_proxy_->UpdateAdaptationSettings(kScalingDisabled,
kScalingDisabled);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
VideoStreamEncoderObserver::AdaptationReason::kCpu, cpu_counts,
quality_counts);
EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_resolution);
}
TEST_F(SendStatisticsProxyTest, GetQualityAdaptationStats) {
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
quality_counts.num_framerate_reductions = 1;
quality_counts.num_resolution_reductions = 0;
quality_counts.fps_adaptations = 1;
quality_counts.resolution_adaptations = 0;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_framerate);
EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
quality_counts.num_framerate_reductions = 0;
quality_counts.num_resolution_reductions = 1;
quality_counts.fps_adaptations = 0;
quality_counts.resolution_adaptations = 1;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
quality_counts.num_framerate_reductions = 1;
quality_counts.num_resolution_reductions = absl::nullopt;
quality_counts.fps_adaptations = 1;
statistics_proxy_->UpdateAdaptationSettings(kResolutionScalingDisabled,
kResolutionScalingDisabled);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_framerate);
EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
quality_counts.num_framerate_reductions = absl::nullopt;
quality_counts.num_resolution_reductions = absl::nullopt;
statistics_proxy_->UpdateAdaptationSettings(kScalingDisabled,
kScalingDisabled);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
}
TEST_F(SendStatisticsProxyTest, GetStatsReportsCpuAdaptChanges) {
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
EXPECT_EQ(0, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
cpu_counts.num_resolution_reductions = 1;
cpu_counts.resolution_adaptations = 1;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kCpu, cpu_counts,
quality_counts);
@ -514,7 +529,7 @@ TEST_F(SendStatisticsProxyTest, GetStatsReportsCpuAdaptChanges) {
EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_resolution);
EXPECT_EQ(1, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
cpu_counts.num_resolution_reductions = 2;
cpu_counts.resolution_adaptations = 2;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kCpu, cpu_counts,
quality_counts);
@ -525,11 +540,12 @@ TEST_F(SendStatisticsProxyTest, GetStatsReportsCpuAdaptChanges) {
}
TEST_F(SendStatisticsProxyTest, GetStatsReportsQualityAdaptChanges) {
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
EXPECT_EQ(0, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
quality_counts.num_framerate_reductions = 1;
quality_counts.fps_adaptations = 1;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
@ -537,7 +553,7 @@ TEST_F(SendStatisticsProxyTest, GetStatsReportsQualityAdaptChanges) {
EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
EXPECT_EQ(1, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
quality_counts.num_framerate_reductions = 0;
quality_counts.fps_adaptations = 0;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
@ -547,6 +563,77 @@ TEST_F(SendStatisticsProxyTest, GetStatsReportsQualityAdaptChanges) {
EXPECT_EQ(0, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
}
TEST_F(SendStatisticsProxyTest, TestAdaptationStatisticsMasking) {
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
EXPECT_EQ(0, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
EXPECT_EQ(0, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
quality_counts.resolution_adaptations = 1;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
quality_counts.fps_adaptations = 1;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
cpu_counts.resolution_adaptations = 1;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kCpu, cpu_counts,
quality_counts);
cpu_counts.fps_adaptations = 1;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kCpu, cpu_counts,
quality_counts);
// We have 1 fps and resolution reduction for both cpu and quality
EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_framerate);
EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_framerate);
EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_resolution);
EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
// Disable quality scaling. Expect quality scaling not limited.
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled,
kScalingDisabled);
EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_framerate);
EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_resolution);
EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
// Disable framerate scaling.
statistics_proxy_->UpdateAdaptationSettings(kFramerateScalingDisabled,
kFramerateScalingDisabled);
EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_resolution);
EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
// Disable resolution scaling.
statistics_proxy_->UpdateAdaptationSettings(kResolutionScalingDisabled,
kResolutionScalingDisabled);
EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_framerate);
EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_framerate);
EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_resolution);
EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
// Enable all
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_framerate);
EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_framerate);
EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_resolution);
EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
}
TEST_F(SendStatisticsProxyTest, AdaptChangesNotReported_AdaptationNotEnabled) {
// First RTP packet sent.
UpdateDataCounters(kFirstSsrc);
@ -563,11 +650,7 @@ TEST_F(SendStatisticsProxyTest, AdaptChangesNotReported_MinRuntimeNotPassed) {
// First RTP packet sent.
UpdateDataCounters(kFirstSsrc);
// Enable adaptation.
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
// Min runtime has not passed.
fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000 - 1);
statistics_proxy_.reset();
@ -581,11 +664,7 @@ TEST_F(SendStatisticsProxyTest, ZeroAdaptChangesReported) {
// First RTP packet sent.
UpdateDataCounters(kFirstSsrc);
// Enable adaptation.
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
// Min runtime has passed.
fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
statistics_proxy_.reset();
@ -603,11 +682,9 @@ TEST_F(SendStatisticsProxyTest, CpuAdaptChangesReported) {
// First RTP packet sent.
UpdateDataCounters(kFirstSsrc);
// Enable adaptation.
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
// Adapt changes: 1, elapsed time: 10 sec => 6 per minute.
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kCpu, cpu_counts,
@ -624,11 +701,9 @@ TEST_F(SendStatisticsProxyTest, ExcludesInitialQualityAdaptDownChange) {
// First RTP packet sent.
UpdateDataCounters(kFirstSsrc);
// Enable adaptation.
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
// Adapt changes: 1 (1 initial) = 0, elapsed time: 10 sec => 0 per minute.
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
@ -646,23 +721,21 @@ TEST_F(SendStatisticsProxyTest, ExcludesInitialQualityAdaptDownChanges) {
// First RTP packet sent.
UpdateDataCounters(kFirstSsrc);
// Enable adaptation.
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
// Adapt changes: 3 (2 initial) = 1, elapsed time: 10 sec => 6 per minute.
quality_counts.num_resolution_reductions = 1;
quality_counts.resolution_adaptations = 1;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
statistics_proxy_->OnInitialQualityResolutionAdaptDown();
quality_counts.num_resolution_reductions = 2;
quality_counts.resolution_adaptations = 2;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
statistics_proxy_->OnInitialQualityResolutionAdaptDown();
quality_counts.num_resolution_reductions = 3;
quality_counts.resolution_adaptations = 3;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
@ -678,11 +751,9 @@ TEST_F(SendStatisticsProxyTest, InitialQualityAdaptChangesNotExcludedOnError) {
// First RTP packet sent.
UpdateDataCounters(kFirstSsrc);
// Enable adaptation.
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
// Adapt changes: 1 (2 initial) = 1, elapsed time: 10 sec => 6 per minute.
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
@ -701,43 +772,42 @@ TEST_F(SendStatisticsProxyTest, ExcludesInitialQualityAdaptDownAndUpChanges) {
// First RTP packet sent.
UpdateDataCounters(kFirstSsrc);
// Enable adaptation.
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
statistics_proxy_->ClearAdaptationStats();
// Adapt changes: 8 (4 initial) = 4, elapsed time: 10 sec => 24 per minute.
quality_counts.num_resolution_reductions = 1;
quality_counts.resolution_adaptations = 1;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
statistics_proxy_->OnInitialQualityResolutionAdaptDown();
quality_counts.num_resolution_reductions = 2;
quality_counts.resolution_adaptations = 2;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
statistics_proxy_->OnInitialQualityResolutionAdaptDown();
quality_counts.num_resolution_reductions = 3;
quality_counts.resolution_adaptations = 3;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
quality_counts.num_framerate_reductions = 1;
quality_counts.fps_adaptations = 1;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
quality_counts.num_framerate_reductions = 0;
quality_counts.fps_adaptations = 0;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
quality_counts.num_resolution_reductions = 2; // Initial resolution up.
quality_counts.resolution_adaptations = 2; // Initial resolution up.
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
quality_counts.num_resolution_reductions = 1; // Initial resolution up.
quality_counts.resolution_adaptations = 1; // Initial resolution up.
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
quality_counts.num_resolution_reductions = 0;
quality_counts.resolution_adaptations = 0;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
@ -755,25 +825,20 @@ TEST_F(SendStatisticsProxyTest, AdaptChangesStatsExcludesDisabledTime) {
UpdateDataCounters(kFirstSsrc);
// Disable quality adaptation.
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
quality_counts.num_framerate_reductions = absl::nullopt;
quality_counts.num_resolution_reductions = absl::nullopt;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled,
kScalingDisabled);
fake_clock_.AdvanceTimeMilliseconds(10000);
// Enable quality adaptation.
// Adapt changes: 2, elapsed time: 20 sec.
quality_counts.num_framerate_reductions = 0;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
quality_counts.fps_adaptations = 0;
statistics_proxy_->UpdateAdaptationSettings(kResolutionScalingDisabled,
kResolutionScalingDisabled);
fake_clock_.AdvanceTimeMilliseconds(5000);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
statistics_proxy_->UpdateAdaptationSettings(kResolutionScalingDisabled,
kResolutionScalingDisabled);
fake_clock_.AdvanceTimeMilliseconds(9000);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
@ -784,32 +849,26 @@ TEST_F(SendStatisticsProxyTest, AdaptChangesStatsExcludesDisabledTime) {
quality_counts);
// Disable quality adaptation.
quality_counts.num_framerate_reductions = absl::nullopt;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
statistics_proxy_->UpdateAdaptationSettings(kScalingDisabled,
kScalingDisabled);
fake_clock_.AdvanceTimeMilliseconds(30000);
// Enable quality adaptation.
// Adapt changes: 1, elapsed time: 10 sec.
quality_counts.num_resolution_reductions = 0;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
quality_counts.resolution_adaptations = 0;
statistics_proxy_->UpdateAdaptationSettings(kFramerateScalingDisabled,
kFramerateScalingDisabled);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
fake_clock_.AdvanceTimeMilliseconds(10000);
// Disable quality adaptation.
quality_counts.num_resolution_reductions = absl::nullopt;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
statistics_proxy_->UpdateAdaptationSettings(kScalingDisabled,
kScalingDisabled);
fake_clock_.AdvanceTimeMilliseconds(5000);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
statistics_proxy_->UpdateAdaptationSettings(kScalingDisabled,
kScalingDisabled);
fake_clock_.AdvanceTimeMilliseconds(20000);
// Adapt changes: 3, elapsed time: 30 sec => 6 per minute.
@ -844,12 +903,10 @@ TEST_F(SendStatisticsProxyTest, QualityAdaptChangesStatsExcludesSuspendedTime) {
UpdateDataCounters(kFirstSsrc);
// Enable adaptation.
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
// Adapt changes: 2, elapsed time: 20 sec.
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
fake_clock_.AdvanceTimeMilliseconds(20000);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
@ -886,12 +943,10 @@ TEST_F(SendStatisticsProxyTest, CpuAdaptChangesStatsExcludesSuspendedTime) {
fake_clock_.AdvanceTimeMilliseconds(30000);
// Enable adaptation.
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
// Adapt changes: 1, elapsed time: 20 sec.
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
fake_clock_.AdvanceTimeMilliseconds(10000);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kCpu, cpu_counts,
@ -902,11 +957,8 @@ TEST_F(SendStatisticsProxyTest, CpuAdaptChangesStatsExcludesSuspendedTime) {
fake_clock_.AdvanceTimeMilliseconds(10000);
// Disable adaptation.
cpu_counts.num_framerate_reductions = absl::nullopt;
cpu_counts.num_resolution_reductions = absl::nullopt;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
statistics_proxy_->UpdateAdaptationSettings(kScalingDisabled,
kScalingDisabled);
fake_clock_.AdvanceTimeMilliseconds(30000);
// Suspend and resume video, stats time not started when scaling not enabled.
@ -917,11 +969,9 @@ TEST_F(SendStatisticsProxyTest, CpuAdaptChangesStatsExcludesSuspendedTime) {
// Enable adaptation.
// Adapt changes: 1, elapsed time: 10 sec.
cpu_counts.num_framerate_reductions = 0;
cpu_counts.num_resolution_reductions = 0;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
cpu_counts.fps_adaptations = 0;
cpu_counts.resolution_adaptations = 0;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
fake_clock_.AdvanceTimeMilliseconds(10000);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kCpu, cpu_counts,
@ -943,11 +993,9 @@ TEST_F(SendStatisticsProxyTest, AdaptChangesStatsNotStartedIfVideoSuspended) {
statistics_proxy_->OnSuspendChange(true);
// Enable adaptation, stats time not started when suspended.
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
fake_clock_.AdvanceTimeMilliseconds(10000);
// Resume video, stats time started.
@ -969,11 +1017,9 @@ TEST_F(SendStatisticsProxyTest, AdaptChangesStatsNotStartedIfVideoSuspended) {
TEST_F(SendStatisticsProxyTest, AdaptChangesStatsRestartsOnFirstSentPacket) {
// Send first packet, adaptation enabled.
// Elapsed time before first packet is sent should be excluded.
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
fake_clock_.AdvanceTimeMilliseconds(10000);
UpdateDataCounters(kFirstSsrc);
@ -994,17 +1040,12 @@ TEST_F(SendStatisticsProxyTest, AdaptChangesStatsRestartsOnFirstSentPacket) {
TEST_F(SendStatisticsProxyTest, AdaptChangesStatsStartedAfterFirstSentPacket) {
// Enable and disable adaptation.
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
fake_clock_.AdvanceTimeMilliseconds(60000);
cpu_counts.num_framerate_reductions = absl::nullopt;
cpu_counts.num_resolution_reductions = absl::nullopt;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
statistics_proxy_->UpdateAdaptationSettings(kScalingDisabled,
kScalingDisabled);
// Send first packet, scaling disabled.
// Elapsed time before first packet is sent should be excluded.
@ -1012,10 +1053,9 @@ TEST_F(SendStatisticsProxyTest, AdaptChangesStatsStartedAfterFirstSentPacket) {
fake_clock_.AdvanceTimeMilliseconds(60000);
// Enable adaptation.
cpu_counts.num_resolution_reductions = 0;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
cpu_counts.resolution_adaptations = 0;
statistics_proxy_->UpdateAdaptationSettings(kFramerateScalingDisabled,
kScalingDisabled);
fake_clock_.AdvanceTimeMilliseconds(10000);
UpdateDataCounters(kFirstSsrc);
@ -1036,13 +1076,10 @@ TEST_F(SendStatisticsProxyTest, AdaptChangesStatsStartedAfterFirstSentPacket) {
TEST_F(SendStatisticsProxyTest, AdaptChangesReportedAfterContentSwitch) {
// First RTP packet sent, cpu adaptation enabled.
UpdateDataCounters(kFirstSsrc);
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
quality_counts.num_framerate_reductions = absl::nullopt;
quality_counts.num_resolution_reductions = absl::nullopt;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled,
kScalingDisabled);
// Adapt changes: 2, elapsed time: 15 sec => 8 per minute.
statistics_proxy_->OnAdaptationChanged(
@ -1067,9 +1104,8 @@ TEST_F(SendStatisticsProxyTest, AdaptChangesReportedAfterContentSwitch) {
// First RTP packet sent, scaling enabled.
UpdateDataCounters(kFirstSsrc);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled,
kScalingDisabled);
// Adapt changes: 4, elapsed time: 120 sec => 2 per minute.
statistics_proxy_->OnAdaptationChanged(
@ -1100,11 +1136,11 @@ TEST_F(SendStatisticsProxyTest, AdaptChangesReportedAfterContentSwitch) {
TEST_F(SendStatisticsProxyTest,
QualityLimitationReasonIsCpuWhenCpuIsResolutionLimited) {
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
cpu_counts.num_resolution_reductions = 1;
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
cpu_counts.resolution_adaptations = 1;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kCpu, cpu_counts,
quality_counts);
@ -1115,11 +1151,12 @@ TEST_F(SendStatisticsProxyTest,
TEST_F(SendStatisticsProxyTest,
QualityLimitationReasonIsCpuWhenCpuIsFramerateLimited) {
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
cpu_counts.num_framerate_reductions = 1;
cpu_counts.fps_adaptations = 1;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kCpu, cpu_counts,
quality_counts);
@ -1130,11 +1167,12 @@ TEST_F(SendStatisticsProxyTest,
TEST_F(SendStatisticsProxyTest,
QualityLimitationReasonIsBandwidthWhenQualityIsResolutionLimited) {
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
quality_counts.num_resolution_reductions = 1;
quality_counts.resolution_adaptations = 1;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
@ -1145,11 +1183,12 @@ TEST_F(SendStatisticsProxyTest,
TEST_F(SendStatisticsProxyTest,
QualityLimitationReasonIsBandwidthWhenQualityIsFramerateLimited) {
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
quality_counts.num_framerate_reductions = 1;
quality_counts.fps_adaptations = 1;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
@ -1160,11 +1199,12 @@ TEST_F(SendStatisticsProxyTest,
TEST_F(SendStatisticsProxyTest,
QualityLimitationReasonIsBandwidthWhenBothCpuAndQualityIsLimited) {
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
cpu_counts.num_resolution_reductions = 1;
quality_counts.num_resolution_reductions = 1;
cpu_counts.resolution_adaptations = 1;
quality_counts.resolution_adaptations = 1;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
// Even if the last adaptation reason is kCpu, if the counters indicate being
// both CPU and quality (=bandwidth) limited, kBandwidth takes precedence.
@ -1177,19 +1217,20 @@ TEST_F(SendStatisticsProxyTest,
}
TEST_F(SendStatisticsProxyTest, QualityLimitationReasonIsNoneWhenNotLimited) {
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
// Observe a limitation due to CPU. This makes sure the test doesn't pass
// due to "none" being the default value.
cpu_counts.num_resolution_reductions = 1;
cpu_counts.resolution_adaptations = 1;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kCpu, cpu_counts,
quality_counts);
// Go back to not being limited.
cpu_counts.num_resolution_reductions = 0;
cpu_counts.resolution_adaptations = 0;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
VideoStreamEncoderObserver::AdaptationReason::kCpu, cpu_counts,
quality_counts);
EXPECT_EQ(QualityLimitationReason::kNone,
@ -1197,27 +1238,28 @@ TEST_F(SendStatisticsProxyTest, QualityLimitationReasonIsNoneWhenNotLimited) {
}
TEST_F(SendStatisticsProxyTest, QualityLimitationDurationIncreasesWithTime) {
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
// Not limited for 3000 ms
fake_clock_.AdvanceTimeMilliseconds(3000);
// CPU limited for 2000 ms
cpu_counts.num_resolution_reductions = 1;
cpu_counts.resolution_adaptations = 1;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kCpu, cpu_counts,
quality_counts);
fake_clock_.AdvanceTimeMilliseconds(2000);
// Bandwidth limited for 1000 ms
cpu_counts.num_resolution_reductions = 0;
quality_counts.num_resolution_reductions = 1;
cpu_counts.resolution_adaptations = 0;
quality_counts.resolution_adaptations = 1;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
fake_clock_.AdvanceTimeMilliseconds(1000);
// CPU limited for another 2000 ms
cpu_counts.num_resolution_reductions = 1;
quality_counts.num_resolution_reductions = 0;
cpu_counts.resolution_adaptations = 1;
quality_counts.resolution_adaptations = 0;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kCpu, cpu_counts,
quality_counts);
@ -1624,12 +1666,8 @@ TEST_F(SendStatisticsProxyTest, SentFpsHistogramExcludesSuspendedTime) {
}
TEST_F(SendStatisticsProxyTest, CpuLimitedHistogramNotUpdatedWhenDisabled) {
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
cpu_counts.num_resolution_reductions = absl::nullopt;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
statistics_proxy_->UpdateAdaptationSettings(kResolutionScalingDisabled,
kResolutionScalingDisabled);
for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
@ -1640,17 +1678,15 @@ TEST_F(SendStatisticsProxyTest, CpuLimitedHistogramNotUpdatedWhenDisabled) {
}
TEST_F(SendStatisticsProxyTest, CpuLimitedHistogramUpdated) {
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
cpu_counts.num_resolution_reductions = 0;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
cpu_counts.resolution_adaptations = 0;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
cpu_counts.num_resolution_reductions = 1;
cpu_counts.resolution_adaptations = 1;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kCpu, cpu_counts,
quality_counts);
@ -2033,12 +2069,8 @@ TEST_F(SendStatisticsProxyTest,
TEST_F(SendStatisticsProxyTest,
QualityLimitedHistogramsNotUpdatedWhenDisabled) {
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
quality_counts.num_resolution_reductions = absl::nullopt;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
statistics_proxy_->UpdateAdaptationSettings(kFramerateScalingDisabled,
kScalingDisabled);
EncodedImage encoded_image;
encoded_image.SetSpatialIndex(0);
for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
@ -2054,12 +2086,7 @@ TEST_F(SendStatisticsProxyTest,
TEST_F(SendStatisticsProxyTest,
QualityLimitedHistogramsUpdatedWhenEnabled_NoResolutionDownscale) {
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
quality_counts.num_resolution_reductions = 0;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
quality_counts);
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
EncodedImage encoded_image;
encoded_image.SetSpatialIndex(0);
for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
@ -2079,11 +2106,12 @@ TEST_F(SendStatisticsProxyTest,
TEST_F(SendStatisticsProxyTest,
QualityLimitedHistogramsUpdatedWhenEnabled_TwoResolutionDownscales) {
const int kDownscales = 2;
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
quality_counts.num_resolution_reductions = kDownscales;
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
quality_counts.resolution_adaptations = kDownscales;
statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kNone, cpu_counts,
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
EncodedImage encoded_image;
encoded_image.SetSpatialIndex(0);
@ -2126,9 +2154,11 @@ TEST_F(SendStatisticsProxyTest, GetStatsReportsBandwidthLimitedResolution) {
encoded_image._encodedHeight = kHeight / 2;
// Resolution scaled due to quality.
SendStatisticsProxy::AdaptationSteps cpu_counts;
SendStatisticsProxy::AdaptationSteps quality_counts;
quality_counts.num_resolution_reductions = 1;
VideoAdaptationCounters cpu_counts;
VideoAdaptationCounters quality_counts;
quality_counts.resolution_adaptations = 1;
statistics_proxy_->UpdateAdaptationSettings(kFramerateScalingDisabled,
kFramerateScalingDisabled);
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);
@ -2136,7 +2166,7 @@ TEST_F(SendStatisticsProxyTest, GetStatsReportsBandwidthLimitedResolution) {
EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
// Adapt up.
quality_counts.num_resolution_reductions = 0;
quality_counts.resolution_adaptations = 0;
statistics_proxy_->OnAdaptationChanged(
VideoStreamEncoderObserver::AdaptationReason::kQuality, cpu_counts,
quality_counts);

View File

@ -3959,6 +3959,7 @@ TEST_F(VideoStreamEncoderTest, RampsUpInQualityWhenBwIsHigh) {
// Reset encoder for field trials to take effect.
VideoEncoderConfig config = video_encoder_config_.Copy();
config.max_bitrate_bps = kTargetBitrateBps;
DataRate max_bitrate = DataRate::BitsPerSec(config.max_bitrate_bps);
ConfigureEncoder(std::move(config));
fake_encoder_.SetQp(kQpLow);
@ -3985,10 +3986,8 @@ TEST_F(VideoStreamEncoderTest, RampsUpInQualityWhenBwIsHigh) {
EXPECT_LT(source.sink_wants().max_pixel_count, kWidth * kHeight);
// Increase bitrate to encoder max.
video_stream_encoder_->OnBitrateUpdated(
DataRate::BitsPerSec(config.max_bitrate_bps),
DataRate::BitsPerSec(config.max_bitrate_bps),
DataRate::BitsPerSec(config.max_bitrate_bps), 0, 0, 0);
video_stream_encoder_->OnBitrateUpdated(max_bitrate, max_bitrate, max_bitrate,
0, 0, 0);
// Insert frames and advance |min_duration_ms|.
for (size_t i = 1; i <= 10; i++) {