Allow to specify a 'fps_hint' when creating a IvfVideoFrameGenerator.
Change-Id: Id75694f9dccfa6523f383e03dd90067fb6894b37 Bug: b/378855419 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/368162 Commit-Queue: Jeremy Leconte <jleconte@webrtc.org> Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43395}
This commit is contained in:
parent
4c171e84c3
commit
90da0650b5
@ -75,8 +75,9 @@ std::unique_ptr<FrameGeneratorInterface> CreateFromNV12FileFrameGenerator(
|
|||||||
|
|
||||||
absl::Nonnull<std::unique_ptr<FrameGeneratorInterface>>
|
absl::Nonnull<std::unique_ptr<FrameGeneratorInterface>>
|
||||||
CreateFromIvfFileFrameGenerator(const Environment& env,
|
CreateFromIvfFileFrameGenerator(const Environment& env,
|
||||||
absl::string_view filename) {
|
absl::string_view filename,
|
||||||
return std::make_unique<IvfVideoFrameGenerator>(env, filename);
|
std::optional<int> fps_hint) {
|
||||||
|
return std::make_unique<IvfVideoFrameGenerator>(env, filename, fps_hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<FrameGeneratorInterface>
|
std::unique_ptr<FrameGeneratorInterface>
|
||||||
|
|||||||
@ -57,7 +57,8 @@ std::unique_ptr<FrameGeneratorInterface> CreateFromNV12FileFrameGenerator(
|
|||||||
|
|
||||||
absl::Nonnull<std::unique_ptr<FrameGeneratorInterface>>
|
absl::Nonnull<std::unique_ptr<FrameGeneratorInterface>>
|
||||||
CreateFromIvfFileFrameGenerator(const Environment& env,
|
CreateFromIvfFileFrameGenerator(const Environment& env,
|
||||||
absl::string_view filename);
|
absl::string_view filename,
|
||||||
|
std::optional<int> fps_hint = std::nullopt);
|
||||||
|
|
||||||
// Creates a frame generator which takes a set of yuv files (wrapping a
|
// Creates a frame generator which takes a set of yuv files (wrapping a
|
||||||
// frame generator created by CreateFromYuvFile() above), but outputs frames
|
// frame generator created by CreateFromYuvFile() above), but outputs frames
|
||||||
|
|||||||
@ -53,12 +53,14 @@ std::unique_ptr<VideoDecoder> CreateDecoder(const Environment& env,
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
IvfVideoFrameGenerator::IvfVideoFrameGenerator(const Environment& env,
|
IvfVideoFrameGenerator::IvfVideoFrameGenerator(const Environment& env,
|
||||||
absl::string_view file_name)
|
absl::string_view file_name,
|
||||||
|
std::optional<int> fps_hint)
|
||||||
: 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()),
|
width_(file_reader_->GetFrameWidth()),
|
||||||
height_(file_reader_->GetFrameHeight()) {
|
height_(file_reader_->GetFrameHeight()),
|
||||||
|
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;
|
||||||
decoder_settings.set_codec_type(file_reader_->GetVideoCodecType());
|
decoder_settings.set_codec_type(file_reader_->GetVideoCodecType());
|
||||||
|
|||||||
@ -32,7 +32,10 @@ namespace test {
|
|||||||
// All methods except constructor must be used from the same thread.
|
// All methods except constructor must be used from the same thread.
|
||||||
class IvfVideoFrameGenerator : public FrameGeneratorInterface {
|
class IvfVideoFrameGenerator : public FrameGeneratorInterface {
|
||||||
public:
|
public:
|
||||||
IvfVideoFrameGenerator(const Environment& env, absl::string_view file_name);
|
// Allow to specify a `fps_hint` in case the fps of the video is known.
|
||||||
|
IvfVideoFrameGenerator(const Environment& env,
|
||||||
|
absl::string_view file_name,
|
||||||
|
std::optional<int> fps_hint);
|
||||||
~IvfVideoFrameGenerator() override;
|
~IvfVideoFrameGenerator() override;
|
||||||
|
|
||||||
VideoFrameData NextFrame() override;
|
VideoFrameData NextFrame() override;
|
||||||
@ -40,7 +43,7 @@ class IvfVideoFrameGenerator : public FrameGeneratorInterface {
|
|||||||
void ChangeResolution(size_t width, size_t height) override;
|
void ChangeResolution(size_t width, size_t height) override;
|
||||||
Resolution GetResolution() const override;
|
Resolution GetResolution() const override;
|
||||||
|
|
||||||
std::optional<int> fps() const override { return std::nullopt; }
|
std::optional<int> fps() const override { return fps_hint_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class DecodedCallback : public DecodedImageCallback {
|
class DecodedCallback : public DecodedImageCallback {
|
||||||
@ -66,6 +69,7 @@ class IvfVideoFrameGenerator : public FrameGeneratorInterface {
|
|||||||
|
|
||||||
size_t width_;
|
size_t width_;
|
||||||
size_t height_;
|
size_t height_;
|
||||||
|
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
|
||||||
// sequentially. It is required because we need to ensure that generator
|
// sequentially. It is required because we need to ensure that generator
|
||||||
|
|||||||
@ -167,15 +167,21 @@ class IvfVideoFrameGeneratorTest : public ::testing::Test {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TEST_F(IvfVideoFrameGeneratorTest, DoesNotKnowFps) {
|
TEST_F(IvfVideoFrameGeneratorTest, FpsWithoutHint) {
|
||||||
CreateTestVideoFile(VideoCodecType::kVideoCodecVP8, CreateVp8Encoder(env_));
|
CreateTestVideoFile(VideoCodecType::kVideoCodecVP8, CreateVp8Encoder(env_));
|
||||||
IvfVideoFrameGenerator generator(env_, file_name_);
|
IvfVideoFrameGenerator generator(env_, file_name_, /*fps_hint=*/std::nullopt);
|
||||||
EXPECT_EQ(generator.fps(), std::nullopt);
|
EXPECT_EQ(generator.fps(), std::nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(IvfVideoFrameGeneratorTest, FpsWithHint) {
|
||||||
|
CreateTestVideoFile(VideoCodecType::kVideoCodecVP8, CreateVp8Encoder(env_));
|
||||||
|
IvfVideoFrameGenerator generator(env_, file_name_, /*fps_hint=*/123);
|
||||||
|
EXPECT_EQ(generator.fps(), 123);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(IvfVideoFrameGeneratorTest, Vp8) {
|
TEST_F(IvfVideoFrameGeneratorTest, Vp8) {
|
||||||
CreateTestVideoFile(VideoCodecType::kVideoCodecVP8, CreateVp8Encoder(env_));
|
CreateTestVideoFile(VideoCodecType::kVideoCodecVP8, CreateVp8Encoder(env_));
|
||||||
IvfVideoFrameGenerator generator(env_, file_name_);
|
IvfVideoFrameGenerator generator(env_, file_name_, /*fps_hint=*/std::nullopt);
|
||||||
for (size_t i = 0; i < video_frames_.size(); ++i) {
|
for (size_t i = 0; i < video_frames_.size(); ++i) {
|
||||||
auto& expected_frame = video_frames_[i];
|
auto& expected_frame = video_frames_[i];
|
||||||
VideoFrame actual_frame = BuildFrame(generator.NextFrame());
|
VideoFrame actual_frame = BuildFrame(generator.NextFrame());
|
||||||
@ -185,7 +191,7 @@ TEST_F(IvfVideoFrameGeneratorTest, Vp8) {
|
|||||||
|
|
||||||
TEST_F(IvfVideoFrameGeneratorTest, Vp8DoubleRead) {
|
TEST_F(IvfVideoFrameGeneratorTest, Vp8DoubleRead) {
|
||||||
CreateTestVideoFile(VideoCodecType::kVideoCodecVP8, CreateVp8Encoder(env_));
|
CreateTestVideoFile(VideoCodecType::kVideoCodecVP8, CreateVp8Encoder(env_));
|
||||||
IvfVideoFrameGenerator generator(env_, file_name_);
|
IvfVideoFrameGenerator generator(env_, file_name_, /*fps_hint=*/std::nullopt);
|
||||||
for (size_t i = 0; i < video_frames_.size() * 2; ++i) {
|
for (size_t i = 0; i < video_frames_.size() * 2; ++i) {
|
||||||
auto& expected_frame = video_frames_[i % video_frames_.size()];
|
auto& expected_frame = video_frames_[i % video_frames_.size()];
|
||||||
VideoFrame actual_frame = BuildFrame(generator.NextFrame());
|
VideoFrame actual_frame = BuildFrame(generator.NextFrame());
|
||||||
@ -195,7 +201,7 @@ TEST_F(IvfVideoFrameGeneratorTest, Vp8DoubleRead) {
|
|||||||
|
|
||||||
TEST_F(IvfVideoFrameGeneratorTest, Vp9) {
|
TEST_F(IvfVideoFrameGeneratorTest, Vp9) {
|
||||||
CreateTestVideoFile(VideoCodecType::kVideoCodecVP9, CreateVp9Encoder(env_));
|
CreateTestVideoFile(VideoCodecType::kVideoCodecVP9, CreateVp9Encoder(env_));
|
||||||
IvfVideoFrameGenerator generator(env_, file_name_);
|
IvfVideoFrameGenerator generator(env_, file_name_, /*fps_hint=*/std::nullopt);
|
||||||
for (size_t i = 0; i < video_frames_.size(); ++i) {
|
for (size_t i = 0; i < video_frames_.size(); ++i) {
|
||||||
auto& expected_frame = video_frames_[i];
|
auto& expected_frame = video_frames_[i];
|
||||||
VideoFrame actual_frame = BuildFrame(generator.NextFrame());
|
VideoFrame actual_frame = BuildFrame(generator.NextFrame());
|
||||||
@ -206,7 +212,7 @@ TEST_F(IvfVideoFrameGeneratorTest, Vp9) {
|
|||||||
#if defined(WEBRTC_USE_H264)
|
#if defined(WEBRTC_USE_H264)
|
||||||
TEST_F(IvfVideoFrameGeneratorTest, H264) {
|
TEST_F(IvfVideoFrameGeneratorTest, H264) {
|
||||||
CreateTestVideoFile(VideoCodecType::kVideoCodecH264, CreateH264Encoder(env_));
|
CreateTestVideoFile(VideoCodecType::kVideoCodecH264, CreateH264Encoder(env_));
|
||||||
IvfVideoFrameGenerator generator(env_, file_name_);
|
IvfVideoFrameGenerator generator(env_, file_name_, /*fps_hint=*/std::nullopt);
|
||||||
for (size_t i = 0; i < video_frames_.size(); ++i) {
|
for (size_t i = 0; i < video_frames_.size(); ++i) {
|
||||||
auto& expected_frame = video_frames_[i];
|
auto& expected_frame = video_frames_[i];
|
||||||
VideoFrame actual_frame = BuildFrame(generator.NextFrame());
|
VideoFrame actual_frame = BuildFrame(generator.NextFrame());
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user