Implement `Y4mFrameGenerator::ChangeResolution()`
This CL implements `ChangeResolution()` to let `Y4mFrameGenerator`
generate I420 frame with resolution other than y4m input by scaling. The
code is mostly copied from `IvfVideoFrameGenerator`.
The test case is also added for this change.
Bug: webrtc:15210
Change-Id: I690e427a545a72d93ed39b77fd0f602054a30508
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/311521
Commit-Queue: Jianhui J Dai <jianhui.j.dai@intel.com>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40426}
diff --git a/test/testsupport/y4m_frame_generator.cc b/test/testsupport/y4m_frame_generator.cc
index 39a5ad9..f1ecbf9 100644
--- a/test/testsupport/y4m_frame_generator.cc
+++ b/test/testsupport/y4m_frame_generator.cc
@@ -59,7 +59,26 @@
static_cast<int>(height_)};
rtc::scoped_refptr<webrtc::I420Buffer> next_frame_buffer =
frame_reader_->PullFrame();
- return VideoFrameData(next_frame_buffer, update_rect);
+
+ if (!next_frame_buffer ||
+ (static_cast<size_t>(next_frame_buffer->width()) == width_ &&
+ static_cast<size_t>(next_frame_buffer->height()) == height_)) {
+ return VideoFrameData(next_frame_buffer, update_rect);
+ }
+
+ // Allocate a new buffer and return scaled version.
+ rtc::scoped_refptr<webrtc::I420Buffer> scaled_buffer(
+ I420Buffer::Create(width_, height_));
+ webrtc::I420Buffer::SetBlack(scaled_buffer.get());
+ scaled_buffer->ScaleFrom(*next_frame_buffer->ToI420());
+ return VideoFrameData(scaled_buffer, update_rect);
+}
+
+void Y4mFrameGenerator::ChangeResolution(size_t width, size_t height) {
+ width_ = width;
+ height_ = height;
+ RTC_CHECK_GT(width_, 0);
+ RTC_CHECK_GT(height_, 0);
}
FrameGeneratorInterface::Resolution Y4mFrameGenerator::GetResolution() const {
diff --git a/test/testsupport/y4m_frame_generator.h b/test/testsupport/y4m_frame_generator.h
index bccd109..4ff64be 100644
--- a/test/testsupport/y4m_frame_generator.h
+++ b/test/testsupport/y4m_frame_generator.h
@@ -45,9 +45,7 @@
VideoFrameData NextFrame() override;
- void ChangeResolution(size_t width, size_t height) override {
- RTC_CHECK_NOTREACHED();
- }
+ void ChangeResolution(size_t width, size_t height) override;
Resolution GetResolution() const override;
diff --git a/test/testsupport/y4m_frame_generator_test.cc b/test/testsupport/y4m_frame_generator_test.cc
index 4341c3e..24d10c8 100644
--- a/test/testsupport/y4m_frame_generator_test.cc
+++ b/test/testsupport/y4m_frame_generator_test.cc
@@ -82,6 +82,29 @@
remove(input_filepath.c_str());
}
+TEST_F(Y4mFrameGeneratorTest, CanChangeResolution) {
+ constexpr int kNewWidth = 4;
+ constexpr int kNewHeight = 6;
+ constexpr int kFrameCount = 10;
+
+ Y4mFrameGenerator generator(input_filepath_,
+ Y4mFrameGenerator::RepeatMode::kLoop);
+ FrameGeneratorInterface::Resolution res = generator.GetResolution();
+ EXPECT_EQ(res.width, 2u);
+ EXPECT_EQ(res.height, 2u);
+
+ generator.ChangeResolution(kNewWidth, kNewHeight);
+ res = generator.GetResolution();
+ EXPECT_EQ(static_cast<int>(res.width), kNewWidth);
+ EXPECT_EQ(static_cast<int>(res.height), kNewHeight);
+
+ for (int i = 0; i < kFrameCount; ++i) {
+ FrameGeneratorInterface::VideoFrameData frame = generator.NextFrame();
+ EXPECT_EQ(frame.buffer->width(), kNewWidth);
+ EXPECT_EQ(frame.buffer->height(), kNewHeight);
+ }
+}
+
TEST_F(Y4mFrameGeneratorTest, SingleRepeatMode) {
Y4mFrameGenerator generator(input_filepath_,
Y4mFrameGenerator::RepeatMode::kSingle);