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:
parent
0e9556a90c
commit
9e5defcf74
@ -59,9 +59,28 @@ Y4mFrameGenerator::VideoFrameData Y4mFrameGenerator::NextFrame() {
|
|||||||
static_cast<int>(height_)};
|
static_cast<int>(height_)};
|
||||||
rtc::scoped_refptr<webrtc::I420Buffer> next_frame_buffer =
|
rtc::scoped_refptr<webrtc::I420Buffer> next_frame_buffer =
|
||||||
frame_reader_->PullFrame();
|
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);
|
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 {
|
FrameGeneratorInterface::Resolution Y4mFrameGenerator::GetResolution() const {
|
||||||
return {.width = width_, .height = height_};
|
return {.width = width_, .height = height_};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,9 +45,7 @@ class Y4mFrameGenerator : public FrameGeneratorInterface {
|
|||||||
|
|
||||||
VideoFrameData NextFrame() override;
|
VideoFrameData NextFrame() override;
|
||||||
|
|
||||||
void ChangeResolution(size_t width, size_t height) override {
|
void ChangeResolution(size_t width, size_t height) override;
|
||||||
RTC_CHECK_NOTREACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Resolution GetResolution() const override;
|
Resolution GetResolution() const override;
|
||||||
|
|
||||||
|
|||||||
@ -82,6 +82,29 @@ TEST_F(Y4mFrameGeneratorTest, CanReadFPSFromFileWhenRoundingIsNeeded) {
|
|||||||
remove(input_filepath.c_str());
|
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) {
|
TEST_F(Y4mFrameGeneratorTest, SingleRepeatMode) {
|
||||||
Y4mFrameGenerator generator(input_filepath_,
|
Y4mFrameGenerator generator(input_filepath_,
|
||||||
Y4mFrameGenerator::RepeatMode::kSingle);
|
Y4mFrameGenerator::RepeatMode::kSingle);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user