Set full path to input video in EncodeDecode test

Replaced --video_name with --input_path, --input_width, --input_height and --input_framerate_fps.

Example of command line:
video_codec_perf_tests --input_width=1920 --input_height=1080 --input_framerate_fps=30 --input_path="/full/path/sample.yuv"

Also added y4m source support to the codec tester.

Bug: b/42225151, b/337757868
Change-Id: Ic399b3e819a126e097072c27d74a5fcc0dc1fe6d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/349581
Commit-Queue: Sergey Silkin <ssilkin@webrtc.org>
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42226}
diff --git a/modules/video_coding/codecs/test/video_codec_test.cc b/modules/video_coding/codecs/test/video_codec_test.cc
index e676756..73d7df6 100644
--- a/modules/video_coding/codecs/test/video_codec_test.cc
+++ b/modules/video_coding/codecs/test/video_codec_test.cc
@@ -36,9 +36,12 @@
 #include "test/video_codec_tester.h"
 
 ABSL_FLAG(std::string,
-          video_name,
-          "FourPeople_1280x720_30",
-          "Name of input video sequence.");
+          input_path,
+          webrtc::test::ResourcePath("FourPeople_1280x720_30", "yuv"),
+          "Path to input video file.");
+ABSL_FLAG(int, input_width, 1280, "Input video width.");
+ABSL_FLAG(int, input_height, 720, "Input video height.");
+ABSL_FLAG(double, input_framerate_fps, 30, "Input video framerate, fps.");
 ABSL_FLAG(std::string,
           encoder,
           "libaom-av1",
@@ -50,8 +53,8 @@
           "Decoder: dav1d, libvpx-vp9, libvpx-vp8, ffmpeg-h264, hw-vp8, "
           "hw-vp9, hw-av1, hw-h264, hw-h265");
 ABSL_FLAG(std::string, scalability_mode, "L1T1", "Scalability mode.");
-ABSL_FLAG(int, width, 1280, "Width.");
-ABSL_FLAG(int, height, 720, "Height.");
+ABSL_FLAG(absl::optional<int>, width, absl::nullopt, "Encode width.");
+ABSL_FLAG(absl::optional<int>, height, absl::nullopt, "Encode height.");
 ABSL_FLAG(std::vector<std::string>,
           bitrate_kbps,
           {"1024"},
@@ -90,30 +93,19 @@
   Frequency framerate;
 };
 
-const std::map<std::string, VideoInfo> kRawVideos = {
-    {"FourPeople_1280x720_30",
-     {.name = "FourPeople_1280x720_30",
-      .resolution = {.width = 1280, .height = 720},
-      .framerate = Frequency::Hertz(30)}},
-    {"vidyo1_1280x720_30",
-     {.name = "vidyo1_1280x720_30",
-      .resolution = {.width = 1280, .height = 720},
-      .framerate = Frequency::Hertz(30)}},
-    {"vidyo4_1280x720_30",
-     {.name = "vidyo4_1280x720_30",
-      .resolution = {.width = 1280, .height = 720},
-      .framerate = Frequency::Hertz(30)}},
-    {"KristenAndSara_1280x720_30",
-     {.name = "KristenAndSara_1280x720_30",
-      .resolution = {.width = 1280, .height = 720},
-      .framerate = Frequency::Hertz(30)}},
-    {"Johnny_1280x720_30",
-     {.name = "Johnny_1280x720_30",
-      .resolution = {.width = 1280, .height = 720},
-      .framerate = Frequency::Hertz(30)}}};
+VideoInfo kFourPeople_1280x720_30 = {
+    .name = "FourPeople_1280x720_30",
+    .resolution = {.width = 1280, .height = 720},
+    .framerate = Frequency::Hertz(30)};
 
 static constexpr Frequency k90kHz = Frequency::Hertz(90000);
 
+VideoSourceSettings ToSourceSettings(VideoInfo video_info) {
+  return VideoSourceSettings{.file_path = ResourcePath(video_info.name, "yuv"),
+                             .resolution = video_info.resolution,
+                             .framerate = video_info.framerate};
+}
+
 std::string CodecNameToCodecType(std::string name) {
   if (name.find("av1") != std::string::npos) {
     return "AV1";
@@ -188,13 +180,8 @@
     const Environment& env,
     std::string encoder_impl,
     std::string decoder_impl,
-    const VideoInfo& video_info,
+    const VideoSourceSettings& source_settings,
     const std::map<uint32_t, EncodingSettings>& encoding_settings) {
-  VideoSourceSettings source_settings{
-      .file_path = ResourcePath(video_info.name, "yuv"),
-      .resolution = video_info.resolution,
-      .framerate = video_info.framerate};
-
   const SdpVideoFormat& sdp_video_format =
       encoding_settings.begin()->second.sdp_video_format;
 
@@ -263,13 +250,8 @@
     const Environment& env,
     std::string codec_type,
     std::string codec_impl,
-    const VideoInfo& video_info,
+    const VideoSourceSettings& source_settings,
     const std::map<uint32_t, EncodingSettings>& encoding_settings) {
-  VideoSourceSettings source_settings{
-      .file_path = ResourcePath(video_info.name, "yuv"),
-      .resolution = video_info.resolution,
-      .framerate = video_info.framerate};
-
   const SdpVideoFormat& sdp_video_format =
       encoding_settings.begin()->second.sdp_video_format;
 
@@ -330,13 +312,15 @@
   int duration_s = 10;
   int num_frames = duration_s * framerate_fps;
 
+  VideoSourceSettings source_settings = ToSourceSettings(video_info);
+
   std::map<uint32_t, EncodingSettings> frames_settings =
       VideoCodecTester::CreateEncodingSettings(
           codec_type, /*scalability_mode=*/"L1T1", width, height,
           {bitrate_kbps}, framerate_fps, num_frames);
 
   std::unique_ptr<VideoCodecStats> stats = RunEncodeDecodeTest(
-      env, codec_impl, codec_impl, video_info, frames_settings);
+      env, codec_impl, codec_impl, source_settings, frames_settings);
 
   VideoCodecStats::Stream stream;
   if (stats != nullptr) {
@@ -365,7 +349,7 @@
 #else
             Values("builtin"),
 #endif
-            Values(kRawVideos.at("FourPeople_1280x720_30")),
+            Values(kFourPeople_1280x720_30),
             Values(std::make_tuple(320, 180, 30, 32, 26),
                    std::make_tuple(320, 180, 30, 64, 29),
                    std::make_tuple(320, 180, 30, 128, 32),
@@ -404,6 +388,8 @@
   int num_frames =
       static_cast<int>(duration_s * video_info.framerate.hertz<double>());
 
+  VideoSourceSettings source_settings = ToSourceSettings(video_info);
+
   std::map<uint32_t, EncodingSettings> encoding_settings =
       VideoCodecTester::CreateEncodingSettings(
           codec_type, /*scalability_mode=*/"L1T1",
@@ -421,8 +407,8 @@
 
   encoding_settings.merge(encoding_settings2);
 
-  std::unique_ptr<VideoCodecStats> stats =
-      RunEncodeTest(env, codec_type, codec_impl, video_info, encoding_settings);
+  std::unique_ptr<VideoCodecStats> stats = RunEncodeTest(
+      env, codec_type, codec_impl, source_settings, encoding_settings);
 
   VideoCodecStats::Stream stream;
   if (stats != nullptr) {
@@ -445,18 +431,18 @@
                             std::to_string(bitrate_kbps.second)}});
 }
 
-INSTANTIATE_TEST_SUITE_P(
-    All,
-    BitrateAdaptationTest,
-    Combine(Values("AV1", "VP9", "VP8", "H264", "H265"),
+INSTANTIATE_TEST_SUITE_P(All,
+                         BitrateAdaptationTest,
+                         Combine(Values("AV1", "VP9", "VP8", "H264", "H265"),
 #if defined(WEBRTC_ANDROID)
-            Values("builtin", "mediacodec"),
+                                 Values("builtin", "mediacodec"),
 #else
-            Values("builtin"),
+                                 Values("builtin"),
 #endif
-            Values(kRawVideos.at("FourPeople_1280x720_30")),
-            Values(std::pair(1024, 512), std::pair(512, 1024))),
-    BitrateAdaptationTest::TestParamsToString);
+                                 Values(kFourPeople_1280x720_30),
+                                 Values(std::pair(1024, 512),
+                                        std::pair(512, 1024))),
+                         BitrateAdaptationTest::TestParamsToString);
 
 class FramerateAdaptationTest
     : public ::testing::TestWithParam<std::tuple</*codec_type=*/std::string,
@@ -481,6 +467,8 @@
 
   int duration_s = 10;  // Duration of fixed rate interval.
 
+  VideoSourceSettings source_settings = ToSourceSettings(video_info);
+
   std::map<uint32_t, EncodingSettings> encoding_settings =
       VideoCodecTester::CreateEncodingSettings(
           codec_type, /*scalability_mode=*/"L1T1",
@@ -502,8 +490,8 @@
 
   encoding_settings.merge(encoding_settings2);
 
-  std::unique_ptr<VideoCodecStats> stats =
-      RunEncodeTest(env, codec_type, codec_impl, video_info, encoding_settings);
+  std::unique_ptr<VideoCodecStats> stats = RunEncodeTest(
+      env, codec_type, codec_impl, source_settings, encoding_settings);
 
   VideoCodecStats::Stream stream;
   if (stats != nullptr) {
@@ -526,18 +514,17 @@
                             std::to_string(framerate_fps.second)}});
 }
 
-INSTANTIATE_TEST_SUITE_P(
-    All,
-    FramerateAdaptationTest,
-    Combine(Values("AV1", "VP9", "VP8", "H264", "H265"),
+INSTANTIATE_TEST_SUITE_P(All,
+                         FramerateAdaptationTest,
+                         Combine(Values("AV1", "VP9", "VP8", "H264", "H265"),
 #if defined(WEBRTC_ANDROID)
-            Values("builtin", "mediacodec"),
+                                 Values("builtin", "mediacodec"),
 #else
-            Values("builtin"),
+                                 Values("builtin"),
 #endif
-            Values(kRawVideos.at("FourPeople_1280x720_30")),
-            Values(std::pair(30, 15), std::pair(15, 30))),
-    FramerateAdaptationTest::TestParamsToString);
+                                 Values(kFourPeople_1280x720_30),
+                                 Values(std::pair(30, 15), std::pair(15, 30))),
+                         FramerateAdaptationTest::TestParamsToString);
 
 TEST(VideoCodecTest, DISABLED_EncodeDecode) {
   ScopedFieldTrials field_trials(absl::GetFlag(FLAGS_field_trials));
@@ -545,6 +532,13 @@
       CreateEnvironment(std::make_unique<ExplicitKeyValueConfig>(
           absl::GetFlag(FLAGS_field_trials)));
 
+  VideoSourceSettings source_settings{
+      .file_path = absl::GetFlag(FLAGS_input_path),
+      .resolution = {.width = absl::GetFlag(FLAGS_input_width),
+                     .height = absl::GetFlag(FLAGS_input_height)},
+      .framerate =
+          Frequency::Hertz<double>(absl::GetFlag(FLAGS_input_framerate_fps))};
+
   std::vector<std::string> bitrate_str = absl::GetFlag(FLAGS_bitrate_kbps);
   std::vector<int> bitrate_kbps;
   std::transform(bitrate_str.begin(), bitrate_str.end(),
@@ -558,9 +552,12 @@
   std::map<uint32_t, EncodingSettings> frames_settings =
       VideoCodecTester::CreateEncodingSettings(
           CodecNameToCodecType(absl::GetFlag(FLAGS_encoder)),
-          absl::GetFlag(FLAGS_scalability_mode), absl::GetFlag(FLAGS_width),
-          absl::GetFlag(FLAGS_height), {bitrate_kbps},
-          absl::GetFlag(FLAGS_framerate_fps), absl::GetFlag(FLAGS_num_frames),
+          absl::GetFlag(FLAGS_scalability_mode),
+          absl::GetFlag(FLAGS_width).value_or(absl::GetFlag(FLAGS_input_width)),
+          absl::GetFlag(FLAGS_height)
+              .value_or(absl::GetFlag(FLAGS_input_height)),
+          {bitrate_kbps}, absl::GetFlag(FLAGS_framerate_fps),
+          absl::GetFlag(FLAGS_num_frames),
           /*first_timestamp_rtp=*/90000, content_type,
           absl::GetFlag(FLAGS_frame_drop));
 
@@ -569,8 +566,8 @@
   // Sync with changes in Stream::LogMetrics (see TODOs there).
   std::unique_ptr<VideoCodecStats> stats = RunEncodeDecodeTest(
       env, CodecNameToCodecImpl(absl::GetFlag(FLAGS_encoder)),
-      CodecNameToCodecImpl(absl::GetFlag(FLAGS_decoder)),
-      kRawVideos.at(absl::GetFlag(FLAGS_video_name)), frames_settings);
+      CodecNameToCodecImpl(absl::GetFlag(FLAGS_decoder)), source_settings,
+      frames_settings);
   ASSERT_NE(nullptr, stats);
 
   // Log unsliced metrics.
diff --git a/test/BUILD.gn b/test/BUILD.gn
index 180297f..9f94917 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -1412,5 +1412,8 @@
     "//third_party/libyuv",
   ]
 
-  absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+  absl_deps = [
+    "//third_party/abseil-cpp/absl/strings:strings",
+    "//third_party/abseil-cpp/absl/types:optional",
+  ]
 }
diff --git a/test/video_codec_tester.cc b/test/video_codec_tester.cc
index 9baedfc..813fbdb 100644
--- a/test/video_codec_tester.cc
+++ b/test/video_codec_tester.cc
@@ -15,6 +15,7 @@
 #include <tuple>
 #include <utility>
 
+#include "absl/strings/match.h"
 #include "api/array_view.h"
 #include "api/environment/environment.h"
 #include "api/units/time_delta.h"
@@ -88,9 +89,15 @@
   explicit VideoSource(VideoSourceSettings source_settings)
       : source_settings_(source_settings) {
     MutexLock lock(&mutex_);
-    frame_reader_ = CreateYuvFrameReader(
-        source_settings_.file_path, source_settings_.resolution,
-        YuvFrameReaderImpl::RepeatMode::kPingPong);
+    if (absl::EndsWith(source_settings.file_path, "y4m")) {
+      frame_reader_ =
+          CreateY4mFrameReader(source_settings_.file_path,
+                               YuvFrameReaderImpl::RepeatMode::kPingPong);
+    } else {
+      frame_reader_ = CreateYuvFrameReader(
+          source_settings_.file_path, source_settings_.resolution,
+          YuvFrameReaderImpl::RepeatMode::kPingPong);
+    }
     RTC_CHECK(frame_reader_);
   }
 
@@ -298,7 +305,7 @@
  public:
   LeakyBucket() : level_bits_(0) {}
 
-  // Updates bucket level and returns its current level in bits. Data is remove
+  // Updates bucket level and returns its current level in bits. Data is removed
   // from bucket with rate equal to target bitrate of previous frame. Bucket
   // level is tracked with floating point precision. Returned value of bucket
   // level is rounded up.