diff --git a/modules/video_coding/codecs/test/video_codec_test.cc b/modules/video_coding/codecs/test/video_codec_test.cc index e6767564e6..73d7df61d1 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 @@ ABSL_FLAG(std::string, "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, width, absl::nullopt, "Encode width."); +ABSL_FLAG(absl::optional, height, absl::nullopt, "Encode height."); ABSL_FLAG(std::vector, bitrate_kbps, {"1024"}, @@ -90,30 +93,19 @@ struct VideoInfo { Frequency framerate; }; -const std::map 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 @@ std::unique_ptr RunEncodeDecodeTest( const Environment& env, std::string encoder_impl, std::string decoder_impl, - const VideoInfo& video_info, + const VideoSourceSettings& source_settings, const std::map& 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 @@ std::unique_ptr RunEncodeTest( const Environment& env, std::string codec_type, std::string codec_impl, - const VideoInfo& video_info, + const VideoSourceSettings& source_settings, const std::map& 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 @@ TEST_P(SpatialQualityTest, SpatialQuality) { int duration_s = 10; int num_frames = duration_s * framerate_fps; + VideoSourceSettings source_settings = ToSourceSettings(video_info); + std::map frames_settings = VideoCodecTester::CreateEncodingSettings( codec_type, /*scalability_mode=*/"L1T1", width, height, {bitrate_kbps}, framerate_fps, num_frames); std::unique_ptr 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 @@ INSTANTIATE_TEST_SUITE_P( #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 @@ TEST_P(BitrateAdaptationTest, BitrateAdaptation) { int num_frames = static_cast(duration_s * video_info.framerate.hertz()); + VideoSourceSettings source_settings = ToSourceSettings(video_info); + std::map encoding_settings = VideoCodecTester::CreateEncodingSettings( codec_type, /*scalability_mode=*/"L1T1", @@ -421,8 +407,8 @@ TEST_P(BitrateAdaptationTest, BitrateAdaptation) { encoding_settings.merge(encoding_settings2); - std::unique_ptr stats = - RunEncodeTest(env, codec_type, codec_impl, video_info, encoding_settings); + std::unique_ptr stats = RunEncodeTest( + env, codec_type, codec_impl, source_settings, encoding_settings); VideoCodecStats::Stream stream; if (stats != nullptr) { @@ -445,18 +431,18 @@ TEST_P(BitrateAdaptationTest, BitrateAdaptation) { 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 encoding_settings = VideoCodecTester::CreateEncodingSettings( codec_type, /*scalability_mode=*/"L1T1", @@ -502,8 +490,8 @@ TEST_P(FramerateAdaptationTest, FramerateAdaptation) { encoding_settings.merge(encoding_settings2); - std::unique_ptr stats = - RunEncodeTest(env, codec_type, codec_impl, video_info, encoding_settings); + std::unique_ptr stats = RunEncodeTest( + env, codec_type, codec_impl, source_settings, encoding_settings); VideoCodecStats::Stream stream; if (stats != nullptr) { @@ -526,18 +514,17 @@ TEST_P(FramerateAdaptationTest, FramerateAdaptation) { 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 @@ TEST(VideoCodecTest, DISABLED_EncodeDecode) { CreateEnvironment(std::make_unique( 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(absl::GetFlag(FLAGS_input_framerate_fps))}; + std::vector bitrate_str = absl::GetFlag(FLAGS_bitrate_kbps); std::vector bitrate_kbps; std::transform(bitrate_str.begin(), bitrate_str.end(), @@ -558,9 +552,12 @@ TEST(VideoCodecTest, DISABLED_EncodeDecode) { std::map 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 @@ TEST(VideoCodecTest, DISABLED_EncodeDecode) { // Sync with changes in Stream::LogMetrics (see TODOs there). std::unique_ptr 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 180297f5c2..9f9491713f 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -1412,5 +1412,8 @@ rtc_library("video_codec_tester") { "//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 9baedfcedf..813fbdbb82 100644 --- a/test/video_codec_tester.cc +++ b/test/video_codec_tester.cc @@ -15,6 +15,7 @@ #include #include +#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 @@ class VideoSource { 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 @@ class LeakyBucket { 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.