Move frame drop functionality in VideoAdapter into a separate class.

This class will replace modules/video_coding/utility/framerate_controller.h

Bug: webrtc:13031
Change-Id: I8faa9c3c158b7c5ab0618e3504224c7e00f8e0b1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/227350
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Åsa Persson <asapersson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34802}
diff --git a/common_video/BUILD.gn b/common_video/BUILD.gn
index 8e53767..081b1c8 100644
--- a/common_video/BUILD.gn
+++ b/common_video/BUILD.gn
@@ -15,6 +15,8 @@
     "bitrate_adjuster.cc",
     "frame_rate_estimator.cc",
     "frame_rate_estimator.h",
+    "framerate_controller.cc",
+    "framerate_controller.h",
     "h264/h264_bitstream_parser.cc",
     "h264/h264_bitstream_parser.h",
     "h264/h264_common.cc",
@@ -87,6 +89,7 @@
     sources = [
       "bitrate_adjuster_unittest.cc",
       "frame_rate_estimator_unittest.cc",
+      "framerate_controller_unittest.cc",
       "h264/h264_bitstream_parser_unittest.cc",
       "h264/pps_parser_unittest.cc",
       "h264/sps_parser_unittest.cc",
diff --git a/common_video/framerate_controller.cc b/common_video/framerate_controller.cc
new file mode 100644
index 0000000..5f7099d
--- /dev/null
+++ b/common_video/framerate_controller.cc
@@ -0,0 +1,70 @@
+/*
+ *  Copyright 2021 The WebRTC Project Authors. All rights reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "common_video/framerate_controller.h"
+
+#include <limits>
+
+#include "rtc_base/time_utils.h"
+
+namespace webrtc {
+namespace {
+constexpr double kMinFramerate = 0.5;
+}  // namespace
+
+FramerateController::FramerateController()
+    : max_framerate_(std::numeric_limits<double>::max()) {}
+
+FramerateController::~FramerateController() {}
+
+void FramerateController::SetMaxFramerate(double max_framerate) {
+  max_framerate_ = max_framerate;
+}
+
+bool FramerateController::ShouldDropFrame(int64_t in_timestamp_ns) {
+  if (max_framerate_ < kMinFramerate)
+    return true;
+
+  // If `max_framerate_` is not set (i.e. maxdouble), `frame_interval_ns` is
+  // rounded to 0.
+  int64_t frame_interval_ns = rtc::kNumNanosecsPerSec / max_framerate_;
+  if (frame_interval_ns <= 0) {
+    // Frame rate throttling not enabled.
+    return false;
+  }
+
+  if (next_frame_timestamp_ns_) {
+    // Time until next frame should be outputted.
+    const int64_t time_until_next_frame_ns =
+        (*next_frame_timestamp_ns_ - in_timestamp_ns);
+    // Continue if timestamp is within expected range.
+    if (std::abs(time_until_next_frame_ns) < 2 * frame_interval_ns) {
+      // Drop if a frame shouldn't be outputted yet.
+      if (time_until_next_frame_ns > 0)
+        return true;
+      // Time to output new frame.
+      *next_frame_timestamp_ns_ += frame_interval_ns;
+      return false;
+    }
+  }
+
+  // First timestamp received or timestamp is way outside expected range, so
+  // reset. Set first timestamp target to just half the interval to prefer
+  // keeping frames in case of jitter.
+  next_frame_timestamp_ns_ = in_timestamp_ns + frame_interval_ns / 2;
+  return false;
+}
+
+void FramerateController::Reset() {
+  max_framerate_ = std::numeric_limits<double>::max();
+  next_frame_timestamp_ns_ = absl::nullopt;
+}
+
+}  // namespace webrtc
diff --git a/common_video/framerate_controller.h b/common_video/framerate_controller.h
new file mode 100644
index 0000000..9339571
--- /dev/null
+++ b/common_video/framerate_controller.h
@@ -0,0 +1,42 @@
+/*
+ *  Copyright 2021 The WebRTC Project Authors. All rights reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef COMMON_VIDEO_FRAMERATE_CONTROLLER_H_
+#define COMMON_VIDEO_FRAMERATE_CONTROLLER_H_
+
+#include <stdint.h>
+
+#include "absl/types/optional.h"
+
+namespace webrtc {
+
+// Determines which frames that should be dropped based on input framerate and
+// requested framerate.
+class FramerateController {
+ public:
+  FramerateController();
+  ~FramerateController();
+
+  // Sets max framerate (default is maxdouble).
+  void SetMaxFramerate(double max_framerate);
+
+  // Returns true if the frame should be dropped, false otherwise.
+  bool ShouldDropFrame(int64_t in_timestamp_ns);
+
+  void Reset();
+
+ private:
+  double max_framerate_;
+  absl::optional<int64_t> next_frame_timestamp_ns_;
+};
+
+}  // namespace webrtc
+
+#endif  // COMMON_VIDEO_FRAMERATE_CONTROLLER_H_
diff --git a/common_video/framerate_controller_unittest.cc b/common_video/framerate_controller_unittest.cc
new file mode 100644
index 0000000..1f4f321
--- /dev/null
+++ b/common_video/framerate_controller_unittest.cc
@@ -0,0 +1,146 @@
+/*
+ *  Copyright 2021 The WebRTC Project Authors. All rights reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "common_video/framerate_controller.h"
+
+#include <limits>
+
+#include "rtc_base/time_utils.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace {
+constexpr int kInputFps = 30;
+constexpr int kNumFrames = 60;
+}  // namespace
+
+class FramerateControllerTest : public ::testing::Test {
+ protected:
+  int64_t GetNextTimestampNs() {
+    int64_t interval_us = rtc::kNumMicrosecsPerSec / kInputFps;
+    next_timestamp_us_ += interval_us;
+    return next_timestamp_us_ * rtc::kNumNanosecsPerMicrosec;
+  }
+
+  int64_t next_timestamp_us_ = rtc::TimeMicros();
+  FramerateController controller_;
+};
+
+TEST_F(FramerateControllerTest, NoFramesDroppedIfNothingRequested) {
+  // Default max framerate is maxdouble.
+  for (int i = 1; i < kNumFrames; ++i)
+    EXPECT_FALSE(controller_.ShouldDropFrame(GetNextTimestampNs()));
+}
+
+TEST_F(FramerateControllerTest, AllFramesDroppedIfZeroRequested) {
+  controller_.SetMaxFramerate(0);
+
+  for (int i = 1; i < kNumFrames; ++i)
+    EXPECT_TRUE(controller_.ShouldDropFrame(GetNextTimestampNs()));
+}
+
+TEST_F(FramerateControllerTest, AllFramesDroppedIfNegativeRequested) {
+  controller_.SetMaxFramerate(-1);
+
+  for (int i = 1; i < kNumFrames; ++i)
+    EXPECT_TRUE(controller_.ShouldDropFrame(GetNextTimestampNs()));
+}
+
+TEST_F(FramerateControllerTest, EverySecondFrameDroppedIfHalfRequested) {
+  controller_.SetMaxFramerate(kInputFps / 2);
+
+  // The first frame should not be dropped.
+  for (int i = 1; i < kNumFrames; ++i)
+    EXPECT_EQ(i % 2 == 0, controller_.ShouldDropFrame(GetNextTimestampNs()));
+}
+
+TEST_F(FramerateControllerTest, EveryThirdFrameDroppedIfTwoThirdsRequested) {
+  controller_.SetMaxFramerate(kInputFps * 2 / 3);
+
+  // The first frame should not be dropped.
+  for (int i = 1; i < kNumFrames; ++i)
+    EXPECT_EQ(i % 3 == 0, controller_.ShouldDropFrame(GetNextTimestampNs()));
+}
+
+TEST_F(FramerateControllerTest, NoFrameDroppedIfTwiceRequested) {
+  controller_.SetMaxFramerate(kInputFps * 2);
+
+  for (int i = 1; i < kNumFrames; ++i)
+    EXPECT_FALSE(controller_.ShouldDropFrame(GetNextTimestampNs()));
+}
+
+TEST_F(FramerateControllerTest, TestAverageFramerate) {
+  const double kMaxFps = 18.2;
+  controller_.SetMaxFramerate(kMaxFps);
+
+  const int kNumSec = 10;
+  int frames_kept = 0;
+  for (int i = 0; i < kInputFps * kNumSec; ++i) {
+    if (!controller_.ShouldDropFrame(GetNextTimestampNs()))
+      ++frames_kept;
+  }
+  double average_fps = static_cast<double>(frames_kept) / kNumSec;
+  EXPECT_NEAR(kMaxFps, average_fps, 0.01);
+}
+
+TEST_F(FramerateControllerTest, NoFrameDroppedForLargeTimestampOffset) {
+  controller_.SetMaxFramerate(kInputFps);
+  EXPECT_FALSE(controller_.ShouldDropFrame(0));
+
+  const int64_t kLargeOffsetNs = -987654321LL * 1000;
+  EXPECT_FALSE(controller_.ShouldDropFrame(kLargeOffsetNs));
+
+  int64_t input_interval_ns = rtc::kNumNanosecsPerSec / kInputFps;
+  EXPECT_FALSE(controller_.ShouldDropFrame(kLargeOffsetNs + input_interval_ns));
+}
+
+TEST_F(FramerateControllerTest, NoFrameDroppedIfInputWithJitterRequested) {
+  controller_.SetMaxFramerate(kInputFps);
+
+  // Input fps with jitter.
+  int64_t input_interval_ns = rtc::kNumNanosecsPerSec / kInputFps;
+  EXPECT_FALSE(controller_.ShouldDropFrame(input_interval_ns * 0 / 10));
+  EXPECT_FALSE(controller_.ShouldDropFrame(input_interval_ns * 10 / 10 - 1));
+  EXPECT_FALSE(controller_.ShouldDropFrame(input_interval_ns * 25 / 10));
+  EXPECT_FALSE(controller_.ShouldDropFrame(input_interval_ns * 30 / 10));
+  EXPECT_FALSE(controller_.ShouldDropFrame(input_interval_ns * 35 / 10));
+  EXPECT_FALSE(controller_.ShouldDropFrame(input_interval_ns * 50 / 10));
+}
+
+TEST_F(FramerateControllerTest, FrameDroppedWhenReductionRequested) {
+  controller_.SetMaxFramerate(kInputFps);
+
+  // Expect no frame drop.
+  for (int i = 1; i < kNumFrames; ++i)
+    EXPECT_FALSE(controller_.ShouldDropFrame(GetNextTimestampNs()));
+
+  // Reduce max frame rate.
+  controller_.SetMaxFramerate(kInputFps / 2);
+
+  // Verify that every other frame is dropped.
+  for (int i = 1; i < kNumFrames; ++i)
+    EXPECT_EQ(i % 2 == 0, controller_.ShouldDropFrame(GetNextTimestampNs()));
+}
+
+TEST_F(FramerateControllerTest, NoFramesDroppedAfterReset) {
+  controller_.SetMaxFramerate(0);
+
+  // All frames dropped.
+  for (int i = 1; i < kNumFrames; ++i)
+    EXPECT_TRUE(controller_.ShouldDropFrame(GetNextTimestampNs()));
+
+  controller_.Reset();
+
+  // Expect no frame drop after reset.
+  for (int i = 1; i < kNumFrames; ++i)
+    EXPECT_FALSE(controller_.ShouldDropFrame(GetNextTimestampNs()));
+}
+
+}  // namespace webrtc
diff --git a/media/base/video_adapter.cc b/media/base/video_adapter.cc
index 7a213a2..4785dfc 100644
--- a/media/base/video_adapter.cc
+++ b/media/base/video_adapter.cc
@@ -144,43 +144,13 @@
 
 VideoAdapter::~VideoAdapter() {}
 
-bool VideoAdapter::KeepFrame(int64_t in_timestamp_ns) {
+bool VideoAdapter::DropFrame(int64_t in_timestamp_ns) {
   int max_fps = max_framerate_request_;
   if (max_fps_)
     max_fps = std::min(max_fps, *max_fps_);
 
-  if (max_fps <= 0)
-    return false;
-
-  // If `max_framerate_request_` is not set, it will default to maxint, which
-  // will lead to a frame_interval_ns rounded to 0.
-  int64_t frame_interval_ns = rtc::kNumNanosecsPerSec / max_fps;
-  if (frame_interval_ns <= 0) {
-    // Frame rate throttling not enabled.
-    return true;
-  }
-
-  if (next_frame_timestamp_ns_) {
-    // Time until next frame should be outputted.
-    const int64_t time_until_next_frame_ns =
-        (*next_frame_timestamp_ns_ - in_timestamp_ns);
-
-    // Continue if timestamp is within expected range.
-    if (std::abs(time_until_next_frame_ns) < 2 * frame_interval_ns) {
-      // Drop if a frame shouldn't be outputted yet.
-      if (time_until_next_frame_ns > 0)
-        return false;
-      // Time to output new frame.
-      *next_frame_timestamp_ns_ += frame_interval_ns;
-      return true;
-    }
-  }
-
-  // First timestamp received or timestamp is way outside expected range, so
-  // reset. Set first timestamp target to just half the interval to prefer
-  // keeping frames in case of jitter.
-  next_frame_timestamp_ns_ = in_timestamp_ns + frame_interval_ns / 2;
-  return true;
+  framerate_controller_.SetMaxFramerate(max_fps);
+  return framerate_controller_.ShouldDropFrame(in_timestamp_ns);
 }
 
 bool VideoAdapter::AdaptFrameResolution(int in_width,
@@ -214,7 +184,7 @@
       std::min(resolution_request_target_pixel_count_, max_pixel_count);
 
   // Drop the input frame if necessary.
-  if (max_pixel_count <= 0 || !KeepFrame(in_timestamp_ns)) {
+  if (max_pixel_count <= 0 || DropFrame(in_timestamp_ns)) {
     // Show VAdapt log every 90 frames dropped. (3 seconds)
     if ((frames_in_ - frames_out_) % 90 == 0) {
       // TODO(fbarchard): Reduce to LS_VERBOSE when adapter info is not needed
@@ -335,7 +305,7 @@
   target_portrait_aspect_ratio_ = target_portrait_aspect_ratio;
   max_portrait_pixel_count_ = max_portrait_pixel_count;
   max_fps_ = max_fps;
-  next_frame_timestamp_ns_ = absl::nullopt;
+  framerate_controller_.Reset();
 }
 
 void VideoAdapter::OnSinkWants(const rtc::VideoSinkWants& sink_wants) {
diff --git a/media/base/video_adapter.h b/media/base/video_adapter.h
index 0493323..1bae10d 100644
--- a/media/base/video_adapter.h
+++ b/media/base/video_adapter.h
@@ -17,6 +17,7 @@
 
 #include "absl/types/optional.h"
 #include "api/video/video_source_interface.h"
+#include "common_video/framerate_controller.h"
 #include "media/base/video_common.h"
 #include "rtc_base/constructor_magic.h"
 #include "rtc_base/synchronization/mutex.h"
@@ -108,7 +109,7 @@
 
  private:
   // Determine if frame should be dropped based on input fps and requested fps.
-  bool KeepFrame(int64_t in_timestamp_ns) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
+  bool DropFrame(int64_t in_timestamp_ns) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 
   int frames_in_ RTC_GUARDED_BY(mutex_);      // Number of input frames.
   int frames_out_ RTC_GUARDED_BY(mutex_);     // Number of output frames.
@@ -127,9 +128,6 @@
   //  - the latest `sink_wants.resolution_alignment`.
   int resolution_alignment_ RTC_GUARDED_BY(mutex_);
 
-  // The target timestamp for the next frame based on requested format.
-  absl::optional<int64_t> next_frame_timestamp_ns_ RTC_GUARDED_BY(mutex_);
-
   // Max number of pixels/fps requested via calls to OnOutputFormatRequest,
   // OnResolutionFramerateRequest respectively.
   // The adapted output format is the minimum of these.
@@ -144,6 +142,8 @@
   int resolution_request_max_pixel_count_ RTC_GUARDED_BY(mutex_);
   int max_framerate_request_ RTC_GUARDED_BY(mutex_);
 
+  webrtc::FramerateController framerate_controller_ RTC_GUARDED_BY(mutex_);
+
   // The critical section to protect the above variables.
   mutable webrtc::Mutex mutex_;
 
diff --git a/media/base/video_adapter_unittest.cc b/media/base/video_adapter_unittest.cc
index cbea817..347e24d 100644
--- a/media/base/video_adapter_unittest.cc
+++ b/media/base/video_adapter_unittest.cc
@@ -195,43 +195,8 @@
 
   // Capture 10 frames and verify that every other frame is dropped. The first
   // frame should not be dropped.
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
-  EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 1);
-  EXPECT_EQ(0, adapter_wrapper_->GetStats().dropped_frames);
-
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
-  EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 2);
-  EXPECT_EQ(1, adapter_wrapper_->GetStats().dropped_frames);
-
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
-  EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 3);
-  EXPECT_EQ(1, adapter_wrapper_->GetStats().dropped_frames);
-
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
-  EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 4);
-  EXPECT_EQ(2, adapter_wrapper_->GetStats().dropped_frames);
-
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
-  EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 5);
-  EXPECT_EQ(2, adapter_wrapper_->GetStats().dropped_frames);
-
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
-  EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 6);
-  EXPECT_EQ(3, adapter_wrapper_->GetStats().dropped_frames);
-
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
-  EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 7);
-  EXPECT_EQ(3, adapter_wrapper_->GetStats().dropped_frames);
-
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
-  EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 8);
-  EXPECT_EQ(4, adapter_wrapper_->GetStats().dropped_frames);
-
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
-  EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 9);
-  EXPECT_EQ(4, adapter_wrapper_->GetStats().dropped_frames);
-
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
+  for (int i = 0; i < 10; ++i)
+    adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
   EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 10);
   EXPECT_EQ(5, adapter_wrapper_->GetStats().dropped_frames);
 }
@@ -244,43 +209,8 @@
 
   // Capture 10 frames and verify that every third frame is dropped. The first
   // frame should not be dropped.
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
-  EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 1);
-  EXPECT_EQ(0, adapter_wrapper_->GetStats().dropped_frames);
-
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
-  EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 2);
-  EXPECT_EQ(0, adapter_wrapper_->GetStats().dropped_frames);
-
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
-  EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 3);
-  EXPECT_EQ(1, adapter_wrapper_->GetStats().dropped_frames);
-
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
-  EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 4);
-  EXPECT_EQ(1, adapter_wrapper_->GetStats().dropped_frames);
-
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
-  EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 5);
-  EXPECT_EQ(1, adapter_wrapper_->GetStats().dropped_frames);
-
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
-  EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 6);
-  EXPECT_EQ(2, adapter_wrapper_->GetStats().dropped_frames);
-
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
-  EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 7);
-  EXPECT_EQ(2, adapter_wrapper_->GetStats().dropped_frames);
-
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
-  EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 8);
-  EXPECT_EQ(2, adapter_wrapper_->GetStats().dropped_frames);
-
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
-  EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 9);
-  EXPECT_EQ(3, adapter_wrapper_->GetStats().dropped_frames);
-
-  adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
+  for (int i = 0; i < 10; ++i)
+    adapter_wrapper_->AdaptFrame(frame_source_->GetFrame());
   EXPECT_GE(adapter_wrapper_->GetStats().captured_frames, 10);
   EXPECT_EQ(3, adapter_wrapper_->GetStats().dropped_frames);
 }
@@ -318,75 +248,6 @@
   }
 }
 
-// After the first timestamp, add a big offset to the timestamps. Expect that
-// the adapter is conservative and resets to the new offset and does not drop
-// any frame.
-TEST_P(VideoAdapterTest, AdaptFramerateTimestampOffset) {
-  const int64_t capture_interval = VideoFormat::FpsToInterval(kDefaultFps);
-  OnOutputFormatRequest(640, 480, kDefaultFps);
-
-  const int64_t first_timestamp = 0;
-  adapter_.AdaptFrameResolution(640, 480, first_timestamp, &cropped_width_,
-                                &cropped_height_, &out_width_, &out_height_);
-  EXPECT_GT(out_width_, 0);
-  EXPECT_GT(out_height_, 0);
-
-  const int64_t big_offset = -987654321LL * 1000;
-  const int64_t second_timestamp = big_offset;
-  adapter_.AdaptFrameResolution(640, 480, second_timestamp, &cropped_width_,
-                                &cropped_height_, &out_width_, &out_height_);
-  EXPECT_GT(out_width_, 0);
-  EXPECT_GT(out_height_, 0);
-
-  const int64_t third_timestamp = big_offset + capture_interval;
-  adapter_.AdaptFrameResolution(640, 480, third_timestamp, &cropped_width_,
-                                &cropped_height_, &out_width_, &out_height_);
-  EXPECT_GT(out_width_, 0);
-  EXPECT_GT(out_height_, 0);
-}
-
-// Request 30 fps and send 30 fps with jitter. Expect that no frame is dropped.
-TEST_P(VideoAdapterTest, AdaptFramerateTimestampJitter) {
-  const int64_t capture_interval = VideoFormat::FpsToInterval(kDefaultFps);
-  OnOutputFormatRequest(640, 480, kDefaultFps);
-
-  adapter_.AdaptFrameResolution(640, 480, capture_interval * 0 / 10,
-                                &cropped_width_, &cropped_height_, &out_width_,
-                                &out_height_);
-  EXPECT_GT(out_width_, 0);
-  EXPECT_GT(out_height_, 0);
-
-  adapter_.AdaptFrameResolution(640, 480, capture_interval * 10 / 10 - 1,
-                                &cropped_width_, &cropped_height_, &out_width_,
-                                &out_height_);
-  EXPECT_GT(out_width_, 0);
-  EXPECT_GT(out_height_, 0);
-
-  adapter_.AdaptFrameResolution(640, 480, capture_interval * 25 / 10,
-                                &cropped_width_, &cropped_height_, &out_width_,
-                                &out_height_);
-  EXPECT_GT(out_width_, 0);
-  EXPECT_GT(out_height_, 0);
-
-  adapter_.AdaptFrameResolution(640, 480, capture_interval * 30 / 10,
-                                &cropped_width_, &cropped_height_, &out_width_,
-                                &out_height_);
-  EXPECT_GT(out_width_, 0);
-  EXPECT_GT(out_height_, 0);
-
-  adapter_.AdaptFrameResolution(640, 480, capture_interval * 35 / 10,
-                                &cropped_width_, &cropped_height_, &out_width_,
-                                &out_height_);
-  EXPECT_GT(out_width_, 0);
-  EXPECT_GT(out_height_, 0);
-
-  adapter_.AdaptFrameResolution(640, 480, capture_interval * 50 / 10,
-                                &cropped_width_, &cropped_height_, &out_width_,
-                                &out_height_);
-  EXPECT_GT(out_width_, 0);
-  EXPECT_GT(out_height_, 0);
-}
-
 // Adapt the frame rate to be half of the capture rate after capturing no less
 // than 10 frames. Expect no frame dropped before adaptation and frame dropped
 // after adaptation.
diff --git a/media/engine/simulcast_encoder_adapter.cc b/media/engine/simulcast_encoder_adapter.cc
index d4137f6..3b63725 100644
--- a/media/engine/simulcast_encoder_adapter.cc
+++ b/media/engine/simulcast_encoder_adapter.cc
@@ -167,7 +167,7 @@
 SimulcastEncoderAdapter::StreamContext::StreamContext(
     SimulcastEncoderAdapter* parent,
     std::unique_ptr<EncoderContext> encoder_context,
-    std::unique_ptr<FramerateController> framerate_controller,
+    std::unique_ptr<FramerateControllerDeprecated> framerate_controller,
     int stream_idx,
     uint16_t width,
     uint16_t height,
@@ -422,7 +422,8 @@
     bool is_paused = stream_start_bitrate_kbps[stream_idx] == 0;
     stream_contexts_.emplace_back(
         parent, std::move(encoder_context),
-        std::make_unique<FramerateController>(stream_codec.maxFramerate),
+        std::make_unique<FramerateControllerDeprecated>(
+            stream_codec.maxFramerate),
         stream_idx, stream_codec.width, stream_codec.height, is_paused);
   }
 
diff --git a/media/engine/simulcast_encoder_adapter.h b/media/engine/simulcast_encoder_adapter.h
index 1d2200b..7d15f10 100644
--- a/media/engine/simulcast_encoder_adapter.h
+++ b/media/engine/simulcast_encoder_adapter.h
@@ -26,7 +26,7 @@
 #include "api/video_codecs/video_encoder.h"
 #include "api/video_codecs/video_encoder_factory.h"
 #include "modules/video_coding/include/video_codec_interface.h"
-#include "modules/video_coding/utility/framerate_controller.h"
+#include "modules/video_coding/utility/framerate_controller_deprecated.h"
 #include "rtc_base/atomic_ops.h"
 #include "rtc_base/experiments/encoder_info_settings.h"
 #include "rtc_base/system/no_unique_address.h"
@@ -93,13 +93,14 @@
 
   class StreamContext : public EncodedImageCallback {
    public:
-    StreamContext(SimulcastEncoderAdapter* parent,
-                  std::unique_ptr<EncoderContext> encoder_context,
-                  std::unique_ptr<FramerateController> framerate_controller,
-                  int stream_idx,
-                  uint16_t width,
-                  uint16_t height,
-                  bool send_stream);
+    StreamContext(
+        SimulcastEncoderAdapter* parent,
+        std::unique_ptr<EncoderContext> encoder_context,
+        std::unique_ptr<FramerateControllerDeprecated> framerate_controller,
+        int stream_idx,
+        uint16_t width,
+        uint16_t height,
+        bool send_stream);
     StreamContext(StreamContext&& rhs);
     StreamContext& operator=(StreamContext&&) = delete;
     ~StreamContext() override;
@@ -134,7 +135,7 @@
    private:
     SimulcastEncoderAdapter* const parent_;
     std::unique_ptr<EncoderContext> encoder_context_;
-    std::unique_ptr<FramerateController> framerate_controller_;
+    std::unique_ptr<FramerateControllerDeprecated> framerate_controller_;
     const int stream_idx_;
     const uint16_t width_;
     const uint16_t height_;
diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn
index 47e4f05..9a438c6 100644
--- a/modules/video_coding/BUILD.gn
+++ b/modules/video_coding/BUILD.gn
@@ -319,8 +319,8 @@
     "utility/decoded_frames_history.h",
     "utility/frame_dropper.cc",
     "utility/frame_dropper.h",
-    "utility/framerate_controller.cc",
-    "utility/framerate_controller.h",
+    "utility/framerate_controller_deprecated.cc",
+    "utility/framerate_controller_deprecated.h",
     "utility/ivf_file_reader.cc",
     "utility/ivf_file_reader.h",
     "utility/ivf_file_writer.cc",
@@ -981,7 +981,7 @@
       "unique_timestamp_counter_unittest.cc",
       "utility/decoded_frames_history_unittest.cc",
       "utility/frame_dropper_unittest.cc",
-      "utility/framerate_controller_unittest.cc",
+      "utility/framerate_controller_deprecated_unittest.cc",
       "utility/ivf_file_reader_unittest.cc",
       "utility/ivf_file_writer_unittest.cc",
       "utility/qp_parser_unittest.cc",
diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h
index f744594..6437587 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h
@@ -24,7 +24,7 @@
 #include "modules/video_coding/codecs/interface/libvpx_interface.h"
 #include "modules/video_coding/codecs/vp8/include/vp8.h"
 #include "modules/video_coding/include/video_codec_interface.h"
-#include "modules/video_coding/utility/framerate_controller.h"
+#include "modules/video_coding/utility/framerate_controller_deprecated.h"
 #include "rtc_base/experiments/cpu_speed_experiment.h"
 #include "rtc_base/experiments/encoder_info_settings.h"
 #include "rtc_base/experiments/rate_control_settings.h"
@@ -145,7 +145,7 @@
   } variable_framerate_experiment_;
   static VariableFramerateExperiment ParseVariableFramerateConfig(
       std::string group_name);
-  FramerateController framerate_controller_;
+  FramerateControllerDeprecated framerate_controller_;
   int num_steady_state_frames_ = 0;
 
   FecControllerOverride* fec_controller_override_ = nullptr;
diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc
index 525fbe8..f920a64 100644
--- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc
+++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc
@@ -496,8 +496,8 @@
   if (use_svc_controller_) {
     svc_controller_ = CreateVp9ScalabilityStructure(*inst);
   }
-  framerate_controller_ = std::vector<FramerateController>(
-      num_spatial_layers_, FramerateController(codec_.maxFramerate));
+  framerate_controller_ = std::vector<FramerateControllerDeprecated>(
+      num_spatial_layers_, FramerateControllerDeprecated(codec_.maxFramerate));
 
   is_svc_ = (num_spatial_layers_ > 1 || num_temporal_layers_ > 1);
 
diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h
index 826e8d6..c2790f0 100644
--- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h
+++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h
@@ -27,7 +27,7 @@
 #include "modules/video_coding/codecs/vp9/include/vp9.h"
 #include "modules/video_coding/codecs/vp9/vp9_frame_buffer_pool.h"
 #include "modules/video_coding/svc/scalable_video_controller.h"
-#include "modules/video_coding/utility/framerate_controller.h"
+#include "modules/video_coding/utility/framerate_controller_deprecated.h"
 #include "rtc_base/experiments/encoder_info_settings.h"
 #include "vpx/vp8cx.h"
 
@@ -147,7 +147,7 @@
   const bool use_svc_controller_;
 
   std::unique_ptr<ScalableVideoController> svc_controller_;
-  std::vector<FramerateController> framerate_controller_;
+  std::vector<FramerateControllerDeprecated> framerate_controller_;
 
   // Used for flexible mode.
   bool is_flexible_mode_;
@@ -188,7 +188,7 @@
   } variable_framerate_experiment_;
   static VariableFramerateExperiment ParseVariableFramerateConfig(
       const WebRtcKeyValueConfig& trials);
-  FramerateController variable_framerate_controller_;
+  FramerateControllerDeprecated variable_framerate_controller_;
 
   const struct QualityScalerExperiment {
     int low_qp;
diff --git a/modules/video_coding/utility/framerate_controller.cc b/modules/video_coding/utility/framerate_controller_deprecated.cc
similarity index 75%
rename from modules/video_coding/utility/framerate_controller.cc
rename to modules/video_coding/utility/framerate_controller_deprecated.cc
index 7abc67e..5978adc 100644
--- a/modules/video_coding/utility/framerate_controller.cc
+++ b/modules/video_coding/utility/framerate_controller_deprecated.cc
@@ -8,7 +8,7 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "modules/video_coding/utility/framerate_controller.h"
+#include "modules/video_coding/utility/framerate_controller_deprecated.h"
 
 #include <stddef.h>
 
@@ -16,12 +16,13 @@
 
 namespace webrtc {
 
-FramerateController::FramerateController(float target_framerate_fps)
+FramerateControllerDeprecated::FramerateControllerDeprecated(
+    float target_framerate_fps)
     : min_frame_interval_ms_(0), framerate_estimator_(1000.0, 1000.0) {
   SetTargetRate(target_framerate_fps);
 }
 
-void FramerateController::SetTargetRate(float target_framerate_fps) {
+void FramerateControllerDeprecated::SetTargetRate(float target_framerate_fps) {
   if (target_framerate_fps_ != target_framerate_fps) {
     framerate_estimator_.Reset();
     if (last_timestamp_ms_) {
@@ -34,16 +35,16 @@
   }
 }
 
-float FramerateController::GetTargetRate() {
+float FramerateControllerDeprecated::GetTargetRate() {
   return *target_framerate_fps_;
 }
 
-void FramerateController::Reset() {
+void FramerateControllerDeprecated::Reset() {
   framerate_estimator_.Reset();
   last_timestamp_ms_.reset();
 }
 
-bool FramerateController::DropFrame(uint32_t timestamp_ms) const {
+bool FramerateControllerDeprecated::DropFrame(uint32_t timestamp_ms) const {
   if (timestamp_ms < last_timestamp_ms_) {
     // Timestamp jumps backward. We can't make adequate drop decision. Don't
     // drop this frame. Stats will be reset in AddFrame().
@@ -66,7 +67,7 @@
   return false;
 }
 
-void FramerateController::AddFrame(uint32_t timestamp_ms) {
+void FramerateControllerDeprecated::AddFrame(uint32_t timestamp_ms) {
   if (timestamp_ms < last_timestamp_ms_) {
     // Timestamp jumps backward.
     Reset();
@@ -76,7 +77,8 @@
   last_timestamp_ms_ = timestamp_ms;
 }
 
-absl::optional<float> FramerateController::Rate(uint32_t timestamp_ms) const {
+absl::optional<float> FramerateControllerDeprecated::Rate(
+    uint32_t timestamp_ms) const {
   return framerate_estimator_.Rate(timestamp_ms);
 }
 
diff --git a/modules/video_coding/utility/framerate_controller.h b/modules/video_coding/utility/framerate_controller_deprecated.h
similarity index 73%
rename from modules/video_coding/utility/framerate_controller.h
rename to modules/video_coding/utility/framerate_controller_deprecated.h
index 4b6a6ad..ca0cbea 100644
--- a/modules/video_coding/utility/framerate_controller.h
+++ b/modules/video_coding/utility/framerate_controller_deprecated.h
@@ -8,8 +8,8 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#ifndef MODULES_VIDEO_CODING_UTILITY_FRAMERATE_CONTROLLER_H_
-#define MODULES_VIDEO_CODING_UTILITY_FRAMERATE_CONTROLLER_H_
+#ifndef MODULES_VIDEO_CODING_UTILITY_FRAMERATE_CONTROLLER_DEPRECATED_H_
+#define MODULES_VIDEO_CODING_UTILITY_FRAMERATE_CONTROLLER_DEPRECATED_H_
 
 #include <stdint.h>
 
@@ -18,9 +18,10 @@
 
 namespace webrtc {
 
-class FramerateController {
+// Please use webrtc::FramerateController instead.
+class FramerateControllerDeprecated {
  public:
-  explicit FramerateController(float target_framerate_fps);
+  explicit FramerateControllerDeprecated(float target_framerate_fps);
 
   void SetTargetRate(float target_framerate_fps);
   float GetTargetRate();
@@ -43,4 +44,4 @@
 
 }  // namespace webrtc
 
-#endif  // MODULES_VIDEO_CODING_UTILITY_FRAMERATE_CONTROLLER_H_
+#endif  // MODULES_VIDEO_CODING_UTILITY_FRAMERATE_CONTROLLER_DEPRECATED_H_
diff --git a/modules/video_coding/utility/framerate_controller_unittest.cc b/modules/video_coding/utility/framerate_controller_deprecated_unittest.cc
similarity index 76%
rename from modules/video_coding/utility/framerate_controller_unittest.cc
rename to modules/video_coding/utility/framerate_controller_deprecated_unittest.cc
index fb6e8cc..eabf052 100644
--- a/modules/video_coding/utility/framerate_controller_unittest.cc
+++ b/modules/video_coding/utility/framerate_controller_deprecated_unittest.cc
@@ -8,7 +8,7 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "modules/video_coding/utility/framerate_controller.h"
+#include "modules/video_coding/utility/framerate_controller_deprecated.h"
 
 #include <stddef.h>
 
@@ -16,14 +16,14 @@
 
 namespace webrtc {
 
-TEST(FramerateController, KeepTargetFramerate) {
+TEST(FramerateControllerDeprecated, KeepTargetFramerate) {
   const float input_framerate_fps = 20;
   const float target_framerate_fps = 5;
   const float max_abs_framerate_error_fps = target_framerate_fps * 0.1f;
   const size_t input_duration_secs = 3;
   const size_t num_input_frames = input_duration_secs * input_framerate_fps;
 
-  FramerateController framerate_controller(target_framerate_fps);
+  FramerateControllerDeprecated framerate_controller(target_framerate_fps);
   size_t num_dropped_frames = 0;
   for (size_t frame_num = 0; frame_num < num_input_frames; ++frame_num) {
     const uint32_t timestamp_ms =
@@ -42,12 +42,12 @@
               max_abs_framerate_error_fps);
 }
 
-TEST(FramerateController, DoNotDropAnyFramesIfTargerEqualsInput) {
+TEST(FramerateControllerDeprecated, DoNotDropAnyFramesIfTargerEqualsInput) {
   const float input_framerate_fps = 30;
   const size_t input_duration_secs = 3;
   const size_t num_input_frames = input_duration_secs * input_framerate_fps;
 
-  FramerateController framerate_controller(input_framerate_fps);
+  FramerateControllerDeprecated framerate_controller(input_framerate_fps);
   size_t num_dropped_frames = 0;
   for (size_t frame_num = 0; frame_num < num_input_frames; ++frame_num) {
     const uint32_t timestamp_ms =
@@ -62,26 +62,26 @@
   EXPECT_EQ(num_dropped_frames, 0U);
 }
 
-TEST(FramerateController, DoNotDropFrameWhenTimestampJumpsBackward) {
-  FramerateController framerate_controller(30);
+TEST(FramerateControllerDeprecated, DoNotDropFrameWhenTimestampJumpsBackward) {
+  FramerateControllerDeprecated framerate_controller(30);
   ASSERT_FALSE(framerate_controller.DropFrame(66));
   framerate_controller.AddFrame(66);
   EXPECT_FALSE(framerate_controller.DropFrame(33));
 }
 
-TEST(FramerateController, DropFrameIfItIsTooCloseToPreviousFrame) {
-  FramerateController framerate_controller(30);
+TEST(FramerateControllerDeprecated, DropFrameIfItIsTooCloseToPreviousFrame) {
+  FramerateControllerDeprecated framerate_controller(30);
   ASSERT_FALSE(framerate_controller.DropFrame(33));
   framerate_controller.AddFrame(33);
   EXPECT_TRUE(framerate_controller.DropFrame(34));
 }
 
-TEST(FramerateController, FrameDroppingStartsFromSecondInputFrame) {
+TEST(FramerateControllerDeprecated, FrameDroppingStartsFromSecondInputFrame) {
   const float input_framerate_fps = 23;
   const float target_framerate_fps = 19;
   const uint32_t input_frame_duration_ms =
       static_cast<uint32_t>(1000 / input_framerate_fps);
-  FramerateController framerate_controller(target_framerate_fps);
+  FramerateControllerDeprecated framerate_controller(target_framerate_fps);
   ASSERT_FALSE(framerate_controller.DropFrame(1 * input_frame_duration_ms));
   framerate_controller.AddFrame(1 * input_frame_duration_ms);
   EXPECT_TRUE(framerate_controller.DropFrame(2 * input_frame_duration_ms));