Don't scale frames by default in the IVF generator
Deliver original decoded resolution unless output resolution is explicitly configured via ChangeResolution(). Bug: none Change-Id: I1d2a47fa564010202762062d7ac483ad3c4effde Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/375340 Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43902}
This commit is contained in:
parent
20bd702ebe
commit
fa7c5b6674
@ -58,8 +58,8 @@ IvfVideoFrameGenerator::IvfVideoFrameGenerator(const Environment& env,
|
|||||||
: callback_(this),
|
: callback_(this),
|
||||||
file_reader_(IvfFileReader::Create(FileWrapper::OpenReadOnly(file_name))),
|
file_reader_(IvfFileReader::Create(FileWrapper::OpenReadOnly(file_name))),
|
||||||
video_decoder_(CreateDecoder(env, file_reader_->GetVideoCodecType())),
|
video_decoder_(CreateDecoder(env, file_reader_->GetVideoCodecType())),
|
||||||
width_(file_reader_->GetFrameWidth()),
|
original_resolution_({.width = file_reader_->GetFrameWidth(),
|
||||||
height_(file_reader_->GetFrameHeight()),
|
.height = file_reader_->GetFrameHeight()}),
|
||||||
fps_hint_(fps_hint) {
|
fps_hint_(fps_hint) {
|
||||||
RTC_CHECK(video_decoder_) << "No decoder found for file's video codec type";
|
RTC_CHECK(video_decoder_) << "No decoder found for file's video codec type";
|
||||||
VideoDecoder::Settings decoder_settings;
|
VideoDecoder::Settings decoder_settings;
|
||||||
@ -110,12 +110,18 @@ FrameGeneratorInterface::VideoFrameData IvfVideoFrameGenerator::NextFrame() {
|
|||||||
MutexLock frame_lock(&frame_decode_lock_);
|
MutexLock frame_lock(&frame_decode_lock_);
|
||||||
rtc::scoped_refptr<VideoFrameBuffer> buffer =
|
rtc::scoped_refptr<VideoFrameBuffer> buffer =
|
||||||
next_frame_->video_frame_buffer();
|
next_frame_->video_frame_buffer();
|
||||||
if (width_ != static_cast<size_t>(buffer->width()) ||
|
|
||||||
height_ != static_cast<size_t>(buffer->height())) {
|
// Set original resolution to resolution of decoded frame.
|
||||||
|
original_resolution_ = {.width = static_cast<size_t>(buffer->width()),
|
||||||
|
.height = static_cast<size_t>(buffer->width())};
|
||||||
|
|
||||||
|
if (output_resolution_.has_value() &&
|
||||||
|
(output_resolution_->width != original_resolution_.width ||
|
||||||
|
output_resolution_->height != original_resolution_.height)) {
|
||||||
// Video adapter has requested a down-scale. Allocate a new buffer and
|
// Video adapter has requested a down-scale. Allocate a new buffer and
|
||||||
// return scaled version.
|
// return scaled version.
|
||||||
rtc::scoped_refptr<I420Buffer> scaled_buffer =
|
rtc::scoped_refptr<I420Buffer> scaled_buffer = I420Buffer::Create(
|
||||||
I420Buffer::Create(width_, height_);
|
output_resolution_->width, output_resolution_->height);
|
||||||
scaled_buffer->ScaleFrom(*buffer->ToI420());
|
scaled_buffer->ScaleFrom(*buffer->ToI420());
|
||||||
buffer = scaled_buffer;
|
buffer = scaled_buffer;
|
||||||
}
|
}
|
||||||
@ -139,13 +145,12 @@ void IvfVideoFrameGenerator::SkipNextFrame() {
|
|||||||
|
|
||||||
void IvfVideoFrameGenerator::ChangeResolution(size_t width, size_t height) {
|
void IvfVideoFrameGenerator::ChangeResolution(size_t width, size_t height) {
|
||||||
MutexLock lock(&lock_);
|
MutexLock lock(&lock_);
|
||||||
width_ = width;
|
output_resolution_ = {.width = width, .height = height};
|
||||||
height_ = height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameGeneratorInterface::Resolution IvfVideoFrameGenerator::GetResolution()
|
FrameGeneratorInterface::Resolution IvfVideoFrameGenerator::GetResolution()
|
||||||
const {
|
const {
|
||||||
return {.width = width_, .height = height_};
|
return output_resolution_.value_or(original_resolution_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t IvfVideoFrameGenerator::DecodedCallback::Decoded(
|
int32_t IvfVideoFrameGenerator::DecodedCallback::Decoded(
|
||||||
|
|||||||
@ -67,8 +67,13 @@ class IvfVideoFrameGenerator : public FrameGeneratorInterface {
|
|||||||
std::unique_ptr<IvfFileReader> file_reader_;
|
std::unique_ptr<IvfFileReader> file_reader_;
|
||||||
std::unique_ptr<VideoDecoder> video_decoder_;
|
std::unique_ptr<VideoDecoder> video_decoder_;
|
||||||
|
|
||||||
size_t width_;
|
// Resolution of IVF. Initially readed from IVF header and then set to
|
||||||
size_t height_;
|
// resolution of decoded frame.
|
||||||
|
Resolution original_resolution_;
|
||||||
|
// Resolution of output frames. When set, the decoded frames scaled to
|
||||||
|
// `output_resolution_`. Otherwise the decoded resolution, which may vary from
|
||||||
|
// frame to frame, is preserved.
|
||||||
|
std::optional<Resolution> output_resolution_;
|
||||||
std::optional<int> fps_hint_;
|
std::optional<int> fps_hint_;
|
||||||
|
|
||||||
// This lock is used to ensure that all API method will be called
|
// This lock is used to ensure that all API method will be called
|
||||||
|
|||||||
@ -221,5 +221,17 @@ TEST_F(IvfVideoFrameGeneratorTest, H264) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
TEST_F(IvfVideoFrameGeneratorTest, ScalesResolution) {
|
||||||
|
CreateTestVideoFile(VideoCodecType::kVideoCodecVP8, CreateVp8Encoder(env_));
|
||||||
|
IvfVideoFrameGenerator generator(env_, file_name_, /*fps_hint=*/123);
|
||||||
|
generator.ChangeResolution(kWidth * 2, kHeight / 2);
|
||||||
|
rtc::scoped_refptr<VideoFrameBuffer> frame_buffer =
|
||||||
|
generator.NextFrame().buffer;
|
||||||
|
frame_buffer = generator.NextFrame().buffer;
|
||||||
|
ASSERT_TRUE(frame_buffer);
|
||||||
|
EXPECT_EQ(frame_buffer->width(), kWidth * 2);
|
||||||
|
EXPECT_EQ(frame_buffer->height(), kHeight / 2);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace test
|
} // namespace test
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user