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