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:
@ -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());
|
||||
|
@ -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_);
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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));
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
});
|
||||
|
@ -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) {
|
||||
|
Reference in New Issue
Block a user