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) {