diff --git a/api/test/create_frame_generator.cc b/api/test/create_frame_generator.cc index 2c57c12f50..ff93a1941d 100644 --- a/api/test/create_frame_generator.cc +++ b/api/test/create_frame_generator.cc @@ -75,8 +75,9 @@ std::unique_ptr CreateFromNV12FileFrameGenerator( absl::Nonnull> CreateFromIvfFileFrameGenerator(const Environment& env, - absl::string_view filename) { - return std::make_unique(env, filename); + absl::string_view filename, + std::optional fps_hint) { + return std::make_unique(env, filename, fps_hint); } std::unique_ptr diff --git a/api/test/create_frame_generator.h b/api/test/create_frame_generator.h index f9eba21ea4..c308e9535d 100644 --- a/api/test/create_frame_generator.h +++ b/api/test/create_frame_generator.h @@ -57,7 +57,8 @@ std::unique_ptr CreateFromNV12FileFrameGenerator( absl::Nonnull> CreateFromIvfFileFrameGenerator(const Environment& env, - absl::string_view filename); + absl::string_view filename, + std::optional fps_hint = std::nullopt); // Creates a frame generator which takes a set of yuv files (wrapping a // frame generator created by CreateFromYuvFile() above), but outputs frames diff --git a/test/testsupport/ivf_video_frame_generator.cc b/test/testsupport/ivf_video_frame_generator.cc index 5f4906e600..52989b1e04 100644 --- a/test/testsupport/ivf_video_frame_generator.cc +++ b/test/testsupport/ivf_video_frame_generator.cc @@ -53,12 +53,14 @@ std::unique_ptr CreateDecoder(const Environment& env, } // namespace IvfVideoFrameGenerator::IvfVideoFrameGenerator(const Environment& env, - absl::string_view file_name) + absl::string_view file_name, + std::optional fps_hint) : callback_(this), file_reader_(IvfFileReader::Create(FileWrapper::OpenReadOnly(file_name))), video_decoder_(CreateDecoder(env, file_reader_->GetVideoCodecType())), 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"; VideoDecoder::Settings decoder_settings; decoder_settings.set_codec_type(file_reader_->GetVideoCodecType()); diff --git a/test/testsupport/ivf_video_frame_generator.h b/test/testsupport/ivf_video_frame_generator.h index b91037e654..c5406f3333 100644 --- a/test/testsupport/ivf_video_frame_generator.h +++ b/test/testsupport/ivf_video_frame_generator.h @@ -32,7 +32,10 @@ namespace test { // All methods except constructor must be used from the same thread. class IvfVideoFrameGenerator : public FrameGeneratorInterface { 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 fps_hint); ~IvfVideoFrameGenerator() override; VideoFrameData NextFrame() override; @@ -40,7 +43,7 @@ class IvfVideoFrameGenerator : public FrameGeneratorInterface { void ChangeResolution(size_t width, size_t height) override; Resolution GetResolution() const override; - std::optional fps() const override { return std::nullopt; } + std::optional fps() const override { return fps_hint_; } private: class DecodedCallback : public DecodedImageCallback { @@ -66,6 +69,7 @@ class IvfVideoFrameGenerator : public FrameGeneratorInterface { size_t width_; size_t height_; + std::optional fps_hint_; // This lock is used to ensure that all API method will be called // sequentially. It is required because we need to ensure that generator diff --git a/test/testsupport/ivf_video_frame_generator_unittest.cc b/test/testsupport/ivf_video_frame_generator_unittest.cc index 0c83a93af4..db7cd8fad0 100644 --- a/test/testsupport/ivf_video_frame_generator_unittest.cc +++ b/test/testsupport/ivf_video_frame_generator_unittest.cc @@ -167,15 +167,21 @@ class IvfVideoFrameGeneratorTest : public ::testing::Test { } // namespace -TEST_F(IvfVideoFrameGeneratorTest, DoesNotKnowFps) { +TEST_F(IvfVideoFrameGeneratorTest, FpsWithoutHint) { 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); } +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) { 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) { auto& expected_frame = video_frames_[i]; VideoFrame actual_frame = BuildFrame(generator.NextFrame()); @@ -185,7 +191,7 @@ TEST_F(IvfVideoFrameGeneratorTest, Vp8) { TEST_F(IvfVideoFrameGeneratorTest, Vp8DoubleRead) { 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) { auto& expected_frame = video_frames_[i % video_frames_.size()]; VideoFrame actual_frame = BuildFrame(generator.NextFrame()); @@ -195,7 +201,7 @@ TEST_F(IvfVideoFrameGeneratorTest, Vp8DoubleRead) { TEST_F(IvfVideoFrameGeneratorTest, Vp9) { 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) { auto& expected_frame = video_frames_[i]; VideoFrame actual_frame = BuildFrame(generator.NextFrame()); @@ -206,7 +212,7 @@ TEST_F(IvfVideoFrameGeneratorTest, Vp9) { #if defined(WEBRTC_USE_H264) TEST_F(IvfVideoFrameGeneratorTest, H264) { 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) { auto& expected_frame = video_frames_[i]; VideoFrame actual_frame = BuildFrame(generator.NextFrame());