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:
parent
83d676bd15
commit
d1f7eb6e83
@ -29,8 +29,7 @@ class MockVideoStreamEncoder : public VideoStreamEncoder {
|
|||||||
send_stats_proxy,
|
send_stats_proxy,
|
||||||
VideoSendStream::Config::EncoderSettings(nullptr),
|
VideoSendStream::Config::EncoderSettings(nullptr),
|
||||||
nullptr,
|
nullptr,
|
||||||
rtc::MakeUnique<OveruseFrameDetector>(CpuOveruseOptions(),
|
rtc::MakeUnique<OveruseFrameDetector>(nullptr)) {}
|
||||||
nullptr)) {}
|
|
||||||
~MockVideoStreamEncoder() { Stop(); }
|
~MockVideoStreamEncoder() { Stop(); }
|
||||||
|
|
||||||
MOCK_METHOD0(SendKeyFrame, void());
|
MOCK_METHOD0(SendKeyFrame, void());
|
||||||
|
|||||||
@ -510,10 +510,8 @@ class OveruseFrameDetector::CheckOveruseTask : public rtc::QueuedTask {
|
|||||||
};
|
};
|
||||||
|
|
||||||
OveruseFrameDetector::OveruseFrameDetector(
|
OveruseFrameDetector::OveruseFrameDetector(
|
||||||
const CpuOveruseOptions& options,
|
|
||||||
CpuOveruseMetricsObserver* metrics_observer)
|
CpuOveruseMetricsObserver* metrics_observer)
|
||||||
: check_overuse_task_(nullptr),
|
: check_overuse_task_(nullptr),
|
||||||
options_(options),
|
|
||||||
metrics_observer_(metrics_observer),
|
metrics_observer_(metrics_observer),
|
||||||
num_process_times_(0),
|
num_process_times_(0),
|
||||||
// TODO(nisse): Use rtc::Optional
|
// TODO(nisse): Use rtc::Optional
|
||||||
@ -525,8 +523,7 @@ OveruseFrameDetector::OveruseFrameDetector(
|
|||||||
num_overuse_detections_(0),
|
num_overuse_detections_(0),
|
||||||
last_rampup_time_ms_(-1),
|
last_rampup_time_ms_(-1),
|
||||||
in_quick_rampup_(false),
|
in_quick_rampup_(false),
|
||||||
current_rampup_delay_ms_(kStandardRampUpDelayMs),
|
current_rampup_delay_ms_(kStandardRampUpDelayMs) {
|
||||||
usage_(CreateProcessingUsage(options)) {
|
|
||||||
task_checker_.Detach();
|
task_checker_.Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -535,10 +532,13 @@ OveruseFrameDetector::~OveruseFrameDetector() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OveruseFrameDetector::StartCheckForOveruse(
|
void OveruseFrameDetector::StartCheckForOveruse(
|
||||||
|
const CpuOveruseOptions& options,
|
||||||
AdaptationObserverInterface* overuse_observer) {
|
AdaptationObserverInterface* overuse_observer) {
|
||||||
RTC_DCHECK_CALLED_SEQUENTIALLY(&task_checker_);
|
RTC_DCHECK_CALLED_SEQUENTIALLY(&task_checker_);
|
||||||
RTC_DCHECK(!check_overuse_task_);
|
RTC_DCHECK(!check_overuse_task_);
|
||||||
RTC_DCHECK(overuse_observer != nullptr);
|
RTC_DCHECK(overuse_observer != nullptr);
|
||||||
|
|
||||||
|
SetOptions(options);
|
||||||
check_overuse_task_ = new CheckOveruseTask(this, overuse_observer);
|
check_overuse_task_ = new CheckOveruseTask(this, overuse_observer);
|
||||||
}
|
}
|
||||||
void OveruseFrameDetector::StopCheckForOveruse() {
|
void OveruseFrameDetector::StopCheckForOveruse() {
|
||||||
@ -669,6 +669,14 @@ void OveruseFrameDetector::CheckForOveruse(
|
|||||||
<< " rampup delay " << rampup_delay;
|
<< " 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) {
|
bool OveruseFrameDetector::IsOverusing(const CpuOveruseMetrics& metrics) {
|
||||||
RTC_DCHECK_CALLED_SEQUENTIALLY(&task_checker_);
|
RTC_DCHECK_CALLED_SEQUENTIALLY(&task_checker_);
|
||||||
|
|
||||||
|
|||||||
@ -65,12 +65,12 @@ class CpuOveruseMetricsObserver {
|
|||||||
// check for overuse.
|
// check for overuse.
|
||||||
class OveruseFrameDetector {
|
class OveruseFrameDetector {
|
||||||
public:
|
public:
|
||||||
OveruseFrameDetector(const CpuOveruseOptions& options,
|
explicit OveruseFrameDetector(CpuOveruseMetricsObserver* metrics_observer);
|
||||||
CpuOveruseMetricsObserver* metrics_observer);
|
|
||||||
virtual ~OveruseFrameDetector();
|
virtual ~OveruseFrameDetector();
|
||||||
|
|
||||||
// Start to periodically check for overuse.
|
// 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
|
// StopCheckForOveruse must be called before destruction if
|
||||||
// StartCheckForOveruse has been called.
|
// StartCheckForOveruse has been called.
|
||||||
@ -116,6 +116,7 @@ class OveruseFrameDetector {
|
|||||||
protected:
|
protected:
|
||||||
// Protected for test purposes.
|
// Protected for test purposes.
|
||||||
void CheckForOveruse(AdaptationObserverInterface* overuse_observer);
|
void CheckForOveruse(AdaptationObserverInterface* overuse_observer);
|
||||||
|
void SetOptions(const CpuOveruseOptions& options);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class CheckOveruseTask;
|
class CheckOveruseTask;
|
||||||
@ -136,7 +137,7 @@ class OveruseFrameDetector {
|
|||||||
// Owned by the task queue from where StartCheckForOveruse is called.
|
// Owned by the task queue from where StartCheckForOveruse is called.
|
||||||
CheckOveruseTask* check_overuse_task_;
|
CheckOveruseTask* check_overuse_task_;
|
||||||
|
|
||||||
const CpuOveruseOptions options_;
|
CpuOveruseOptions options_;
|
||||||
|
|
||||||
// Stats metrics.
|
// Stats metrics.
|
||||||
CpuOveruseMetricsObserver* const metrics_observer_;
|
CpuOveruseMetricsObserver* const metrics_observer_;
|
||||||
@ -156,8 +157,7 @@ class OveruseFrameDetector {
|
|||||||
bool in_quick_rampup_ RTC_GUARDED_BY(task_checker_);
|
bool in_quick_rampup_ RTC_GUARDED_BY(task_checker_);
|
||||||
int current_rampup_delay_ms_ RTC_GUARDED_BY(task_checker_);
|
int current_rampup_delay_ms_ RTC_GUARDED_BY(task_checker_);
|
||||||
|
|
||||||
const std::unique_ptr<ProcessingUsage> usage_
|
std::unique_ptr<ProcessingUsage> usage_ RTC_PT_GUARDED_BY(task_checker_);
|
||||||
RTC_PT_GUARDED_BY(task_checker_);
|
|
||||||
|
|
||||||
RTC_DISALLOW_COPY_AND_ASSIGN(OveruseFrameDetector);
|
RTC_DISALLOW_COPY_AND_ASSIGN(OveruseFrameDetector);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -58,13 +58,13 @@ class CpuOveruseObserverImpl : public AdaptationObserverInterface {
|
|||||||
|
|
||||||
class OveruseFrameDetectorUnderTest : public OveruseFrameDetector {
|
class OveruseFrameDetectorUnderTest : public OveruseFrameDetector {
|
||||||
public:
|
public:
|
||||||
OveruseFrameDetectorUnderTest(const CpuOveruseOptions& options,
|
explicit OveruseFrameDetectorUnderTest(
|
||||||
CpuOveruseMetricsObserver* metrics_observer)
|
CpuOveruseMetricsObserver* metrics_observer)
|
||||||
: OveruseFrameDetector(options,
|
: OveruseFrameDetector(metrics_observer) {}
|
||||||
metrics_observer) {}
|
|
||||||
~OveruseFrameDetectorUnderTest() {}
|
~OveruseFrameDetectorUnderTest() {}
|
||||||
|
|
||||||
using OveruseFrameDetector::CheckForOveruse;
|
using OveruseFrameDetector::CheckForOveruse;
|
||||||
|
using OveruseFrameDetector::SetOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OveruseFrameDetectorTest : public ::testing::Test,
|
class OveruseFrameDetectorTest : public ::testing::Test,
|
||||||
@ -73,12 +73,9 @@ class OveruseFrameDetectorTest : public ::testing::Test,
|
|||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
observer_ = &mock_observer_;
|
observer_ = &mock_observer_;
|
||||||
options_.min_process_count = 0;
|
options_.min_process_count = 0;
|
||||||
ReinitializeOveruseDetector();
|
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 ReinitializeOveruseDetector() {
|
|
||||||
overuse_detector_.reset(new OveruseFrameDetectorUnderTest(
|
|
||||||
options_, this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnEncodedFrameTimeMeasured(int encode_time_ms,
|
void OnEncodedFrameTimeMeasured(int encode_time_ms,
|
||||||
@ -199,12 +196,14 @@ class OveruseFrameDetectorTest : public ::testing::Test,
|
|||||||
// UsagePercent() < low_encode_usage_threshold_percent => underuse.
|
// UsagePercent() < low_encode_usage_threshold_percent => underuse.
|
||||||
TEST_F(OveruseFrameDetectorTest, TriggerOveruse) {
|
TEST_F(OveruseFrameDetectorTest, TriggerOveruse) {
|
||||||
// usage > high => overuse
|
// usage > high => overuse
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
|
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
|
||||||
TriggerOveruse(options_.high_threshold_consecutive_count);
|
TriggerOveruse(options_.high_threshold_consecutive_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) {
|
TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) {
|
||||||
// usage > high => overuse
|
// usage > high => overuse
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
|
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
|
||||||
TriggerOveruse(options_.high_threshold_consecutive_count);
|
TriggerOveruse(options_.high_threshold_consecutive_count);
|
||||||
// usage < low => underuse
|
// usage < low => underuse
|
||||||
@ -213,6 +212,7 @@ TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) {
|
TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) {
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(2);
|
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(2);
|
||||||
TriggerOveruse(options_.high_threshold_consecutive_count);
|
TriggerOveruse(options_.high_threshold_consecutive_count);
|
||||||
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;
|
options_.min_process_count = 1;
|
||||||
CpuOveruseObserverImpl overuse_observer;
|
CpuOveruseObserverImpl overuse_observer;
|
||||||
observer_ = nullptr;
|
observer_ = nullptr;
|
||||||
overuse_detector_.reset(new OveruseFrameDetectorUnderTest(
|
overuse_detector_->SetOptions(options_);
|
||||||
options_, this));
|
|
||||||
InsertAndSendFramesWithInterval(
|
InsertAndSendFramesWithInterval(
|
||||||
1200, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
|
1200, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
|
||||||
overuse_detector_->CheckForOveruse(&overuse_observer);
|
overuse_detector_->CheckForOveruse(&overuse_observer);
|
||||||
@ -237,6 +236,7 @@ TEST_F(OveruseFrameDetectorTest, TriggerUnderuseWithMinProcessCount) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) {
|
TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) {
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(0);
|
EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(0);
|
||||||
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(64);
|
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(64);
|
||||||
for (size_t i = 0; i < 64; ++i) {
|
for (size_t i = 0; i < 64; ++i) {
|
||||||
@ -245,26 +245,30 @@ TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest, ConsecutiveCountTriggersOveruse) {
|
TEST_F(OveruseFrameDetectorTest, ConsecutiveCountTriggersOveruse) {
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
|
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
|
||||||
options_.high_threshold_consecutive_count = 2;
|
options_.high_threshold_consecutive_count = 2;
|
||||||
ReinitializeOveruseDetector();
|
overuse_detector_->SetOptions(options_);
|
||||||
TriggerOveruse(2);
|
TriggerOveruse(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest, IncorrectConsecutiveCountTriggersNoOveruse) {
|
TEST_F(OveruseFrameDetectorTest, IncorrectConsecutiveCountTriggersNoOveruse) {
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(0);
|
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(0);
|
||||||
options_.high_threshold_consecutive_count = 2;
|
options_.high_threshold_consecutive_count = 2;
|
||||||
ReinitializeOveruseDetector();
|
overuse_detector_->SetOptions(options_);
|
||||||
TriggerOveruse(1);
|
TriggerOveruse(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest, ProcessingUsage) {
|
TEST_F(OveruseFrameDetectorTest, ProcessingUsage) {
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
InsertAndSendFramesWithInterval(
|
InsertAndSendFramesWithInterval(
|
||||||
1000, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
|
1000, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
|
||||||
EXPECT_EQ(kProcessTimeUs * 100 / kFrameIntervalUs, UsagePercent());
|
EXPECT_EQ(kProcessTimeUs * 100 / kFrameIntervalUs, UsagePercent());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest, ResetAfterResolutionChange) {
|
TEST_F(OveruseFrameDetectorTest, ResetAfterResolutionChange) {
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
ForceUpdate(kWidth, kHeight);
|
ForceUpdate(kWidth, kHeight);
|
||||||
EXPECT_EQ(InitialUsage(), UsagePercent());
|
EXPECT_EQ(InitialUsage(), UsagePercent());
|
||||||
InsertAndSendFramesWithInterval(
|
InsertAndSendFramesWithInterval(
|
||||||
@ -276,6 +280,7 @@ TEST_F(OveruseFrameDetectorTest, ResetAfterResolutionChange) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest, ResetAfterFrameTimeout) {
|
TEST_F(OveruseFrameDetectorTest, ResetAfterFrameTimeout) {
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
ForceUpdate(kWidth, kHeight);
|
ForceUpdate(kWidth, kHeight);
|
||||||
EXPECT_EQ(InitialUsage(), UsagePercent());
|
EXPECT_EQ(InitialUsage(), UsagePercent());
|
||||||
InsertAndSendFramesWithInterval(
|
InsertAndSendFramesWithInterval(
|
||||||
@ -295,7 +300,7 @@ TEST_F(OveruseFrameDetectorTest, ResetAfterFrameTimeout) {
|
|||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest, MinFrameSamplesBeforeUpdating) {
|
TEST_F(OveruseFrameDetectorTest, MinFrameSamplesBeforeUpdating) {
|
||||||
options_.min_frame_samples = 40;
|
options_.min_frame_samples = 40;
|
||||||
ReinitializeOveruseDetector();
|
overuse_detector_->SetOptions(options_);
|
||||||
InsertAndSendFramesWithInterval(
|
InsertAndSendFramesWithInterval(
|
||||||
40, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
|
40, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
|
||||||
EXPECT_EQ(InitialUsage(), UsagePercent());
|
EXPECT_EQ(InitialUsage(), UsagePercent());
|
||||||
@ -314,11 +319,13 @@ TEST_F(OveruseFrameDetectorTest, MinFrameSamplesBeforeUpdating) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest, InitialProcessingUsage) {
|
TEST_F(OveruseFrameDetectorTest, InitialProcessingUsage) {
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
ForceUpdate(kWidth, kHeight);
|
ForceUpdate(kWidth, kHeight);
|
||||||
EXPECT_EQ(InitialUsage(), UsagePercent());
|
EXPECT_EQ(InitialUsage(), UsagePercent());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest, MeasuresMultipleConcurrentSamples) {
|
TEST_F(OveruseFrameDetectorTest, MeasuresMultipleConcurrentSamples) {
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
EXPECT_CALL(mock_observer_, AdaptDown(reason_))
|
EXPECT_CALL(mock_observer_, AdaptDown(reason_))
|
||||||
.Times(testing::AtLeast(1));
|
.Times(testing::AtLeast(1));
|
||||||
static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
|
static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
|
||||||
@ -342,6 +349,7 @@ TEST_F(OveruseFrameDetectorTest, MeasuresMultipleConcurrentSamples) {
|
|||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest, UpdatesExistingSamples) {
|
TEST_F(OveruseFrameDetectorTest, UpdatesExistingSamples) {
|
||||||
// >85% encoding time should trigger overuse.
|
// >85% encoding time should trigger overuse.
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
EXPECT_CALL(mock_observer_, AdaptDown(reason_))
|
EXPECT_CALL(mock_observer_, AdaptDown(reason_))
|
||||||
.Times(testing::AtLeast(1));
|
.Times(testing::AtLeast(1));
|
||||||
static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
|
static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
|
||||||
@ -372,7 +380,7 @@ TEST_F(OveruseFrameDetectorTest, RunOnTqNormalUsage) {
|
|||||||
|
|
||||||
rtc::Event event(false, false);
|
rtc::Event event(false, false);
|
||||||
queue.PostTask([this, &event] {
|
queue.PostTask([this, &event] {
|
||||||
overuse_detector_->StartCheckForOveruse(observer_);
|
overuse_detector_->StartCheckForOveruse(options_, observer_);
|
||||||
event.Set();
|
event.Set();
|
||||||
});
|
});
|
||||||
event.Wait(rtc::Event::kForever);
|
event.Wait(rtc::Event::kForever);
|
||||||
@ -401,6 +409,7 @@ TEST_F(OveruseFrameDetectorTest, MaxIntervalScalesWithFramerate) {
|
|||||||
const int kCapturerMaxFrameRate = 30;
|
const int kCapturerMaxFrameRate = 30;
|
||||||
const int kEncodeMaxFrameRate = 20; // Maximum fps the encoder can sustain.
|
const int kEncodeMaxFrameRate = 20; // Maximum fps the encoder can sustain.
|
||||||
|
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
// Trigger overuse.
|
// Trigger overuse.
|
||||||
int64_t frame_interval_us = rtc::kNumMicrosecsPerSec / kCapturerMaxFrameRate;
|
int64_t frame_interval_us = rtc::kNumMicrosecsPerSec / kCapturerMaxFrameRate;
|
||||||
// Processing time just below over use limit given kEncodeMaxFrameRate.
|
// Processing time just below over use limit given kEncodeMaxFrameRate.
|
||||||
@ -434,6 +443,7 @@ TEST_F(OveruseFrameDetectorTest, MaxIntervalScalesWithFramerate) {
|
|||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest, RespectsMinFramerate) {
|
TEST_F(OveruseFrameDetectorTest, RespectsMinFramerate) {
|
||||||
const int kMinFrameRate = 7; // Minimum fps allowed by current detector impl.
|
const int kMinFrameRate = 7; // Minimum fps allowed by current detector impl.
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
overuse_detector_->OnTargetFramerateUpdated(kMinFrameRate);
|
overuse_detector_->OnTargetFramerateUpdated(kMinFrameRate);
|
||||||
|
|
||||||
// Normal usage just at the limit.
|
// Normal usage just at the limit.
|
||||||
@ -470,6 +480,7 @@ TEST_F(OveruseFrameDetectorTest, RespectsMinFramerate) {
|
|||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest, LimitsMaxFrameInterval) {
|
TEST_F(OveruseFrameDetectorTest, LimitsMaxFrameInterval) {
|
||||||
const int kMaxFrameRate = 20;
|
const int kMaxFrameRate = 20;
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
overuse_detector_->OnTargetFramerateUpdated(kMaxFrameRate);
|
overuse_detector_->OnTargetFramerateUpdated(kMaxFrameRate);
|
||||||
int64_t frame_interval_us = rtc::kNumMicrosecsPerSec / kMaxFrameRate;
|
int64_t frame_interval_us = rtc::kNumMicrosecsPerSec / kMaxFrameRate;
|
||||||
// Maximum frame interval allowed is 35% above ideal.
|
// 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_, AdaptDown(_)).Times(0);
|
||||||
// EXPECT_CALL(mock_observer_, AdaptUp(reason_))
|
// EXPECT_CALL(mock_observer_, AdaptUp(reason_))
|
||||||
// .Times(testing::AtLeast(1));
|
// .Times(testing::AtLeast(1));
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
|
|
||||||
const int kNumFrames = 500;
|
const int kNumFrames = 500;
|
||||||
const int kEncodeTimeUs = 100 * rtc::kNumMicrosecsPerMillisec;
|
const int kEncodeTimeUs = 100 * rtc::kNumMicrosecsPerMillisec;
|
||||||
@ -542,6 +554,7 @@ TEST_F(OveruseFrameDetectorTest, NoOveruseForLargeRandomFrameInterval) {
|
|||||||
TEST_F(OveruseFrameDetectorTest, NoOveruseForRandomFrameIntervalWithReset) {
|
TEST_F(OveruseFrameDetectorTest, NoOveruseForRandomFrameIntervalWithReset) {
|
||||||
// TODO(bugs.webrtc.org/8504): When new estimator is relanded,
|
// TODO(bugs.webrtc.org/8504): When new estimator is relanded,
|
||||||
// behavior is improved in this scenario, and we get AdaptUp events.
|
// 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_, AdaptDown(_)).Times(0);
|
||||||
// EXPECT_CALL(mock_observer_, AdaptUp(reason_))
|
// EXPECT_CALL(mock_observer_, AdaptUp(reason_))
|
||||||
// .Times(testing::AtLeast(1));
|
// .Times(testing::AtLeast(1));
|
||||||
@ -627,12 +640,14 @@ class OveruseFrameDetectorTest2 : public OveruseFrameDetectorTest {
|
|||||||
// UsagePercent() < low_encode_usage_threshold_percent => underuse.
|
// UsagePercent() < low_encode_usage_threshold_percent => underuse.
|
||||||
TEST_F(OveruseFrameDetectorTest2, TriggerOveruse) {
|
TEST_F(OveruseFrameDetectorTest2, TriggerOveruse) {
|
||||||
// usage > high => overuse
|
// usage > high => overuse
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
|
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
|
||||||
TriggerOveruse(options_.high_threshold_consecutive_count);
|
TriggerOveruse(options_.high_threshold_consecutive_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest2, OveruseAndRecover) {
|
TEST_F(OveruseFrameDetectorTest2, OveruseAndRecover) {
|
||||||
// usage > high => overuse
|
// usage > high => overuse
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
|
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
|
||||||
TriggerOveruse(options_.high_threshold_consecutive_count);
|
TriggerOveruse(options_.high_threshold_consecutive_count);
|
||||||
// usage < low => underuse
|
// usage < low => underuse
|
||||||
@ -641,6 +656,7 @@ TEST_F(OveruseFrameDetectorTest2, OveruseAndRecover) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest2, DoubleOveruseAndRecover) {
|
TEST_F(OveruseFrameDetectorTest2, DoubleOveruseAndRecover) {
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(2);
|
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(2);
|
||||||
TriggerOveruse(options_.high_threshold_consecutive_count);
|
TriggerOveruse(options_.high_threshold_consecutive_count);
|
||||||
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;
|
options_.min_process_count = 1;
|
||||||
CpuOveruseObserverImpl overuse_observer;
|
CpuOveruseObserverImpl overuse_observer;
|
||||||
observer_ = nullptr;
|
observer_ = nullptr;
|
||||||
overuse_detector_.reset(new OveruseFrameDetectorUnderTest(
|
overuse_detector_->SetOptions(options_);
|
||||||
options_, this));
|
|
||||||
InsertAndSendFramesWithInterval(
|
InsertAndSendFramesWithInterval(
|
||||||
1200, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
|
1200, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
|
||||||
overuse_detector_->CheckForOveruse(&overuse_observer);
|
overuse_detector_->CheckForOveruse(&overuse_observer);
|
||||||
@ -665,6 +680,7 @@ TEST_F(OveruseFrameDetectorTest2, TriggerUnderuseWithMinProcessCount) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest2, ConstantOveruseGivesNoNormalUsage) {
|
TEST_F(OveruseFrameDetectorTest2, ConstantOveruseGivesNoNormalUsage) {
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(0);
|
EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(0);
|
||||||
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(64);
|
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(64);
|
||||||
for (size_t i = 0; i < 64; ++i) {
|
for (size_t i = 0; i < 64; ++i) {
|
||||||
@ -675,24 +691,26 @@ TEST_F(OveruseFrameDetectorTest2, ConstantOveruseGivesNoNormalUsage) {
|
|||||||
TEST_F(OveruseFrameDetectorTest2, ConsecutiveCountTriggersOveruse) {
|
TEST_F(OveruseFrameDetectorTest2, ConsecutiveCountTriggersOveruse) {
|
||||||
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
|
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
|
||||||
options_.high_threshold_consecutive_count = 2;
|
options_.high_threshold_consecutive_count = 2;
|
||||||
ReinitializeOveruseDetector();
|
overuse_detector_->SetOptions(options_);
|
||||||
TriggerOveruse(2);
|
TriggerOveruse(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest2, IncorrectConsecutiveCountTriggersNoOveruse) {
|
TEST_F(OveruseFrameDetectorTest2, IncorrectConsecutiveCountTriggersNoOveruse) {
|
||||||
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(0);
|
EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(0);
|
||||||
options_.high_threshold_consecutive_count = 2;
|
options_.high_threshold_consecutive_count = 2;
|
||||||
ReinitializeOveruseDetector();
|
overuse_detector_->SetOptions(options_);
|
||||||
TriggerOveruse(1);
|
TriggerOveruse(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest2, ProcessingUsage) {
|
TEST_F(OveruseFrameDetectorTest2, ProcessingUsage) {
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
InsertAndSendFramesWithInterval(
|
InsertAndSendFramesWithInterval(
|
||||||
1000, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
|
1000, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
|
||||||
EXPECT_EQ(kProcessTimeUs * 100 / kFrameIntervalUs, UsagePercent());
|
EXPECT_EQ(kProcessTimeUs * 100 / kFrameIntervalUs, UsagePercent());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest2, ResetAfterResolutionChange) {
|
TEST_F(OveruseFrameDetectorTest2, ResetAfterResolutionChange) {
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
ForceUpdate(kWidth, kHeight);
|
ForceUpdate(kWidth, kHeight);
|
||||||
EXPECT_EQ(InitialUsage(), UsagePercent());
|
EXPECT_EQ(InitialUsage(), UsagePercent());
|
||||||
InsertAndSendFramesWithInterval(
|
InsertAndSendFramesWithInterval(
|
||||||
@ -704,6 +722,7 @@ TEST_F(OveruseFrameDetectorTest2, ResetAfterResolutionChange) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest2, ResetAfterFrameTimeout) {
|
TEST_F(OveruseFrameDetectorTest2, ResetAfterFrameTimeout) {
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
ForceUpdate(kWidth, kHeight);
|
ForceUpdate(kWidth, kHeight);
|
||||||
EXPECT_EQ(InitialUsage(), UsagePercent());
|
EXPECT_EQ(InitialUsage(), UsagePercent());
|
||||||
InsertAndSendFramesWithInterval(
|
InsertAndSendFramesWithInterval(
|
||||||
@ -722,6 +741,7 @@ TEST_F(OveruseFrameDetectorTest2, ResetAfterFrameTimeout) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest2, ConvergesSlowly) {
|
TEST_F(OveruseFrameDetectorTest2, ConvergesSlowly) {
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight,
|
InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight,
|
||||||
kProcessTimeUs);
|
kProcessTimeUs);
|
||||||
// No update for the first sample.
|
// No update for the first sample.
|
||||||
@ -743,11 +763,13 @@ TEST_F(OveruseFrameDetectorTest2, ConvergesSlowly) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest2, InitialProcessingUsage) {
|
TEST_F(OveruseFrameDetectorTest2, InitialProcessingUsage) {
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
ForceUpdate(kWidth, kHeight);
|
ForceUpdate(kWidth, kHeight);
|
||||||
EXPECT_EQ(InitialUsage(), UsagePercent());
|
EXPECT_EQ(InitialUsage(), UsagePercent());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest2, MeasuresMultipleConcurrentSamples) {
|
TEST_F(OveruseFrameDetectorTest2, MeasuresMultipleConcurrentSamples) {
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
EXPECT_CALL(mock_observer_, AdaptDown(reason_))
|
EXPECT_CALL(mock_observer_, AdaptDown(reason_))
|
||||||
.Times(testing::AtLeast(1));
|
.Times(testing::AtLeast(1));
|
||||||
static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
|
static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
|
||||||
@ -771,6 +793,7 @@ TEST_F(OveruseFrameDetectorTest2, MeasuresMultipleConcurrentSamples) {
|
|||||||
|
|
||||||
TEST_F(OveruseFrameDetectorTest2, UpdatesExistingSamples) {
|
TEST_F(OveruseFrameDetectorTest2, UpdatesExistingSamples) {
|
||||||
// >85% encoding time should trigger overuse.
|
// >85% encoding time should trigger overuse.
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
EXPECT_CALL(mock_observer_, AdaptDown(reason_))
|
EXPECT_CALL(mock_observer_, AdaptDown(reason_))
|
||||||
.Times(testing::AtLeast(1));
|
.Times(testing::AtLeast(1));
|
||||||
static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
|
static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
|
||||||
@ -801,7 +824,7 @@ TEST_F(OveruseFrameDetectorTest2, RunOnTqNormalUsage) {
|
|||||||
|
|
||||||
rtc::Event event(false, false);
|
rtc::Event event(false, false);
|
||||||
queue.PostTask([this, &event] {
|
queue.PostTask([this, &event] {
|
||||||
overuse_detector_->StartCheckForOveruse(observer_);
|
overuse_detector_->StartCheckForOveruse(options_, observer_);
|
||||||
event.Set();
|
event.Set();
|
||||||
});
|
});
|
||||||
event.Wait(rtc::Event::kForever);
|
event.Wait(rtc::Event::kForever);
|
||||||
@ -829,6 +852,7 @@ TEST_F(OveruseFrameDetectorTest2, RunOnTqNormalUsage) {
|
|||||||
// Models screencast, with irregular arrival of frames which are heavy
|
// Models screencast, with irregular arrival of frames which are heavy
|
||||||
// to encode.
|
// to encode.
|
||||||
TEST_F(OveruseFrameDetectorTest2, NoOveruseForLargeRandomFrameInterval) {
|
TEST_F(OveruseFrameDetectorTest2, NoOveruseForLargeRandomFrameInterval) {
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
EXPECT_CALL(mock_observer_, AdaptDown(_)).Times(0);
|
EXPECT_CALL(mock_observer_, AdaptDown(_)).Times(0);
|
||||||
EXPECT_CALL(mock_observer_, AdaptUp(reason_))
|
EXPECT_CALL(mock_observer_, AdaptUp(reason_))
|
||||||
.Times(testing::AtLeast(1));
|
.Times(testing::AtLeast(1));
|
||||||
@ -849,6 +873,7 @@ TEST_F(OveruseFrameDetectorTest2, NoOveruseForLargeRandomFrameInterval) {
|
|||||||
// Models screencast, with irregular arrival of frames, often
|
// Models screencast, with irregular arrival of frames, often
|
||||||
// exceeding the timeout interval.
|
// exceeding the timeout interval.
|
||||||
TEST_F(OveruseFrameDetectorTest2, NoOveruseForRandomFrameIntervalWithReset) {
|
TEST_F(OveruseFrameDetectorTest2, NoOveruseForRandomFrameIntervalWithReset) {
|
||||||
|
overuse_detector_->SetOptions(options_);
|
||||||
EXPECT_CALL(mock_observer_, AdaptDown(_)).Times(0);
|
EXPECT_CALL(mock_observer_, AdaptDown(_)).Times(0);
|
||||||
EXPECT_CALL(mock_observer_, AdaptUp(reason_))
|
EXPECT_CALL(mock_observer_, AdaptUp(reason_))
|
||||||
.Times(testing::AtLeast(1));
|
.Times(testing::AtLeast(1));
|
||||||
|
|||||||
@ -238,24 +238,6 @@ int CalculatePacketRate(uint32_t bitrate_bps, size_t packet_size_bytes) {
|
|||||||
packet_size_bits);
|
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 CalculateMaxHeaderSize(const VideoSendStream::Config::Rtp& config) {
|
||||||
size_t header_size = kRtpHeaderSize;
|
size_t header_size = kRtpHeaderSize;
|
||||||
size_t extensions_size = 0;
|
size_t extensions_size = 0;
|
||||||
@ -533,8 +515,7 @@ VideoSendStream::VideoSendStream(
|
|||||||
num_cpu_cores, &stats_proxy_,
|
num_cpu_cores, &stats_proxy_,
|
||||||
config_.encoder_settings,
|
config_.encoder_settings,
|
||||||
config_.pre_encode_callback,
|
config_.pre_encode_callback,
|
||||||
rtc::MakeUnique<OveruseFrameDetector>(
|
rtc::MakeUnique<OveruseFrameDetector>(&stats_proxy_));
|
||||||
GetCpuOveruseOptions(config_), &stats_proxy_));
|
|
||||||
// TODO(srte): Initialization should not be done posted on a task queue.
|
// 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
|
// Note that the posted task must not outlive this scope since the closure
|
||||||
// references local variables.
|
// references local variables.
|
||||||
|
|||||||
@ -94,6 +94,25 @@ bool IsFramerateScalingEnabled(
|
|||||||
VideoSendStream::DegradationPreference::kBalanced;
|
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
|
} // namespace
|
||||||
|
|
||||||
class VideoStreamEncoder::EncodeTask : public rtc::QueuedTask {
|
class VideoStreamEncoder::EncodeTask : public rtc::QueuedTask {
|
||||||
@ -396,7 +415,8 @@ VideoStreamEncoder::VideoStreamEncoder(
|
|||||||
RTC_DCHECK(overuse_detector_);
|
RTC_DCHECK(overuse_detector_);
|
||||||
encoder_queue_.PostTask([this] {
|
encoder_queue_.PostTask([this] {
|
||||||
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
RTC_DCHECK_RUN_ON(&encoder_queue_);
|
||||||
overuse_detector_->StartCheckForOveruse(this);
|
overuse_detector_->StartCheckForOveruse(GetCpuOveruseOptions(settings_),
|
||||||
|
this);
|
||||||
video_sender_.RegisterExternalEncoder(
|
video_sender_.RegisterExternalEncoder(
|
||||||
settings_.encoder, settings_.internal_source);
|
settings_.encoder, settings_.internal_source);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -67,10 +67,8 @@ class TestBuffer : public webrtc::I420Buffer {
|
|||||||
|
|
||||||
class CpuOveruseDetectorProxy : public OveruseFrameDetector {
|
class CpuOveruseDetectorProxy : public OveruseFrameDetector {
|
||||||
public:
|
public:
|
||||||
CpuOveruseDetectorProxy(const CpuOveruseOptions& options,
|
explicit CpuOveruseDetectorProxy(CpuOveruseMetricsObserver* metrics_observer)
|
||||||
CpuOveruseMetricsObserver* metrics_observer)
|
: OveruseFrameDetector(metrics_observer),
|
||||||
: OveruseFrameDetector(options,
|
|
||||||
metrics_observer),
|
|
||||||
last_target_framerate_fps_(-1) {}
|
last_target_framerate_fps_(-1) {}
|
||||||
virtual ~CpuOveruseDetectorProxy() {}
|
virtual ~CpuOveruseDetectorProxy() {}
|
||||||
|
|
||||||
@ -101,7 +99,6 @@ class VideoStreamEncoderUnderTest : public VideoStreamEncoder {
|
|||||||
nullptr /* pre_encode_callback */,
|
nullptr /* pre_encode_callback */,
|
||||||
std::unique_ptr<OveruseFrameDetector>(
|
std::unique_ptr<OveruseFrameDetector>(
|
||||||
overuse_detector_proxy_ = new CpuOveruseDetectorProxy(
|
overuse_detector_proxy_ = new CpuOveruseDetectorProxy(
|
||||||
CpuOveruseOptions(),
|
|
||||||
stats_proxy))) {}
|
stats_proxy))) {}
|
||||||
|
|
||||||
void PostTaskAndWait(bool down, AdaptReason reason) {
|
void PostTaskAndWait(bool down, AdaptReason reason) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user