[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:

committed by
Commit Bot

parent
ff0e4dbd1f
commit
ad515a255b
@ -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<OveruseFrameDetector> 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 {
|
||||
|
@ -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<OveruseFrameDetector> 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
|
||||
|
@ -312,7 +312,7 @@ VideoStreamEncoder::VideoStreamEncoder(
|
||||
/*source=*/nullptr)),
|
||||
resource_adaptation_module_(
|
||||
std::make_unique<OveruseFrameDetectorResourceAdaptationModule>(
|
||||
/*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_);
|
||||
|
@ -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_|.
|
||||
|
Reference in New Issue
Block a user