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}
This commit is contained in:
Jianhui Dai 2023-07-12 04:58:09 +08:00 committed by WebRTC LUCI CQ
parent 0e9556a90c
commit 9e5defcf74
3 changed files with 44 additions and 4 deletions

View File

@ -59,7 +59,26 @@ Y4mFrameGenerator::VideoFrameData Y4mFrameGenerator::NextFrame() {
static_cast<int>(height_)};
rtc::scoped_refptr<webrtc::I420Buffer> next_frame_buffer =
frame_reader_->PullFrame();
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 {

View File

@ -45,9 +45,7 @@ class Y4mFrameGenerator : public FrameGeneratorInterface {
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;

View File

@ -82,6 +82,29 @@ TEST_F(Y4mFrameGeneratorTest, CanReadFPSFromFileWhenRoundingIsNeeded) {
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);