FrameGeneratorCapturer: add methods OnOutputFormatRequest and GetResolution
To be used in tests.
Bug: none
Change-Id: Ia7b551b3ac66ed23d1907df56ddc4e09e3667a2b
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/245644
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Commit-Queue: Åsa Persson <asapersson@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35703}
diff --git a/test/frame_generator_capturer.cc b/test/frame_generator_capturer.cc
index a4c528e..1a51bfc 100644
--- a/test/frame_generator_capturer.cc
+++ b/test/frame_generator_capturer.cc
@@ -175,31 +175,49 @@
}
void FrameGeneratorCapturer::InsertFrame() {
- MutexLock lock(&lock_);
- if (sending_) {
- FrameGeneratorInterface::VideoFrameData frame_data =
- frame_generator_->NextFrame();
- // TODO(srte): Use more advanced frame rate control to allow arbritrary
- // fractions.
- int decimation =
- std::round(static_cast<double>(source_fps_) / target_capture_fps_);
- for (int i = 1; i < decimation; ++i)
- frame_data = frame_generator_->NextFrame();
+ absl::optional<Resolution> resolution;
- VideoFrame frame = VideoFrame::Builder()
- .set_video_frame_buffer(frame_data.buffer)
- .set_rotation(fake_rotation_)
- .set_timestamp_us(clock_->TimeInMicroseconds())
- .set_ntp_time_ms(clock_->CurrentNtpInMilliseconds())
- .set_update_rect(frame_data.update_rect)
- .set_color_space(fake_color_space_)
- .build();
- if (first_frame_capture_time_ == -1) {
- first_frame_capture_time_ = frame.ntp_time_ms();
+ {
+ MutexLock lock(&lock_);
+ if (sending_) {
+ FrameGeneratorInterface::VideoFrameData frame_data =
+ frame_generator_->NextFrame();
+ // TODO(srte): Use more advanced frame rate control to allow arbritrary
+ // fractions.
+ int decimation =
+ std::round(static_cast<double>(source_fps_) / target_capture_fps_);
+ for (int i = 1; i < decimation; ++i)
+ frame_data = frame_generator_->NextFrame();
+
+ VideoFrame frame =
+ VideoFrame::Builder()
+ .set_video_frame_buffer(frame_data.buffer)
+ .set_rotation(fake_rotation_)
+ .set_timestamp_us(clock_->TimeInMicroseconds())
+ .set_ntp_time_ms(clock_->CurrentNtpInMilliseconds())
+ .set_update_rect(frame_data.update_rect)
+ .set_color_space(fake_color_space_)
+ .build();
+ if (first_frame_capture_time_ == -1) {
+ first_frame_capture_time_ = frame.ntp_time_ms();
+ }
+
+ resolution = Resolution{frame.width(), frame.height()};
+
+ TestVideoCapturer::OnFrame(frame);
}
-
- TestVideoCapturer::OnFrame(frame);
}
+
+ if (resolution) {
+ MutexLock lock(&stats_lock_);
+ source_resolution_ = resolution;
+ }
+}
+
+absl::optional<FrameGeneratorCapturer::Resolution>
+FrameGeneratorCapturer::GetResolution() {
+ MutexLock lock(&stats_lock_);
+ return source_resolution_;
}
void FrameGeneratorCapturer::Start() {
@@ -243,6 +261,13 @@
target_capture_fps_ = std::min(source_fps_, target_framerate);
}
+void FrameGeneratorCapturer::OnOutputFormatRequest(
+ int width,
+ int height,
+ const absl::optional<int>& max_fps) {
+ TestVideoCapturer::OnOutputFormatRequest(width, height, max_fps);
+}
+
void FrameGeneratorCapturer::SetSinkWantsObserver(SinkWantsObserver* observer) {
MutexLock lock(&lock_);
RTC_DCHECK(!sink_wants_observer_);
diff --git a/test/frame_generator_capturer.h b/test/frame_generator_capturer.h
index 1e915fc..e310e40 100644
--- a/test/frame_generator_capturer.h
+++ b/test/frame_generator_capturer.h
@@ -132,6 +132,16 @@
void ChangeResolution(size_t width, size_t height);
void ChangeFramerate(int target_framerate);
+ struct Resolution {
+ int width;
+ int height;
+ };
+ absl::optional<Resolution> GetResolution();
+
+ void OnOutputFormatRequest(int width,
+ int height,
+ const absl::optional<int>& max_fps);
+
void SetSinkWantsObserver(SinkWantsObserver* observer);
void AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink,
@@ -167,6 +177,10 @@
absl::optional<ColorSpace> fake_color_space_ RTC_GUARDED_BY(&lock_);
int64_t first_frame_capture_time_;
+
+ Mutex stats_lock_;
+ absl::optional<Resolution> source_resolution_ RTC_GUARDED_BY(&stats_lock_);
+
// Must be the last field, so it will be deconstructed first as tasks
// in the TaskQueue access other fields of the instance of this class.
rtc::TaskQueue task_queue_;
diff --git a/test/frame_generator_capturer_unittest.cc b/test/frame_generator_capturer_unittest.cc
index a76cb95..d8371f4 100644
--- a/test/frame_generator_capturer_unittest.cc
+++ b/test/frame_generator_capturer_unittest.cc
@@ -19,6 +19,9 @@
using ::testing::Eq;
using ::testing::Property;
+constexpr int kWidth = 640;
+constexpr int kHeight = 360;
+
class MockVideoSinkInterfaceVideoFrame
: public rtc::VideoSinkInterface<VideoFrame> {
public:
@@ -26,6 +29,7 @@
MOCK_METHOD(void, OnDiscardedFrame, (), (override));
};
} // namespace
+
TEST(FrameGeneratorCapturerTest, CreateFromConfig) {
GlobalSimulatedTimeController time(Timestamp::Seconds(1000));
FrameGeneratorCapturerConfig config;
@@ -41,5 +45,45 @@
.Times(21);
time.AdvanceTime(TimeDelta::Seconds(1));
}
+
+TEST(FrameGeneratorCapturerTest, OnOutputFormatRequest) {
+ GlobalSimulatedTimeController time(Timestamp::Seconds(1000));
+ FrameGeneratorCapturerConfig config;
+ config.squares_video->width = kWidth;
+ config.squares_video->height = kHeight;
+ config.squares_video->framerate = 20;
+ auto capturer = FrameGeneratorCapturer::Create(
+ time.GetClock(), *time.GetTaskQueueFactory(), config);
+ testing::StrictMock<MockVideoSinkInterfaceVideoFrame> mock_sink;
+ capturer->AddOrUpdateSink(&mock_sink, rtc::VideoSinkWants());
+ capturer->OnOutputFormatRequest(kWidth / 2, kHeight / 2, /*max_fps=*/10);
+ capturer->Start();
+ EXPECT_CALL(mock_sink, OnFrame(Property(&VideoFrame::width, Eq(kWidth / 2))))
+ .Times(11);
+ time.AdvanceTime(TimeDelta::Seconds(1));
+}
+
+TEST(FrameGeneratorCapturerTest, ChangeResolution) {
+ GlobalSimulatedTimeController time(Timestamp::Seconds(1000));
+ FrameGeneratorCapturerConfig config;
+ config.squares_video->width = kWidth;
+ config.squares_video->height = kHeight;
+ config.squares_video->framerate = 20;
+ auto capturer = FrameGeneratorCapturer::Create(
+ time.GetClock(), *time.GetTaskQueueFactory(), config);
+ EXPECT_FALSE(capturer->GetResolution());
+ capturer->Start();
+ time.AdvanceTime(TimeDelta::Seconds(1));
+ ASSERT_TRUE(capturer->GetResolution());
+ EXPECT_EQ(kWidth, capturer->GetResolution()->width);
+ EXPECT_EQ(kHeight, capturer->GetResolution()->height);
+
+ capturer->ChangeResolution(kWidth / 2, kHeight / 2);
+ time.AdvanceTime(TimeDelta::Seconds(1));
+ ASSERT_TRUE(capturer->GetResolution());
+ EXPECT_EQ(kWidth / 2, capturer->GetResolution()->width);
+ EXPECT_EQ(kHeight / 2, capturer->GetResolution()->height);
+}
+
} // namespace test
} // namespace webrtc
diff --git a/test/test_video_capturer.cc b/test/test_video_capturer.cc
index 9ce4aa0..4a4adc6 100644
--- a/test/test_video_capturer.cc
+++ b/test/test_video_capturer.cc
@@ -21,6 +21,17 @@
namespace test {
TestVideoCapturer::~TestVideoCapturer() = default;
+void TestVideoCapturer::OnOutputFormatRequest(
+ int width,
+ int height,
+ const absl::optional<int>& max_fps) {
+ absl::optional<std::pair<int, int>> target_aspect_ratio =
+ std::make_pair(width, height);
+ absl::optional<int> max_pixel_count = width * height;
+ video_adapter_.OnOutputFormatRequest(target_aspect_ratio, max_pixel_count,
+ max_fps);
+}
+
void TestVideoCapturer::OnFrame(const VideoFrame& original_frame) {
int cropped_width = 0;
int cropped_height = 0;
diff --git a/test/test_video_capturer.h b/test/test_video_capturer.h
index dff529c..6fafd96 100644
--- a/test/test_video_capturer.h
+++ b/test/test_video_capturer.h
@@ -41,6 +41,9 @@
MutexLock lock(&lock_);
preprocessor_ = std::move(preprocessor);
}
+ void OnOutputFormatRequest(int width,
+ int height,
+ const absl::optional<int>& max_fps);
protected:
void OnFrame(const VideoFrame& frame);