[Overuse] Move GetCpuOveruseOptions() to adaption module.

This removes the last remaining explicit reference from
OveruseFrameDetectorResourceAdaptationModule to
VideoStreamEncoder.

VideoStreamEncoder's call to SetEncoderSettings() inside
ReconfigureEncoder() is moved a few lines down - it was discovered that
during these lines the EncoderInfo config could get modified in
response to InitEncode() - so this fixes a potential bug.

Bug: webrtc:11222
Change-Id: I9746f28a4df8e631e297669c10636bf17b39acec
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/167363
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Evan Shrubsole <eshr@google.com>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30381}
This commit is contained in:
Henrik Boström
2020-01-27 13:38:05 +01:00
committed by Commit Bot
parent ff0e4dbd1f
commit ad515a255b
4 changed files with 34 additions and 37 deletions

View File

@ -24,6 +24,7 @@
#include "rtc_base/logging.h" #include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_conversions.h" #include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/strings/string_builder.h" #include "rtc_base/strings/string_builder.h"
#include "rtc_base/time_utils.h"
#include "video/video_stream_encoder.h" #include "video/video_stream_encoder.h"
namespace webrtc { namespace webrtc {
@ -341,12 +342,12 @@ OveruseFrameDetectorResourceAdaptationModule::AdaptCounter::ToString(
OveruseFrameDetectorResourceAdaptationModule:: OveruseFrameDetectorResourceAdaptationModule::
OveruseFrameDetectorResourceAdaptationModule( OveruseFrameDetectorResourceAdaptationModule(
VideoStreamEncoder* video_stream_encoder, bool experiment_cpu_load_estimator,
std::unique_ptr<OveruseFrameDetector> overuse_detector, std::unique_ptr<OveruseFrameDetector> overuse_detector,
VideoStreamEncoderObserver* encoder_stats_observer, VideoStreamEncoderObserver* encoder_stats_observer,
ResourceAdaptationModuleListener* adaptation_listener) ResourceAdaptationModuleListener* adaptation_listener)
: adaptation_listener_(adaptation_listener), : adaptation_listener_(adaptation_listener),
video_stream_encoder_(video_stream_encoder), experiment_cpu_load_estimator_(experiment_cpu_load_estimator),
has_input_video_(false), has_input_video_(false),
degradation_preference_(DegradationPreference::DISABLED), degradation_preference_(DegradationPreference::DISABLED),
adapt_counters_(), adapt_counters_(),
@ -362,7 +363,6 @@ OveruseFrameDetectorResourceAdaptationModule::
encoder_settings_(absl::nullopt), encoder_settings_(absl::nullopt),
encoder_stats_observer_(encoder_stats_observer) { encoder_stats_observer_(encoder_stats_observer) {
RTC_DCHECK(adaptation_listener_); RTC_DCHECK(adaptation_listener_);
RTC_DCHECK(video_stream_encoder_);
RTC_DCHECK(overuse_detector_); RTC_DCHECK(overuse_detector_);
RTC_DCHECK(encoder_stats_observer_); RTC_DCHECK(encoder_stats_observer_);
} }
@ -381,9 +381,8 @@ void OveruseFrameDetectorResourceAdaptationModule::StartResourceAdaptation(
// support adaptation caused by VideoStreamEncoder or QualityScaler invoking // support adaptation caused by VideoStreamEncoder or QualityScaler invoking
// AdaptUp() and AdaptDown() even when the OveruseDetector is inactive. // AdaptUp() and AdaptDown() even when the OveruseDetector is inactive.
RTC_DCHECK_EQ(adaptation_listener, adaptation_listener_); RTC_DCHECK_EQ(adaptation_listener, adaptation_listener_);
overuse_detector_->StartCheckForOveruse( overuse_detector_->StartCheckForOveruse(TaskQueueBase::Current(),
TaskQueueBase::Current(), video_stream_encoder_->GetCpuOveruseOptions(), GetCpuOveruseOptions(), this);
this);
overuse_detector_is_started_ = true; overuse_detector_is_started_ = true;
overuse_detector_->OnTargetFramerateUpdated( overuse_detector_->OnTargetFramerateUpdated(
target_frame_rate_.has_value() target_frame_rate_.has_value()
@ -707,6 +706,28 @@ bool OveruseFrameDetectorResourceAdaptationModule::AdaptDown(
return did_adapt; return did_adapt;
} }
// TODO(pbos): Lower these thresholds (to closer to 100%) when we handle
// pipelining encoders better (multiple input frames before something comes
// out). This should effectively turn off CPU adaptations for systems that
// remotely cope with the load right now.
CpuOveruseOptions
OveruseFrameDetectorResourceAdaptationModule::GetCpuOveruseOptions() const {
// This is already ensured by the only caller of this method:
// StartResourceAdaptation().
RTC_DCHECK(encoder_settings_.has_value());
CpuOveruseOptions options;
// Hardware accelerated encoders are assumed to be pipelined; give them
// additional overuse time.
if (encoder_settings_->encoder_info().is_hardware_accelerated) {
options.low_encode_usage_threshold_percent = 150;
options.high_encode_usage_threshold_percent = 200;
}
if (experiment_cpu_load_estimator_) {
options.filter_time_ms = 5 * rtc::kNumMillisecsPerSec;
}
return options;
}
VideoCodecType VideoCodecType
OveruseFrameDetectorResourceAdaptationModule::GetVideoCodecTypeOrGeneric() OveruseFrameDetectorResourceAdaptationModule::GetVideoCodecTypeOrGeneric()
const { const {

View File

@ -40,7 +40,6 @@ class VideoStreamEncoder;
// //
// This class is single-threaded. The caller is responsible for ensuring safe // This class is single-threaded. The caller is responsible for ensuring safe
// usage. // usage.
// TODO(hbos): Reduce the coupling with VideoStreamEncoder.
// TODO(hbos): Add unittests specific to this class, it is currently only tested // TODO(hbos): Add unittests specific to this class, it is currently only tested
// indirectly in video_stream_encoder_unittest.cc and other tests exercising // indirectly in video_stream_encoder_unittest.cc and other tests exercising
// VideoStreamEncoder. // VideoStreamEncoder.
@ -55,7 +54,7 @@ class OveruseFrameDetectorResourceAdaptationModule
// The module can be constructed on any sequence, but must be initialized and // The module can be constructed on any sequence, but must be initialized and
// used on a single sequence, e.g. the encoder queue. // used on a single sequence, e.g. the encoder queue.
OveruseFrameDetectorResourceAdaptationModule( OveruseFrameDetectorResourceAdaptationModule(
VideoStreamEncoder* video_stream_encoder, bool experiment_cpu_load_estimator,
std::unique_ptr<OveruseFrameDetector> overuse_detector, std::unique_ptr<OveruseFrameDetector> overuse_detector,
VideoStreamEncoderObserver* encoder_stats_observer, VideoStreamEncoderObserver* encoder_stats_observer,
ResourceAdaptationModuleListener* adaptation_listener); ResourceAdaptationModuleListener* adaptation_listener);
@ -169,6 +168,7 @@ class OveruseFrameDetectorResourceAdaptationModule
enum class Mode { kAdaptUp, kAdaptDown } mode_; enum class Mode { kAdaptUp, kAdaptDown } mode_;
}; };
CpuOveruseOptions GetCpuOveruseOptions() const;
VideoCodecType GetVideoCodecTypeOrGeneric() const; VideoCodecType GetVideoCodecTypeOrGeneric() const;
int LastInputFrameSizeOrDefault() const; int LastInputFrameSizeOrDefault() const;
@ -187,10 +187,9 @@ class OveruseFrameDetectorResourceAdaptationModule
bool CanAdaptUpResolution(int pixels, uint32_t bitrate_bps) const; bool CanAdaptUpResolution(int pixels, uint32_t bitrate_bps) const;
ResourceAdaptationModuleListener* const adaptation_listener_; ResourceAdaptationModuleListener* const adaptation_listener_;
const bool experiment_cpu_load_estimator_;
// The restrictions that |adaptation_listener_| is informed of. // The restrictions that |adaptation_listener_| is informed of.
VideoSourceRestrictions video_source_restrictions_; VideoSourceRestrictions video_source_restrictions_;
// Used to query CpuOveruseOptions at StartCheckForOveruse().
VideoStreamEncoder* video_stream_encoder_;
bool has_input_video_; bool has_input_video_;
DegradationPreference degradation_preference_; DegradationPreference degradation_preference_;
// Counters used for deciding if the video resolution or framerate is // Counters used for deciding if the video resolution or framerate is

View File

@ -312,7 +312,7 @@ VideoStreamEncoder::VideoStreamEncoder(
/*source=*/nullptr)), /*source=*/nullptr)),
resource_adaptation_module_( resource_adaptation_module_(
std::make_unique<OveruseFrameDetectorResourceAdaptationModule>( std::make_unique<OveruseFrameDetectorResourceAdaptationModule>(
/*video_stream_encoder=*/this, settings_.experiment_cpu_load_estimator,
std::move(overuse_detector), std::move(overuse_detector),
encoder_stats_observer, encoder_stats_observer,
/*adaptation_listener=*/this)), /*adaptation_listener=*/this)),
@ -663,9 +663,6 @@ void VideoStreamEncoder::ReconfigureEncoder() {
} }
send_codec_ = codec; send_codec_ = codec;
resource_adaptation_module_->SetEncoderSettings(EncoderSettings(
encoder_->GetEncoderInfo(), encoder_config_.Copy(), send_codec_));
encoder_switch_experiment_.SetCodec(send_codec_.codecType); encoder_switch_experiment_.SetCodec(send_codec_.codecType);
quality_rampup_experiment_.SetMaxBitrate( quality_rampup_experiment_.SetMaxBitrate(
last_frame_info_->width * last_frame_info_->height, codec.maxBitrate); last_frame_info_->width * last_frame_info_->height, codec.maxBitrate);
@ -702,6 +699,9 @@ void VideoStreamEncoder::ReconfigureEncoder() {
was_encode_called_since_last_initialization_ = false; was_encode_called_since_last_initialization_ = false;
} }
resource_adaptation_module_->SetEncoderSettings(EncoderSettings(
encoder_->GetEncoderInfo(), encoder_config_.Copy(), send_codec_));
if (success) { if (success) {
next_frame_types_.clear(); next_frame_types_.clear();
next_frame_types_.resize( next_frame_types_.resize(
@ -1700,25 +1700,6 @@ bool VideoStreamEncoder::TryQualityRampup(int64_t now_ms) {
return false; return false;
} }
// TODO(pbos): Lower these thresholds (to closer to 100%) when we handle
// pipelining encoders better (multiple input frames before something comes
// out). This should effectively turn off CPU adaptations for systems that
// remotely cope with the load right now.
CpuOveruseOptions VideoStreamEncoder::GetCpuOveruseOptions() const {
RTC_DCHECK_RUN_ON(&encoder_queue_);
CpuOveruseOptions options;
// Hardware accelerated encoders are assumed to be pipelined; give them
// additional overuse time.
if (encoder_->GetEncoderInfo().is_hardware_accelerated) {
options.low_encode_usage_threshold_percent = 150;
options.high_encode_usage_threshold_percent = 200;
}
if (settings_.experiment_cpu_load_estimator) {
options.filter_time_ms = 5 * rtc::kNumMillisecsPerSec;
}
return options;
}
bool VideoStreamEncoder::TriggerAdaptDown( bool VideoStreamEncoder::TriggerAdaptDown(
AdaptationObserverInterface::AdaptReason reason) { AdaptationObserverInterface::AdaptReason reason) {
RTC_DCHECK_RUN_ON(&encoder_queue_); RTC_DCHECK_RUN_ON(&encoder_queue_);

View File

@ -112,10 +112,6 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
uint8_t fraction_lost, uint8_t fraction_lost,
int64_t round_trip_time_ms) override; int64_t round_trip_time_ms) override;
// If an OveruseFrameDetectorResourceAdaptationModule is used, this method is
// used by the module to configure its OveruseFrameDetector.
CpuOveruseOptions GetCpuOveruseOptions() const;
protected: protected:
// Used for testing. For example the |ScalingObserverInterface| methods must // Used for testing. For example the |ScalingObserverInterface| methods must
// be called on |encoder_queue_|. // be called on |encoder_queue_|.