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}
diff --git a/api/test/create_frame_generator.cc b/api/test/create_frame_generator.cc
index 2c57c12..ff93a19 100644
--- a/api/test/create_frame_generator.cc
+++ b/api/test/create_frame_generator.cc
@@ -75,8 +75,9 @@
 
 absl::Nonnull<std::unique_ptr<FrameGeneratorInterface>>
 CreateFromIvfFileFrameGenerator(const Environment& env,
-                                absl::string_view filename) {
-  return std::make_unique<IvfVideoFrameGenerator>(env, filename);
+                                absl::string_view filename,
+                                std::optional<int> fps_hint) {
+  return std::make_unique<IvfVideoFrameGenerator>(env, filename, fps_hint);
 }
 
 std::unique_ptr<FrameGeneratorInterface>
diff --git a/api/test/create_frame_generator.h b/api/test/create_frame_generator.h
index f9eba21..c308e95 100644
--- a/api/test/create_frame_generator.h
+++ b/api/test/create_frame_generator.h
@@ -57,7 +57,8 @@
 
 absl::Nonnull<std::unique_ptr<FrameGeneratorInterface>>
 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
 // 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 5f4906e..52989b1 100644
--- a/test/testsupport/ivf_video_frame_generator.cc
+++ b/test/testsupport/ivf_video_frame_generator.cc
@@ -53,12 +53,14 @@
 }  // namespace
 
 IvfVideoFrameGenerator::IvfVideoFrameGenerator(const Environment& env,
-                                               absl::string_view file_name)
+                                               absl::string_view file_name,
+                                               std::optional<int> 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 b91037e..c5406f3 100644
--- a/test/testsupport/ivf_video_frame_generator.h
+++ b/test/testsupport/ivf_video_frame_generator.h
@@ -32,7 +32,10 @@
 // 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<int> fps_hint);
   ~IvfVideoFrameGenerator() override;
 
   VideoFrameData NextFrame() override;
@@ -40,7 +43,7 @@
   void ChangeResolution(size_t width, size_t height) override;
   Resolution GetResolution() const override;
 
-  std::optional<int> fps() const override { return std::nullopt; }
+  std::optional<int> fps() const override { return fps_hint_; }
 
  private:
   class DecodedCallback : public DecodedImageCallback {
@@ -66,6 +69,7 @@
 
   size_t width_;
   size_t height_;
+  std::optional<int> 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 0c83a93..db7cd8f 100644
--- a/test/testsupport/ivf_video_frame_generator_unittest.cc
+++ b/test/testsupport/ivf_video_frame_generator_unittest.cc
@@ -167,15 +167,21 @@
 
 }  // 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, 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, 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 @@
 #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());