Move creation of OveruseFrameDetector to VideoSendStream.
Intended to make it easier to wire up cpu-adaptation experiments.
To setup the circular references between OveruseFrameDetector and
VideoStreamEncoder, let the AdaptationObserverInterface pointer be
an argument to StartCheckForOveruse.
Bug: webrtc:8504
Change-Id: Ifcf7655ec65e637819d77f507552cb22a6aa5f0f
Reviewed-on: https://webrtc-review.googlesource.com/33340
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22006}
diff --git a/video/encoder_rtcp_feedback_unittest.cc b/video/encoder_rtcp_feedback_unittest.cc
index 8acbec4..cf9d62e 100644
--- a/video/encoder_rtcp_feedback_unittest.cc
+++ b/video/encoder_rtcp_feedback_unittest.cc
@@ -29,7 +29,8 @@
VideoSendStream::Config::EncoderSettings("fake", 0,
nullptr),
nullptr,
- std::unique_ptr<OveruseFrameDetector>()) {}
+ rtc::MakeUnique<OveruseFrameDetector>(
+ CpuOveruseOptions(), nullptr)) {}
~MockVideoStreamEncoder() { Stop(); }
MOCK_METHOD1(OnReceivedIntraFrameRequest, void(size_t));
diff --git a/video/overuse_frame_detector.cc b/video/overuse_frame_detector.cc
index 35828fc..80d7025 100644
--- a/video/overuse_frame_detector.cc
+++ b/video/overuse_frame_detector.cc
@@ -478,8 +478,9 @@
class OveruseFrameDetector::CheckOveruseTask : public rtc::QueuedTask {
public:
- explicit CheckOveruseTask(OveruseFrameDetector* overuse_detector)
- : overuse_detector_(overuse_detector) {
+ CheckOveruseTask(OveruseFrameDetector* overuse_detector,
+ AdaptationObserverInterface* observer)
+ : overuse_detector_(overuse_detector), observer_(observer) {
rtc::TaskQueue::Current()->PostDelayedTask(
std::unique_ptr<rtc::QueuedTask>(this), kTimeToFirstCheckForOveruseMs);
}
@@ -494,7 +495,7 @@
RTC_CHECK(task_checker_.CalledSequentially());
if (!overuse_detector_)
return true; // This will make the task queue delete this task.
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(observer_);
rtc::TaskQueue::Current()->PostDelayedTask(
std::unique_ptr<rtc::QueuedTask>(this), kCheckForOveruseIntervalMs);
@@ -504,15 +505,15 @@
}
rtc::SequencedTaskChecker task_checker_;
OveruseFrameDetector* overuse_detector_;
+ // Observer getting overuse reports.
+ AdaptationObserverInterface* observer_;
};
OveruseFrameDetector::OveruseFrameDetector(
const CpuOveruseOptions& options,
- AdaptationObserverInterface* observer,
CpuOveruseMetricsObserver* metrics_observer)
: check_overuse_task_(nullptr),
options_(options),
- observer_(observer),
metrics_observer_(metrics_observer),
num_process_times_(0),
// TODO(nisse): Use rtc::Optional
@@ -533,10 +534,12 @@
RTC_DCHECK(!check_overuse_task_) << "StopCheckForOverUse must be called.";
}
-void OveruseFrameDetector::StartCheckForOveruse() {
+void OveruseFrameDetector::StartCheckForOveruse(
+ AdaptationObserverInterface* overuse_observer) {
RTC_DCHECK_CALLED_SEQUENTIALLY(&task_checker_);
RTC_DCHECK(!check_overuse_task_);
- check_overuse_task_ = new CheckOveruseTask(this);
+ RTC_DCHECK(overuse_observer != nullptr);
+ check_overuse_task_ = new CheckOveruseTask(this, overuse_observer);
}
void OveruseFrameDetector::StopCheckForOveruse() {
RTC_DCHECK_CALLED_SEQUENTIALLY(&task_checker_);
@@ -616,8 +619,10 @@
}
}
-void OveruseFrameDetector::CheckForOveruse() {
+void OveruseFrameDetector::CheckForOveruse(
+ AdaptationObserverInterface* observer) {
RTC_DCHECK_CALLED_SEQUENTIALLY(&task_checker_);
+ RTC_DCHECK(observer);
++num_process_times_;
if (num_process_times_ <= options_.min_process_count || !metrics_)
return;
@@ -647,14 +652,12 @@
checks_above_threshold_ = 0;
++num_overuse_detections_;
- if (observer_)
- observer_->AdaptDown(kScaleReasonCpu);
+ observer->AdaptDown(kScaleReasonCpu);
} else if (IsUnderusing(*metrics_, now_ms)) {
last_rampup_time_ms_ = now_ms;
in_quick_rampup_ = true;
- if (observer_)
- observer_->AdaptUp(kScaleReasonCpu);
+ observer->AdaptUp(kScaleReasonCpu);
}
int rampup_delay =
diff --git a/video/overuse_frame_detector.h b/video/overuse_frame_detector.h
index f7ebdb2..81ba546 100644
--- a/video/overuse_frame_detector.h
+++ b/video/overuse_frame_detector.h
@@ -66,12 +66,11 @@
class OveruseFrameDetector {
public:
OveruseFrameDetector(const CpuOveruseOptions& options,
- AdaptationObserverInterface* overuse_observer,
CpuOveruseMetricsObserver* metrics_observer);
virtual ~OveruseFrameDetector();
// Start to periodically check for overuse.
- void StartCheckForOveruse();
+ void StartCheckForOveruse(AdaptationObserverInterface* overuse_observer);
// StopCheckForOveruse must be called before destruction if
// StartCheckForOveruse has been called.
@@ -115,7 +114,8 @@
};
protected:
- void CheckForOveruse(); // Protected for test purposes.
+ // Protected for test purposes.
+ void CheckForOveruse(AdaptationObserverInterface* overuse_observer);
private:
class CheckOveruseTask;
@@ -138,9 +138,6 @@
const CpuOveruseOptions options_;
- // Observer getting overuse reports.
- AdaptationObserverInterface* const observer_;
-
// Stats metrics.
CpuOveruseMetricsObserver* const metrics_observer_;
rtc::Optional<CpuOveruseMetrics> metrics_ RTC_GUARDED_BY(task_checker_);
diff --git a/video/overuse_frame_detector_unittest.cc b/video/overuse_frame_detector_unittest.cc
index cefc91c..7bb537a 100644
--- a/video/overuse_frame_detector_unittest.cc
+++ b/video/overuse_frame_detector_unittest.cc
@@ -59,10 +59,8 @@
class OveruseFrameDetectorUnderTest : public OveruseFrameDetector {
public:
OveruseFrameDetectorUnderTest(const CpuOveruseOptions& options,
- AdaptationObserverInterface* overuse_observer,
CpuOveruseMetricsObserver* metrics_observer)
: OveruseFrameDetector(options,
- overuse_observer,
metrics_observer) {}
~OveruseFrameDetectorUnderTest() {}
@@ -73,14 +71,14 @@
public CpuOveruseMetricsObserver {
protected:
void SetUp() override {
- observer_.reset(new MockCpuOveruseObserver());
+ observer_ = &mock_observer_;
options_.min_process_count = 0;
ReinitializeOveruseDetector();
}
void ReinitializeOveruseDetector() {
overuse_detector_.reset(new OveruseFrameDetectorUnderTest(
- options_, observer_.get(), this));
+ options_, this));
}
void OnEncodedFrameTimeMeasured(int encode_time_ms,
@@ -134,7 +132,7 @@
capture_time_us,
rtc::Optional<int>(delay_us));
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(observer_);
// Avoid turning clock backwards.
if (interval_us > delay_us)
clock_.AdvanceTimeMicros(interval_us - delay_us);
@@ -156,7 +154,7 @@
for (int i = 0; i < num_times; ++i) {
InsertAndSendFramesWithInterval(
1000, kFrameIntervalUs, kWidth, kHeight, kDelayUs);
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(observer_);
}
}
@@ -167,7 +165,7 @@
1300, kFrameIntervalUs, kWidth, kHeight, kDelayUs1);
InsertAndSendFramesWithInterval(
1, kFrameIntervalUs, kWidth, kHeight, kDelayUs2);
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(observer_);
}
int UsagePercent() { return metrics_.encode_usage_percent; }
@@ -188,7 +186,8 @@
CpuOveruseOptions options_;
rtc::ScopedFakeClock clock_;
- std::unique_ptr<MockCpuOveruseObserver> observer_;
+ MockCpuOveruseObserver mock_observer_;
+ AdaptationObserverInterface* observer_;
std::unique_ptr<OveruseFrameDetectorUnderTest> overuse_detector_;
CpuOveruseMetrics metrics_;
@@ -200,33 +199,24 @@
// UsagePercent() < low_encode_usage_threshold_percent => underuse.
TEST_F(OveruseFrameDetectorTest, TriggerOveruse) {
// usage > high => overuse
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
TriggerOveruse(options_.high_threshold_consecutive_count);
}
TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) {
// usage > high => overuse
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
TriggerOveruse(options_.high_threshold_consecutive_count);
// usage < low => underuse
- EXPECT_CALL(*(observer_.get()), AdaptUp(reason_)).Times(testing::AtLeast(1));
- TriggerUnderuse();
-}
-
-TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithNoObserver) {
- overuse_detector_.reset(new OveruseFrameDetectorUnderTest(
- options_, nullptr, this));
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(0);
- TriggerOveruse(options_.high_threshold_consecutive_count);
- EXPECT_CALL(*(observer_.get()), AdaptUp(reason_)).Times(0);
+ EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(testing::AtLeast(1));
TriggerUnderuse();
}
TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) {
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(2);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(2);
TriggerOveruse(options_.high_threshold_consecutive_count);
TriggerOveruse(options_.high_threshold_consecutive_count);
- EXPECT_CALL(*(observer_.get()), AdaptUp(reason_)).Times(testing::AtLeast(1));
+ EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(testing::AtLeast(1));
TriggerUnderuse();
}
@@ -234,34 +224,35 @@
const int kProcessIntervalUs = 5 * rtc::kNumMicrosecsPerSec;
options_.min_process_count = 1;
CpuOveruseObserverImpl overuse_observer;
+ observer_ = nullptr;
overuse_detector_.reset(new OveruseFrameDetectorUnderTest(
- options_, &overuse_observer, this));
+ options_, this));
InsertAndSendFramesWithInterval(
1200, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(&overuse_observer);
EXPECT_EQ(0, overuse_observer.normaluse_);
clock_.AdvanceTimeMicros(kProcessIntervalUs);
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(&overuse_observer);
EXPECT_EQ(1, overuse_observer.normaluse_);
}
TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) {
- EXPECT_CALL(*(observer_.get()), AdaptUp(reason_)).Times(0);
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(64);
+ EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(0);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(64);
for (size_t i = 0; i < 64; ++i) {
TriggerOveruse(options_.high_threshold_consecutive_count);
}
}
TEST_F(OveruseFrameDetectorTest, ConsecutiveCountTriggersOveruse) {
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
options_.high_threshold_consecutive_count = 2;
ReinitializeOveruseDetector();
TriggerOveruse(2);
}
TEST_F(OveruseFrameDetectorTest, IncorrectConsecutiveCountTriggersNoOveruse) {
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(0);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(0);
options_.high_threshold_consecutive_count = 2;
ReinitializeOveruseDetector();
TriggerOveruse(1);
@@ -328,7 +319,7 @@
}
TEST_F(OveruseFrameDetectorTest, MeasuresMultipleConcurrentSamples) {
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_))
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_))
.Times(testing::AtLeast(1));
static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
static const size_t kNumFramesEncodingDelay = 3;
@@ -345,13 +336,13 @@
static_cast<uint32_t>(i - kNumFramesEncodingDelay), rtc::TimeMicros(),
capture_time_us, kIntervalUs);
}
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(observer_);
}
}
TEST_F(OveruseFrameDetectorTest, UpdatesExistingSamples) {
// >85% encoding time should trigger overuse.
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_))
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_))
.Times(testing::AtLeast(1));
static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
static const int kDelayUs = 30 * rtc::kNumMicrosecsPerMillisec;
@@ -372,7 +363,7 @@
kDelayUs);
clock_.AdvanceTimeMicros(kIntervalUs - kDelayUs);
timestamp += kIntervalUs * 90 / 1000;
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(observer_);
}
}
@@ -381,14 +372,14 @@
rtc::Event event(false, false);
queue.PostTask([this, &event] {
- overuse_detector_->StartCheckForOveruse();
+ overuse_detector_->StartCheckForOveruse(observer_);
event.Set();
});
event.Wait(rtc::Event::kForever);
// Expect NormalUsage(). When called, stop the |overuse_detector_| and then
// set |event| to end the test.
- EXPECT_CALL(*(observer_.get()), AdaptUp(reason_))
+ EXPECT_CALL(mock_observer_, AdaptUp(reason_))
.WillOnce(InvokeWithoutArgs([this, &event] {
overuse_detector_->StopCheckForOveruse();
event.Set();
@@ -415,30 +406,30 @@
// Processing time just below over use limit given kEncodeMaxFrameRate.
int64_t processing_time_us =
(98 * OveruseProcessingTimeLimitForFramerate(kEncodeMaxFrameRate)) / 100;
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
processing_time_us);
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(observer_);
}
// Simulate frame rate reduction and normal usage.
frame_interval_us = rtc::kNumMicrosecsPerSec / kEncodeMaxFrameRate;
overuse_detector_->OnTargetFramerateUpdated(kEncodeMaxFrameRate);
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(0);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(0);
for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
processing_time_us);
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(observer_);
}
// Reduce processing time to trigger underuse.
processing_time_us =
(98 * UnderuseProcessingTimeLimitForFramerate(kEncodeMaxFrameRate)) / 100;
- EXPECT_CALL(*(observer_.get()), AdaptUp(reason_)).Times(1);
+ EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(1);
InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
processing_time_us);
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(observer_);
}
TEST_F(OveruseFrameDetectorTest, RespectsMinFramerate) {
@@ -450,30 +441,30 @@
// Processing time just below over use limit given kEncodeMaxFrameRate.
int64_t processing_time_us =
(98 * OveruseProcessingTimeLimitForFramerate(kMinFrameRate)) / 100;
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(0);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(0);
for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
processing_time_us);
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(observer_);
}
// Over the limit to overuse.
processing_time_us =
(102 * OveruseProcessingTimeLimitForFramerate(kMinFrameRate)) / 100;
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
processing_time_us);
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(observer_);
}
// Reduce input frame rate. Should still trigger overuse.
overuse_detector_->OnTargetFramerateUpdated(kMinFrameRate - 1);
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
processing_time_us);
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(observer_);
}
}
@@ -491,29 +482,29 @@
// Processing time just below overuse limit given kMaxFrameRate.
int64_t processing_time_us = (98 * max_processing_time_us) / 100;
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(0);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(0);
for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
InsertAndSendFramesWithInterval(1200, max_frame_interval_us, kWidth,
kHeight, processing_time_us);
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(observer_);
}
// Go above limit, trigger overuse.
processing_time_us = (102 * max_processing_time_us) / 100;
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
InsertAndSendFramesWithInterval(1200, max_frame_interval_us, kWidth,
kHeight, processing_time_us);
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(observer_);
}
// Increase frame interval, should still trigger overuse.
max_frame_interval_us *= 2;
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
InsertAndSendFramesWithInterval(1200, max_frame_interval_us, kWidth,
kHeight, processing_time_us);
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(observer_);
}
}
@@ -524,8 +515,8 @@
// behavior is improved in this scenario, with only AdaptUp events,
// and estimated load closer to the true average.
- // EXPECT_CALL(*(observer_.get()), AdaptDown(_)).Times(0);
- // EXPECT_CALL(*(observer_.get()), AdaptUp(reason_))
+ // EXPECT_CALL(mock_observer_, AdaptDown(_)).Times(0);
+ // EXPECT_CALL(mock_observer_, AdaptUp(reason_))
// .Times(testing::AtLeast(1));
const int kNumFrames = 500;
@@ -551,8 +542,8 @@
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.
- EXPECT_CALL(*(observer_.get()), AdaptDown(_)).Times(0);
- // EXPECT_CALL(*(observer_.get()), AdaptUp(reason_))
+ EXPECT_CALL(mock_observer_, AdaptDown(_)).Times(0);
+ // EXPECT_CALL(mock_observer_, AdaptUp(reason_))
// .Times(testing::AtLeast(1));
const int kNumFrames = 500;
@@ -619,7 +610,7 @@
0 /* ignored send_time_us */,
capture_time_us, delay_us);
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(observer_);
clock_.AdvanceTimeMicros(interval_us);
}
}
@@ -636,33 +627,24 @@
// UsagePercent() < low_encode_usage_threshold_percent => underuse.
TEST_F(OveruseFrameDetectorTest2, TriggerOveruse) {
// usage > high => overuse
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
TriggerOveruse(options_.high_threshold_consecutive_count);
}
TEST_F(OveruseFrameDetectorTest2, OveruseAndRecover) {
// usage > high => overuse
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
TriggerOveruse(options_.high_threshold_consecutive_count);
// usage < low => underuse
- EXPECT_CALL(*(observer_.get()), AdaptUp(reason_)).Times(testing::AtLeast(1));
- TriggerUnderuse();
-}
-
-TEST_F(OveruseFrameDetectorTest2, OveruseAndRecoverWithNoObserver) {
- overuse_detector_.reset(new OveruseFrameDetectorUnderTest(
- options_, nullptr, this));
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(0);
- TriggerOveruse(options_.high_threshold_consecutive_count);
- EXPECT_CALL(*(observer_.get()), AdaptUp(reason_)).Times(0);
+ EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(testing::AtLeast(1));
TriggerUnderuse();
}
TEST_F(OveruseFrameDetectorTest2, DoubleOveruseAndRecover) {
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(2);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(2);
TriggerOveruse(options_.high_threshold_consecutive_count);
TriggerOveruse(options_.high_threshold_consecutive_count);
- EXPECT_CALL(*(observer_.get()), AdaptUp(reason_)).Times(testing::AtLeast(1));
+ EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(testing::AtLeast(1));
TriggerUnderuse();
}
@@ -670,34 +652,35 @@
const int kProcessIntervalUs = 5 * rtc::kNumMicrosecsPerSec;
options_.min_process_count = 1;
CpuOveruseObserverImpl overuse_observer;
+ observer_ = nullptr;
overuse_detector_.reset(new OveruseFrameDetectorUnderTest(
- options_, &overuse_observer, this));
+ options_, this));
InsertAndSendFramesWithInterval(
1200, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(&overuse_observer);
EXPECT_EQ(0, overuse_observer.normaluse_);
clock_.AdvanceTimeMicros(kProcessIntervalUs);
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(&overuse_observer);
EXPECT_EQ(1, overuse_observer.normaluse_);
}
TEST_F(OveruseFrameDetectorTest2, ConstantOveruseGivesNoNormalUsage) {
- EXPECT_CALL(*(observer_.get()), AdaptUp(reason_)).Times(0);
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(64);
+ EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(0);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(64);
for (size_t i = 0; i < 64; ++i) {
TriggerOveruse(options_.high_threshold_consecutive_count);
}
}
TEST_F(OveruseFrameDetectorTest2, ConsecutiveCountTriggersOveruse) {
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
options_.high_threshold_consecutive_count = 2;
ReinitializeOveruseDetector();
TriggerOveruse(2);
}
TEST_F(OveruseFrameDetectorTest2, IncorrectConsecutiveCountTriggersNoOveruse) {
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(0);
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(0);
options_.high_threshold_consecutive_count = 2;
ReinitializeOveruseDetector();
TriggerOveruse(1);
@@ -765,7 +748,7 @@
}
TEST_F(OveruseFrameDetectorTest2, MeasuresMultipleConcurrentSamples) {
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_))
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_))
.Times(testing::AtLeast(1));
static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
static const size_t kNumFramesEncodingDelay = 3;
@@ -782,13 +765,13 @@
static_cast<uint32_t>(i - kNumFramesEncodingDelay), rtc::TimeMicros(),
capture_time_us, kIntervalUs);
}
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(observer_);
}
}
TEST_F(OveruseFrameDetectorTest2, UpdatesExistingSamples) {
// >85% encoding time should trigger overuse.
- EXPECT_CALL(*(observer_.get()), AdaptDown(reason_))
+ EXPECT_CALL(mock_observer_, AdaptDown(reason_))
.Times(testing::AtLeast(1));
static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
static const int kDelayUs = 30 * rtc::kNumMicrosecsPerMillisec;
@@ -809,7 +792,7 @@
kDelayUs);
clock_.AdvanceTimeMicros(kIntervalUs - kDelayUs);
timestamp += kIntervalUs * 90 / 1000;
- overuse_detector_->CheckForOveruse();
+ overuse_detector_->CheckForOveruse(observer_);
}
}
@@ -818,14 +801,14 @@
rtc::Event event(false, false);
queue.PostTask([this, &event] {
- overuse_detector_->StartCheckForOveruse();
+ overuse_detector_->StartCheckForOveruse(observer_);
event.Set();
});
event.Wait(rtc::Event::kForever);
// Expect NormalUsage(). When called, stop the |overuse_detector_| and then
// set |event| to end the test.
- EXPECT_CALL(*(observer_.get()), AdaptUp(reason_))
+ EXPECT_CALL(mock_observer_, AdaptUp(reason_))
.WillOnce(InvokeWithoutArgs([this, &event] {
overuse_detector_->StopCheckForOveruse();
event.Set();
@@ -846,8 +829,8 @@
// Models screencast, with irregular arrival of frames which are heavy
// to encode.
TEST_F(OveruseFrameDetectorTest2, NoOveruseForLargeRandomFrameInterval) {
- EXPECT_CALL(*(observer_.get()), AdaptDown(_)).Times(0);
- EXPECT_CALL(*(observer_.get()), AdaptUp(reason_))
+ EXPECT_CALL(mock_observer_, AdaptDown(_)).Times(0);
+ EXPECT_CALL(mock_observer_, AdaptUp(reason_))
.Times(testing::AtLeast(1));
const int kNumFrames = 500;
@@ -866,8 +849,8 @@
// Models screencast, with irregular arrival of frames, often
// exceeding the timeout interval.
TEST_F(OveruseFrameDetectorTest2, NoOveruseForRandomFrameIntervalWithReset) {
- EXPECT_CALL(*(observer_.get()), AdaptDown(_)).Times(0);
- EXPECT_CALL(*(observer_.get()), AdaptUp(reason_))
+ EXPECT_CALL(mock_observer_, AdaptDown(_)).Times(0);
+ EXPECT_CALL(mock_observer_, AdaptUp(reason_))
.Times(testing::AtLeast(1));
const int kNumFrames = 500;
diff --git a/video/video_send_stream.cc b/video/video_send_stream.cc
index 4bada9a..765ec42 100644
--- a/video/video_send_stream.cc
+++ b/video/video_send_stream.cc
@@ -234,6 +234,24 @@
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;
+}
+
} // namespace
namespace internal {
@@ -597,11 +615,13 @@
encoder_config.content_type),
config_(std::move(config)),
content_type_(encoder_config.content_type) {
- video_stream_encoder_.reset(
- new VideoStreamEncoder(num_cpu_cores, &stats_proxy_,
- config_.encoder_settings,
- config_.pre_encode_callback,
- std::unique_ptr<OveruseFrameDetector>()));
+ video_stream_encoder_ = rtc::MakeUnique<VideoStreamEncoder>(
+ num_cpu_cores, &stats_proxy_,
+ config_.encoder_settings,
+ config_.pre_encode_callback,
+ rtc::MakeUnique<OveruseFrameDetector>(
+ GetCpuOveruseOptions(config_), &stats_proxy_));
+
worker_queue_->PostTask(std::unique_ptr<rtc::QueuedTask>(new ConstructionTask(
&send_stream_, &thread_sync_event_, &stats_proxy_,
video_stream_encoder_.get(), module_process_thread, call_stats, transport,
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index 1d56c52..ddf4671 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -396,13 +396,7 @@
settings_(settings),
codec_type_(PayloadStringToCodecType(settings.payload_name)),
video_sender_(Clock::GetRealTimeClock(), this),
- overuse_detector_(
- overuse_detector.get()
- ? overuse_detector.release()
- : new OveruseFrameDetector(
- GetCpuOveruseOptions(settings),
- this,
- stats_proxy)),
+ overuse_detector_(std::move(overuse_detector)),
stats_proxy_(stats_proxy),
pre_encode_callback_(pre_encode_callback),
max_framerate_(-1),
@@ -425,9 +419,10 @@
bitrate_observer_(nullptr),
encoder_queue_("EncoderQueue") {
RTC_DCHECK(stats_proxy);
+ RTC_DCHECK(overuse_detector_);
encoder_queue_.PostTask([this] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
- overuse_detector_->StartCheckForOveruse();
+ overuse_detector_->StartCheckForOveruse(this);
video_sender_.RegisterExternalEncoder(
settings_.encoder, settings_.payload_type, settings_.internal_source);
});
@@ -439,23 +434,6 @@
<< "Must call ::Stop() before destruction.";
}
-// 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 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;
-}
-
void VideoStreamEncoder::Stop() {
RTC_DCHECK_RUN_ON(&thread_checker_);
source_proxy_->SetSource(nullptr, VideoSendStream::DegradationPreference());
diff --git a/video/video_stream_encoder.h b/video/video_stream_encoder.h
index 5282f40..d8679bd 100644
--- a/video/video_stream_encoder.h
+++ b/video/video_stream_encoder.h
@@ -117,8 +117,6 @@
// These methods are protected for easier testing.
void AdaptUp(AdaptReason reason) override;
void AdaptDown(AdaptReason reason) override;
- static CpuOveruseOptions GetCpuOveruseOptions(
- const VideoSendStream::Config::EncoderSettings& settings);
private:
class ConfigureEncoderTask;
diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc
index 15ce361..c8fb8bc 100644
--- a/video/video_stream_encoder_unittest.cc
+++ b/video/video_stream_encoder_unittest.cc
@@ -67,10 +67,8 @@
class CpuOveruseDetectorProxy : public OveruseFrameDetector {
public:
CpuOveruseDetectorProxy(const CpuOveruseOptions& options,
- AdaptationObserverInterface* overuse_observer,
CpuOveruseMetricsObserver* metrics_observer)
: OveruseFrameDetector(options,
- overuse_observer,
metrics_observer),
last_target_framerate_fps_(-1) {}
virtual ~CpuOveruseDetectorProxy() {}
@@ -102,8 +100,7 @@
nullptr /* pre_encode_callback */,
std::unique_ptr<OveruseFrameDetector>(
overuse_detector_proxy_ = new CpuOveruseDetectorProxy(
- GetCpuOveruseOptions(settings),
- this,
+ CpuOveruseOptions(),
stats_proxy))) {}
void PostTaskAndWait(bool down, AdaptReason reason) {