From ad515a255be704c8768bd917a109f05e3fbc5312 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Bostr=C3=B6m?= Date: Mon, 27 Jan 2020 13:38:05 +0100 Subject: [PATCH] [Overuse] Move GetCpuOveruseOptions() to adaption module. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Evan Shrubsole Commit-Queue: Henrik Boström Cr-Commit-Position: refs/heads/master@{#30381} --- ...ame_detector_resource_adaptation_module.cc | 33 +++++++++++++++---- ...rame_detector_resource_adaptation_module.h | 7 ++-- video/video_stream_encoder.cc | 27 +++------------ video/video_stream_encoder.h | 4 --- 4 files changed, 34 insertions(+), 37 deletions(-) diff --git a/video/overuse_frame_detector_resource_adaptation_module.cc b/video/overuse_frame_detector_resource_adaptation_module.cc index baadb98c17..05813eb10d 100644 --- a/video/overuse_frame_detector_resource_adaptation_module.cc +++ b/video/overuse_frame_detector_resource_adaptation_module.cc @@ -24,6 +24,7 @@ #include "rtc_base/logging.h" #include "rtc_base/numerics/safe_conversions.h" #include "rtc_base/strings/string_builder.h" +#include "rtc_base/time_utils.h" #include "video/video_stream_encoder.h" namespace webrtc { @@ -341,12 +342,12 @@ OveruseFrameDetectorResourceAdaptationModule::AdaptCounter::ToString( OveruseFrameDetectorResourceAdaptationModule:: OveruseFrameDetectorResourceAdaptationModule( - VideoStreamEncoder* video_stream_encoder, + bool experiment_cpu_load_estimator, std::unique_ptr overuse_detector, VideoStreamEncoderObserver* encoder_stats_observer, ResourceAdaptationModuleListener* adaptation_listener) : adaptation_listener_(adaptation_listener), - video_stream_encoder_(video_stream_encoder), + experiment_cpu_load_estimator_(experiment_cpu_load_estimator), has_input_video_(false), degradation_preference_(DegradationPreference::DISABLED), adapt_counters_(), @@ -362,7 +363,6 @@ OveruseFrameDetectorResourceAdaptationModule:: encoder_settings_(absl::nullopt), encoder_stats_observer_(encoder_stats_observer) { RTC_DCHECK(adaptation_listener_); - RTC_DCHECK(video_stream_encoder_); RTC_DCHECK(overuse_detector_); RTC_DCHECK(encoder_stats_observer_); } @@ -381,9 +381,8 @@ void OveruseFrameDetectorResourceAdaptationModule::StartResourceAdaptation( // support adaptation caused by VideoStreamEncoder or QualityScaler invoking // AdaptUp() and AdaptDown() even when the OveruseDetector is inactive. RTC_DCHECK_EQ(adaptation_listener, adaptation_listener_); - overuse_detector_->StartCheckForOveruse( - TaskQueueBase::Current(), video_stream_encoder_->GetCpuOveruseOptions(), - this); + overuse_detector_->StartCheckForOveruse(TaskQueueBase::Current(), + GetCpuOveruseOptions(), this); overuse_detector_is_started_ = true; overuse_detector_->OnTargetFramerateUpdated( target_frame_rate_.has_value() @@ -707,6 +706,28 @@ bool OveruseFrameDetectorResourceAdaptationModule::AdaptDown( 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 OveruseFrameDetectorResourceAdaptationModule::GetVideoCodecTypeOrGeneric() const { diff --git a/video/overuse_frame_detector_resource_adaptation_module.h b/video/overuse_frame_detector_resource_adaptation_module.h index 7c63b8009a..7d266fa35d 100644 --- a/video/overuse_frame_detector_resource_adaptation_module.h +++ b/video/overuse_frame_detector_resource_adaptation_module.h @@ -40,7 +40,6 @@ class VideoStreamEncoder; // // This class is single-threaded. The caller is responsible for ensuring safe // usage. -// TODO(hbos): Reduce the coupling with VideoStreamEncoder. // TODO(hbos): Add unittests specific to this class, it is currently only tested // indirectly in video_stream_encoder_unittest.cc and other tests exercising // VideoStreamEncoder. @@ -55,7 +54,7 @@ class OveruseFrameDetectorResourceAdaptationModule // The module can be constructed on any sequence, but must be initialized and // used on a single sequence, e.g. the encoder queue. OveruseFrameDetectorResourceAdaptationModule( - VideoStreamEncoder* video_stream_encoder, + bool experiment_cpu_load_estimator, std::unique_ptr overuse_detector, VideoStreamEncoderObserver* encoder_stats_observer, ResourceAdaptationModuleListener* adaptation_listener); @@ -169,6 +168,7 @@ class OveruseFrameDetectorResourceAdaptationModule enum class Mode { kAdaptUp, kAdaptDown } mode_; }; + CpuOveruseOptions GetCpuOveruseOptions() const; VideoCodecType GetVideoCodecTypeOrGeneric() const; int LastInputFrameSizeOrDefault() const; @@ -187,10 +187,9 @@ class OveruseFrameDetectorResourceAdaptationModule bool CanAdaptUpResolution(int pixels, uint32_t bitrate_bps) const; ResourceAdaptationModuleListener* const adaptation_listener_; + const bool experiment_cpu_load_estimator_; // The restrictions that |adaptation_listener_| is informed of. VideoSourceRestrictions video_source_restrictions_; - // Used to query CpuOveruseOptions at StartCheckForOveruse(). - VideoStreamEncoder* video_stream_encoder_; bool has_input_video_; DegradationPreference degradation_preference_; // Counters used for deciding if the video resolution or framerate is diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc index c48c15bd37..716a56e978 100644 --- a/video/video_stream_encoder.cc +++ b/video/video_stream_encoder.cc @@ -312,7 +312,7 @@ VideoStreamEncoder::VideoStreamEncoder( /*source=*/nullptr)), resource_adaptation_module_( std::make_unique( - /*video_stream_encoder=*/this, + settings_.experiment_cpu_load_estimator, std::move(overuse_detector), encoder_stats_observer, /*adaptation_listener=*/this)), @@ -663,9 +663,6 @@ void VideoStreamEncoder::ReconfigureEncoder() { } send_codec_ = codec; - resource_adaptation_module_->SetEncoderSettings(EncoderSettings( - encoder_->GetEncoderInfo(), encoder_config_.Copy(), send_codec_)); - encoder_switch_experiment_.SetCodec(send_codec_.codecType); quality_rampup_experiment_.SetMaxBitrate( last_frame_info_->width * last_frame_info_->height, codec.maxBitrate); @@ -702,6 +699,9 @@ void VideoStreamEncoder::ReconfigureEncoder() { was_encode_called_since_last_initialization_ = false; } + resource_adaptation_module_->SetEncoderSettings(EncoderSettings( + encoder_->GetEncoderInfo(), encoder_config_.Copy(), send_codec_)); + if (success) { next_frame_types_.clear(); next_frame_types_.resize( @@ -1700,25 +1700,6 @@ bool VideoStreamEncoder::TryQualityRampup(int64_t now_ms) { 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( AdaptationObserverInterface::AdaptReason reason) { RTC_DCHECK_RUN_ON(&encoder_queue_); diff --git a/video/video_stream_encoder.h b/video/video_stream_encoder.h index b7af6840b9..01d77382a2 100644 --- a/video/video_stream_encoder.h +++ b/video/video_stream_encoder.h @@ -112,10 +112,6 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface, uint8_t fraction_lost, 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: // Used for testing. For example the |ScalingObserverInterface| methods must // be called on |encoder_queue_|.