Postpone setting of CpuOveruseOptions.

This will enable changing thresholds when switching between hardware
and software encoders. It is also a partial revert of
https://webrtc-review.googlesource.com/33340: construction of the
OveruseFrameDetector is still in VideoSendStream, but configuration is
moved back to VideoStreamEncoder.

Longer term, information about HW vs SW, or generally, about resources
consumed by the encoder, should be passed in the per-frame callbacks
to OveruseFrameDetector, and then the CpuOveruseOptions could move
back to construction time.

Bug: webrtc:8504, webrtc:8830
Change-Id: I44577519d4e05356730cac9bd9ae3c74bfc17ed7
Reviewed-on: https://webrtc-review.googlesource.com/65163
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22761}
This commit is contained in:
Niels Möller
2018-03-28 16:40:58 +02:00
committed by Commit Bot
parent 83d676bd15
commit d1f7eb6e83
7 changed files with 89 additions and 59 deletions

View File

@ -29,8 +29,7 @@ class MockVideoStreamEncoder : public VideoStreamEncoder {
send_stats_proxy,
VideoSendStream::Config::EncoderSettings(nullptr),
nullptr,
rtc::MakeUnique<OveruseFrameDetector>(CpuOveruseOptions(),
nullptr)) {}
rtc::MakeUnique<OveruseFrameDetector>(nullptr)) {}
~MockVideoStreamEncoder() { Stop(); }
MOCK_METHOD0(SendKeyFrame, void());

View File

@ -510,10 +510,8 @@ class OveruseFrameDetector::CheckOveruseTask : public rtc::QueuedTask {
};
OveruseFrameDetector::OveruseFrameDetector(
const CpuOveruseOptions& options,
CpuOveruseMetricsObserver* metrics_observer)
: check_overuse_task_(nullptr),
options_(options),
metrics_observer_(metrics_observer),
num_process_times_(0),
// TODO(nisse): Use rtc::Optional
@ -525,8 +523,7 @@ OveruseFrameDetector::OveruseFrameDetector(
num_overuse_detections_(0),
last_rampup_time_ms_(-1),
in_quick_rampup_(false),
current_rampup_delay_ms_(kStandardRampUpDelayMs),
usage_(CreateProcessingUsage(options)) {
current_rampup_delay_ms_(kStandardRampUpDelayMs) {
task_checker_.Detach();
}
@ -535,10 +532,13 @@ OveruseFrameDetector::~OveruseFrameDetector() {
}
void OveruseFrameDetector::StartCheckForOveruse(
const CpuOveruseOptions& options,
AdaptationObserverInterface* overuse_observer) {
RTC_DCHECK_CALLED_SEQUENTIALLY(&task_checker_);
RTC_DCHECK(!check_overuse_task_);
RTC_DCHECK(overuse_observer != nullptr);
SetOptions(options);
check_overuse_task_ = new CheckOveruseTask(this, overuse_observer);
}
void OveruseFrameDetector::StopCheckForOveruse() {
@ -669,6 +669,14 @@ void OveruseFrameDetector::CheckForOveruse(
<< " rampup delay " << rampup_delay;
}
void OveruseFrameDetector::SetOptions(const CpuOveruseOptions& options) {
RTC_DCHECK_CALLED_SEQUENTIALLY(&task_checker_);
options_ = options;
// Force reset with next frame.
num_pixels_ = 0;
usage_ = CreateProcessingUsage(options);
}
bool OveruseFrameDetector::IsOverusing(const CpuOveruseMetrics& metrics) {
RTC_DCHECK_CALLED_SEQUENTIALLY(&task_checker_);

View File

@ -65,12 +65,12 @@ class CpuOveruseMetricsObserver {
// check for overuse.
class OveruseFrameDetector {
public:
OveruseFrameDetector(const CpuOveruseOptions& options,
CpuOveruseMetricsObserver* metrics_observer);
explicit OveruseFrameDetector(CpuOveruseMetricsObserver* metrics_observer);
virtual ~OveruseFrameDetector();
// Start to periodically check for overuse.
void StartCheckForOveruse(AdaptationObserverInterface* overuse_observer);
void StartCheckForOveruse(const CpuOveruseOptions& options,
AdaptationObserverInterface* overuse_observer);
// StopCheckForOveruse must be called before destruction if
// StartCheckForOveruse has been called.
@ -116,6 +116,7 @@ class OveruseFrameDetector {
protected:
// Protected for test purposes.
void CheckForOveruse(AdaptationObserverInterface* overuse_observer);
void SetOptions(const CpuOveruseOptions& options);
private:
class CheckOveruseTask;
@ -136,7 +137,7 @@ class OveruseFrameDetector {
// Owned by the task queue from where StartCheckForOveruse is called.
CheckOveruseTask* check_overuse_task_;
const CpuOveruseOptions options_;
CpuOveruseOptions options_;
// Stats metrics.
CpuOveruseMetricsObserver* const metrics_observer_;
@ -156,8 +157,7 @@ class OveruseFrameDetector {
bool in_quick_rampup_ RTC_GUARDED_BY(task_checker_);
int current_rampup_delay_ms_ RTC_GUARDED_BY(task_checker_);
const std::unique_ptr<ProcessingUsage> usage_
RTC_PT_GUARDED_BY(task_checker_);
std::unique_ptr<ProcessingUsage> usage_ RTC_PT_GUARDED_BY(task_checker_);
RTC_DISALLOW_COPY_AND_ASSIGN(OveruseFrameDetector);
};

View File

@ -58,13 +58,13 @@ class CpuOveruseObserverImpl : public AdaptationObserverInterface {
class OveruseFrameDetectorUnderTest : public OveruseFrameDetector {
public:
OveruseFrameDetectorUnderTest(const CpuOveruseOptions& options,
CpuOveruseMetricsObserver* metrics_observer)
: OveruseFrameDetector(options,
metrics_observer) {}
explicit OveruseFrameDetectorUnderTest(
CpuOveruseMetricsObserver* metrics_observer)
: OveruseFrameDetector(metrics_observer) {}
~OveruseFrameDetectorUnderTest() {}
using OveruseFrameDetector::CheckForOveruse;
using OveruseFrameDetector::SetOptions;
};
class OveruseFrameDetectorTest : public ::testing::Test,
@ -73,12 +73,9 @@ class OveruseFrameDetectorTest : public ::testing::Test,
void SetUp() override {
observer_ = &mock_observer_;
options_.min_process_count = 0;
ReinitializeOveruseDetector();
}
void ReinitializeOveruseDetector() {
overuse_detector_.reset(new OveruseFrameDetectorUnderTest(
options_, this));
overuse_detector_ = rtc::MakeUnique<OveruseFrameDetectorUnderTest>(this);
// Unfortunately, we can't call SetOptions here, since that would break
// single-threading requirements in the RunOnTqNormalUsage test.
}
void OnEncodedFrameTimeMeasured(int encode_time_ms,
@ -199,12 +196,14 @@ class OveruseFrameDetectorTest : public ::testing::Test,
// UsagePercent() < low_encode_usage_threshold_percent => underuse.
TEST_F(OveruseFrameDetectorTest, TriggerOveruse) {
// usage > high => overuse
overuse_detector_->SetOptions(options_);
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
TriggerOveruse(options_.high_threshold_consecutive_count);
}
TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) {
// usage > high => overuse
overuse_detector_->SetOptions(options_);
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
TriggerOveruse(options_.high_threshold_consecutive_count);
// usage < low => underuse
@ -213,6 +212,7 @@ TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) {
}
TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) {
overuse_detector_->SetOptions(options_);
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(2);
TriggerOveruse(options_.high_threshold_consecutive_count);
TriggerOveruse(options_.high_threshold_consecutive_count);
@ -225,8 +225,7 @@ TEST_F(OveruseFrameDetectorTest, TriggerUnderuseWithMinProcessCount) {
options_.min_process_count = 1;
CpuOveruseObserverImpl overuse_observer;
observer_ = nullptr;
overuse_detector_.reset(new OveruseFrameDetectorUnderTest(
options_, this));
overuse_detector_->SetOptions(options_);
InsertAndSendFramesWithInterval(
1200, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
overuse_detector_->CheckForOveruse(&overuse_observer);
@ -237,6 +236,7 @@ TEST_F(OveruseFrameDetectorTest, TriggerUnderuseWithMinProcessCount) {
}
TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) {
overuse_detector_->SetOptions(options_);
EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(0);
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(64);
for (size_t i = 0; i < 64; ++i) {
@ -245,26 +245,30 @@ TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) {
}
TEST_F(OveruseFrameDetectorTest, ConsecutiveCountTriggersOveruse) {
overuse_detector_->SetOptions(options_);
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
options_.high_threshold_consecutive_count = 2;
ReinitializeOveruseDetector();
overuse_detector_->SetOptions(options_);
TriggerOveruse(2);
}
TEST_F(OveruseFrameDetectorTest, IncorrectConsecutiveCountTriggersNoOveruse) {
overuse_detector_->SetOptions(options_);
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(0);
options_.high_threshold_consecutive_count = 2;
ReinitializeOveruseDetector();
overuse_detector_->SetOptions(options_);
TriggerOveruse(1);
}
TEST_F(OveruseFrameDetectorTest, ProcessingUsage) {
overuse_detector_->SetOptions(options_);
InsertAndSendFramesWithInterval(
1000, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
EXPECT_EQ(kProcessTimeUs * 100 / kFrameIntervalUs, UsagePercent());
}
TEST_F(OveruseFrameDetectorTest, ResetAfterResolutionChange) {
overuse_detector_->SetOptions(options_);
ForceUpdate(kWidth, kHeight);
EXPECT_EQ(InitialUsage(), UsagePercent());
InsertAndSendFramesWithInterval(
@ -276,6 +280,7 @@ TEST_F(OveruseFrameDetectorTest, ResetAfterResolutionChange) {
}
TEST_F(OveruseFrameDetectorTest, ResetAfterFrameTimeout) {
overuse_detector_->SetOptions(options_);
ForceUpdate(kWidth, kHeight);
EXPECT_EQ(InitialUsage(), UsagePercent());
InsertAndSendFramesWithInterval(
@ -295,7 +300,7 @@ TEST_F(OveruseFrameDetectorTest, ResetAfterFrameTimeout) {
TEST_F(OveruseFrameDetectorTest, MinFrameSamplesBeforeUpdating) {
options_.min_frame_samples = 40;
ReinitializeOveruseDetector();
overuse_detector_->SetOptions(options_);
InsertAndSendFramesWithInterval(
40, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
EXPECT_EQ(InitialUsage(), UsagePercent());
@ -314,11 +319,13 @@ TEST_F(OveruseFrameDetectorTest, MinFrameSamplesBeforeUpdating) {
}
TEST_F(OveruseFrameDetectorTest, InitialProcessingUsage) {
overuse_detector_->SetOptions(options_);
ForceUpdate(kWidth, kHeight);
EXPECT_EQ(InitialUsage(), UsagePercent());
}
TEST_F(OveruseFrameDetectorTest, MeasuresMultipleConcurrentSamples) {
overuse_detector_->SetOptions(options_);
EXPECT_CALL(mock_observer_, AdaptDown(reason_))
.Times(testing::AtLeast(1));
static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
@ -342,6 +349,7 @@ TEST_F(OveruseFrameDetectorTest, MeasuresMultipleConcurrentSamples) {
TEST_F(OveruseFrameDetectorTest, UpdatesExistingSamples) {
// >85% encoding time should trigger overuse.
overuse_detector_->SetOptions(options_);
EXPECT_CALL(mock_observer_, AdaptDown(reason_))
.Times(testing::AtLeast(1));
static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
@ -372,7 +380,7 @@ TEST_F(OveruseFrameDetectorTest, RunOnTqNormalUsage) {
rtc::Event event(false, false);
queue.PostTask([this, &event] {
overuse_detector_->StartCheckForOveruse(observer_);
overuse_detector_->StartCheckForOveruse(options_, observer_);
event.Set();
});
event.Wait(rtc::Event::kForever);
@ -401,6 +409,7 @@ TEST_F(OveruseFrameDetectorTest, MaxIntervalScalesWithFramerate) {
const int kCapturerMaxFrameRate = 30;
const int kEncodeMaxFrameRate = 20; // Maximum fps the encoder can sustain.
overuse_detector_->SetOptions(options_);
// Trigger overuse.
int64_t frame_interval_us = rtc::kNumMicrosecsPerSec / kCapturerMaxFrameRate;
// Processing time just below over use limit given kEncodeMaxFrameRate.
@ -434,6 +443,7 @@ TEST_F(OveruseFrameDetectorTest, MaxIntervalScalesWithFramerate) {
TEST_F(OveruseFrameDetectorTest, RespectsMinFramerate) {
const int kMinFrameRate = 7; // Minimum fps allowed by current detector impl.
overuse_detector_->SetOptions(options_);
overuse_detector_->OnTargetFramerateUpdated(kMinFrameRate);
// Normal usage just at the limit.
@ -470,6 +480,7 @@ TEST_F(OveruseFrameDetectorTest, RespectsMinFramerate) {
TEST_F(OveruseFrameDetectorTest, LimitsMaxFrameInterval) {
const int kMaxFrameRate = 20;
overuse_detector_->SetOptions(options_);
overuse_detector_->OnTargetFramerateUpdated(kMaxFrameRate);
int64_t frame_interval_us = rtc::kNumMicrosecsPerSec / kMaxFrameRate;
// Maximum frame interval allowed is 35% above ideal.
@ -518,6 +529,7 @@ TEST_F(OveruseFrameDetectorTest, NoOveruseForLargeRandomFrameInterval) {
// EXPECT_CALL(mock_observer_, AdaptDown(_)).Times(0);
// EXPECT_CALL(mock_observer_, AdaptUp(reason_))
// .Times(testing::AtLeast(1));
overuse_detector_->SetOptions(options_);
const int kNumFrames = 500;
const int kEncodeTimeUs = 100 * rtc::kNumMicrosecsPerMillisec;
@ -542,6 +554,7 @@ TEST_F(OveruseFrameDetectorTest, NoOveruseForLargeRandomFrameInterval) {
TEST_F(OveruseFrameDetectorTest, NoOveruseForRandomFrameIntervalWithReset) {
// TODO(bugs.webrtc.org/8504): When new estimator is relanded,
// behavior is improved in this scenario, and we get AdaptUp events.
overuse_detector_->SetOptions(options_);
EXPECT_CALL(mock_observer_, AdaptDown(_)).Times(0);
// EXPECT_CALL(mock_observer_, AdaptUp(reason_))
// .Times(testing::AtLeast(1));
@ -627,12 +640,14 @@ class OveruseFrameDetectorTest2 : public OveruseFrameDetectorTest {
// UsagePercent() < low_encode_usage_threshold_percent => underuse.
TEST_F(OveruseFrameDetectorTest2, TriggerOveruse) {
// usage > high => overuse
overuse_detector_->SetOptions(options_);
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
TriggerOveruse(options_.high_threshold_consecutive_count);
}
TEST_F(OveruseFrameDetectorTest2, OveruseAndRecover) {
// usage > high => overuse
overuse_detector_->SetOptions(options_);
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
TriggerOveruse(options_.high_threshold_consecutive_count);
// usage < low => underuse
@ -641,6 +656,7 @@ TEST_F(OveruseFrameDetectorTest2, OveruseAndRecover) {
}
TEST_F(OveruseFrameDetectorTest2, DoubleOveruseAndRecover) {
overuse_detector_->SetOptions(options_);
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(2);
TriggerOveruse(options_.high_threshold_consecutive_count);
TriggerOveruse(options_.high_threshold_consecutive_count);
@ -653,8 +669,7 @@ TEST_F(OveruseFrameDetectorTest2, TriggerUnderuseWithMinProcessCount) {
options_.min_process_count = 1;
CpuOveruseObserverImpl overuse_observer;
observer_ = nullptr;
overuse_detector_.reset(new OveruseFrameDetectorUnderTest(
options_, this));
overuse_detector_->SetOptions(options_);
InsertAndSendFramesWithInterval(
1200, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
overuse_detector_->CheckForOveruse(&overuse_observer);
@ -665,6 +680,7 @@ TEST_F(OveruseFrameDetectorTest2, TriggerUnderuseWithMinProcessCount) {
}
TEST_F(OveruseFrameDetectorTest2, ConstantOveruseGivesNoNormalUsage) {
overuse_detector_->SetOptions(options_);
EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(0);
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(64);
for (size_t i = 0; i < 64; ++i) {
@ -675,24 +691,26 @@ TEST_F(OveruseFrameDetectorTest2, ConstantOveruseGivesNoNormalUsage) {
TEST_F(OveruseFrameDetectorTest2, ConsecutiveCountTriggersOveruse) {
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
options_.high_threshold_consecutive_count = 2;
ReinitializeOveruseDetector();
overuse_detector_->SetOptions(options_);
TriggerOveruse(2);
}
TEST_F(OveruseFrameDetectorTest2, IncorrectConsecutiveCountTriggersNoOveruse) {
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(0);
options_.high_threshold_consecutive_count = 2;
ReinitializeOveruseDetector();
overuse_detector_->SetOptions(options_);
TriggerOveruse(1);
}
TEST_F(OveruseFrameDetectorTest2, ProcessingUsage) {
overuse_detector_->SetOptions(options_);
InsertAndSendFramesWithInterval(
1000, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
EXPECT_EQ(kProcessTimeUs * 100 / kFrameIntervalUs, UsagePercent());
}
TEST_F(OveruseFrameDetectorTest2, ResetAfterResolutionChange) {
overuse_detector_->SetOptions(options_);
ForceUpdate(kWidth, kHeight);
EXPECT_EQ(InitialUsage(), UsagePercent());
InsertAndSendFramesWithInterval(
@ -704,6 +722,7 @@ TEST_F(OveruseFrameDetectorTest2, ResetAfterResolutionChange) {
}
TEST_F(OveruseFrameDetectorTest2, ResetAfterFrameTimeout) {
overuse_detector_->SetOptions(options_);
ForceUpdate(kWidth, kHeight);
EXPECT_EQ(InitialUsage(), UsagePercent());
InsertAndSendFramesWithInterval(
@ -722,6 +741,7 @@ TEST_F(OveruseFrameDetectorTest2, ResetAfterFrameTimeout) {
}
TEST_F(OveruseFrameDetectorTest2, ConvergesSlowly) {
overuse_detector_->SetOptions(options_);
InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight,
kProcessTimeUs);
// No update for the first sample.
@ -743,11 +763,13 @@ TEST_F(OveruseFrameDetectorTest2, ConvergesSlowly) {
}
TEST_F(OveruseFrameDetectorTest2, InitialProcessingUsage) {
overuse_detector_->SetOptions(options_);
ForceUpdate(kWidth, kHeight);
EXPECT_EQ(InitialUsage(), UsagePercent());
}
TEST_F(OveruseFrameDetectorTest2, MeasuresMultipleConcurrentSamples) {
overuse_detector_->SetOptions(options_);
EXPECT_CALL(mock_observer_, AdaptDown(reason_))
.Times(testing::AtLeast(1));
static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
@ -771,6 +793,7 @@ TEST_F(OveruseFrameDetectorTest2, MeasuresMultipleConcurrentSamples) {
TEST_F(OveruseFrameDetectorTest2, UpdatesExistingSamples) {
// >85% encoding time should trigger overuse.
overuse_detector_->SetOptions(options_);
EXPECT_CALL(mock_observer_, AdaptDown(reason_))
.Times(testing::AtLeast(1));
static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
@ -801,7 +824,7 @@ TEST_F(OveruseFrameDetectorTest2, RunOnTqNormalUsage) {
rtc::Event event(false, false);
queue.PostTask([this, &event] {
overuse_detector_->StartCheckForOveruse(observer_);
overuse_detector_->StartCheckForOveruse(options_, observer_);
event.Set();
});
event.Wait(rtc::Event::kForever);
@ -829,6 +852,7 @@ TEST_F(OveruseFrameDetectorTest2, RunOnTqNormalUsage) {
// Models screencast, with irregular arrival of frames which are heavy
// to encode.
TEST_F(OveruseFrameDetectorTest2, NoOveruseForLargeRandomFrameInterval) {
overuse_detector_->SetOptions(options_);
EXPECT_CALL(mock_observer_, AdaptDown(_)).Times(0);
EXPECT_CALL(mock_observer_, AdaptUp(reason_))
.Times(testing::AtLeast(1));
@ -849,6 +873,7 @@ TEST_F(OveruseFrameDetectorTest2, NoOveruseForLargeRandomFrameInterval) {
// Models screencast, with irregular arrival of frames, often
// exceeding the timeout interval.
TEST_F(OveruseFrameDetectorTest2, NoOveruseForRandomFrameIntervalWithReset) {
overuse_detector_->SetOptions(options_);
EXPECT_CALL(mock_observer_, AdaptDown(_)).Times(0);
EXPECT_CALL(mock_observer_, AdaptUp(reason_))
.Times(testing::AtLeast(1));

View File

@ -238,24 +238,6 @@ int CalculatePacketRate(uint32_t bitrate_bps, size_t packet_size_bytes) {
packet_size_bits);
}
// 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 GetCpuOveruseOptions(const VideoSendStream::Config& config) {
CpuOveruseOptions options;
if (config.encoder_settings.full_overuse_time) {
options.low_encode_usage_threshold_percent = 150;
options.high_encode_usage_threshold_percent = 200;
}
if (config.encoder_settings.experiment_cpu_load_estimator) {
options.filter_time_ms = 5 * rtc::kNumMillisecsPerSec;
}
return options;
}
size_t CalculateMaxHeaderSize(const VideoSendStream::Config::Rtp& config) {
size_t header_size = kRtpHeaderSize;
size_t extensions_size = 0;
@ -533,8 +515,7 @@ VideoSendStream::VideoSendStream(
num_cpu_cores, &stats_proxy_,
config_.encoder_settings,
config_.pre_encode_callback,
rtc::MakeUnique<OveruseFrameDetector>(
GetCpuOveruseOptions(config_), &stats_proxy_));
rtc::MakeUnique<OveruseFrameDetector>(&stats_proxy_));
// TODO(srte): Initialization should not be done posted on a task queue.
// Note that the posted task must not outlive this scope since the closure
// references local variables.

View File

@ -94,6 +94,25 @@ bool IsFramerateScalingEnabled(
VideoSendStream::DegradationPreference::kBalanced;
}
// 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 GetCpuOveruseOptions(
const VideoSendStream::Config::EncoderSettings& settings) {
CpuOveruseOptions options;
if (settings.full_overuse_time) {
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;
}
} // namespace
class VideoStreamEncoder::EncodeTask : public rtc::QueuedTask {
@ -396,7 +415,8 @@ VideoStreamEncoder::VideoStreamEncoder(
RTC_DCHECK(overuse_detector_);
encoder_queue_.PostTask([this] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
overuse_detector_->StartCheckForOveruse(this);
overuse_detector_->StartCheckForOveruse(GetCpuOveruseOptions(settings_),
this);
video_sender_.RegisterExternalEncoder(
settings_.encoder, settings_.internal_source);
});

View File

@ -67,10 +67,8 @@ class TestBuffer : public webrtc::I420Buffer {
class CpuOveruseDetectorProxy : public OveruseFrameDetector {
public:
CpuOveruseDetectorProxy(const CpuOveruseOptions& options,
CpuOveruseMetricsObserver* metrics_observer)
: OveruseFrameDetector(options,
metrics_observer),
explicit CpuOveruseDetectorProxy(CpuOveruseMetricsObserver* metrics_observer)
: OveruseFrameDetector(metrics_observer),
last_target_framerate_fps_(-1) {}
virtual ~CpuOveruseDetectorProxy() {}
@ -101,7 +99,6 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
nullptr /* pre_encode_callback */,
std::unique_ptr<OveruseFrameDetector>(
overuse_detector_proxy_ = new CpuOveruseDetectorProxy(
CpuOveruseOptions(),
stats_proxy))) {}
void PostTaskAndWait(bool down, AdaptReason reason) {