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}
This commit is contained in:
Sergey Silkin 2024-05-03 13:36:09 +00:00 committed by WebRTC LUCI CQ
parent 8b7d89a85f
commit 853e247fbb
3 changed files with 79 additions and 72 deletions

View file

@ -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<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 @@ struct VideoInfo {
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 @@ std::unique_ptr<VideoCodecStats> RunEncodeDecodeTest(
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 @@ std::unique_ptr<VideoCodecStats> RunEncodeTest(
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 @@ TEST_P(SpatialQualityTest, SpatialQuality) {
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 @@ 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<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 @@ TEST_P(BitrateAdaptationTest, BitrateAdaptation) {
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 @@ 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<std::tuple</*codec_type=*/std::string,
@ -481,6 +467,8 @@ TEST_P(FramerateAdaptationTest, FramerateAdaptation) {
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 @@ TEST_P(FramerateAdaptationTest, FramerateAdaptation) {
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 @@ 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<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 @@ TEST(VideoCodecTest, DISABLED_EncodeDecode) {
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 @@ TEST(VideoCodecTest, DISABLED_EncodeDecode) {
// 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.

View file

@ -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",
]
}

View file

@ -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 @@ 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.