Merge "L2E: Make SimpleEncode take vp9 level as an input" into main

This commit is contained in:
Cheng Chen
2022-04-05 18:25:23 +00:00
committed by Gerrit Code Review
5 changed files with 62 additions and 32 deletions

View File

@@ -37,13 +37,14 @@ class SimpleEncodeTest : public ::testing::Test {
const int frame_rate_den_ = 1;
const int target_bitrate_ = 1000;
const int num_frames_ = 17;
const int target_level_ = LEVEL_UNKNOWN;
const std::string in_file_path_str_ =
libvpx_test::GetDataPath() + "/bus_352x288_420_f20_b8.yuv";
};
TEST_F(SimpleEncodeTest, ComputeFirstPassStats) {
SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
target_bitrate_, num_frames_,
target_bitrate_, num_frames_, target_level_,
in_file_path_str_.c_str());
simple_encode.ComputeFirstPassStats();
std::vector<std::vector<double>> frame_stats =
@@ -64,7 +65,7 @@ TEST_F(SimpleEncodeTest, ComputeFirstPassStats) {
TEST_F(SimpleEncodeTest, ObserveFirstPassMotionVectors) {
SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
target_bitrate_, num_frames_,
target_bitrate_, num_frames_, target_level_,
in_file_path_str_.c_str());
simple_encode.ComputeFirstPassStats();
std::vector<std::vector<MotionVectorInfo>> fps_motion_vectors =
@@ -86,7 +87,7 @@ TEST_F(SimpleEncodeTest, ObserveFirstPassMotionVectors) {
TEST_F(SimpleEncodeTest, GetCodingFrameNum) {
SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
target_bitrate_, num_frames_,
target_bitrate_, num_frames_, target_level_,
in_file_path_str_.c_str());
simple_encode.ComputeFirstPassStats();
const int num_coding_frames = simple_encode.GetCodingFrameNum();
@@ -95,7 +96,7 @@ TEST_F(SimpleEncodeTest, GetCodingFrameNum) {
TEST_F(SimpleEncodeTest, EncodeFrame) {
SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
target_bitrate_, num_frames_,
target_bitrate_, num_frames_, target_level_,
in_file_path_str_.c_str());
simple_encode.ComputeFirstPassStats();
int num_coding_frames = simple_encode.GetCodingFrameNum();
@@ -138,7 +139,7 @@ TEST_F(SimpleEncodeTest, EncodeFrame) {
TEST_F(SimpleEncodeTest, ObserveKeyFrameMap) {
SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
target_bitrate_, num_frames_,
target_bitrate_, num_frames_, target_level_,
in_file_path_str_.c_str());
simple_encode.ComputeFirstPassStats();
std::vector<int> key_frame_map = simple_encode.ObserveKeyFrameMap();
@@ -167,7 +168,7 @@ TEST_F(SimpleEncodeTest, ObserveKeyFrameMap) {
TEST_F(SimpleEncodeTest, EncodeFrameWithTargetFrameBits) {
SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
target_bitrate_, num_frames_,
target_bitrate_, num_frames_, target_level_,
in_file_path_str_.c_str());
simple_encode.ComputeFirstPassStats();
const int num_coding_frames = simple_encode.GetCodingFrameNum();
@@ -205,7 +206,7 @@ TEST_F(SimpleEncodeTest, EncodeFrameWithTargetFrameBits) {
TEST_F(SimpleEncodeTest, EncodeFrameWithQuantizeIndex) {
SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
target_bitrate_, num_frames_,
target_bitrate_, num_frames_, target_level_,
in_file_path_str_.c_str());
simple_encode.ComputeFirstPassStats();
const int num_coding_frames = simple_encode.GetCodingFrameNum();
@@ -237,7 +238,7 @@ TEST_F(SimpleEncodeTest, EncodeConsistencyTest) {
// The first encode.
SimpleEncode simple_encode(width_, height_, frame_rate_num_,
frame_rate_den_, target_bitrate_, num_frames_,
in_file_path_str_.c_str());
target_level_, in_file_path_str_.c_str());
simple_encode.ComputeFirstPassStats();
const int num_coding_frames = simple_encode.GetCodingFrameNum();
simple_encode.StartEncode();
@@ -257,7 +258,7 @@ TEST_F(SimpleEncodeTest, EncodeConsistencyTest) {
// The second encode with quantize index got from the first encode.
SimpleEncode simple_encode(width_, height_, frame_rate_num_,
frame_rate_den_, target_bitrate_, num_frames_,
in_file_path_str_.c_str());
target_level_, in_file_path_str_.c_str());
simple_encode.ComputeFirstPassStats();
const int num_coding_frames = simple_encode.GetCodingFrameNum();
EXPECT_EQ(static_cast<size_t>(num_coding_frames),
@@ -286,7 +287,7 @@ TEST_F(SimpleEncodeTest, EncodeConsistencyTest2) {
const int num_units_4x4 = num_rows_4x4 * num_cols_4x4;
// The first encode.
SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
target_bitrate_, num_frames_,
target_bitrate_, num_frames_, target_level_,
in_file_path_str_.c_str());
simple_encode.ComputeFirstPassStats();
const int num_coding_frames = simple_encode.GetCodingFrameNum();
@@ -309,7 +310,7 @@ TEST_F(SimpleEncodeTest, EncodeConsistencyTest2) {
// The second encode.
SimpleEncode simple_encode_2(width_, height_, frame_rate_num_,
frame_rate_den_, target_bitrate_, num_frames_,
in_file_path_str_.c_str());
target_level_, in_file_path_str_.c_str());
simple_encode_2.ComputeFirstPassStats();
const int num_coding_frames_2 = simple_encode_2.GetCodingFrameNum();
simple_encode_2.StartEncode();
@@ -357,7 +358,7 @@ TEST_F(SimpleEncodeTest, EncodeConsistencyTest3) {
const int num_units_4x4 = num_rows_4x4 * num_cols_4x4;
// The first encode.
SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
target_bitrate_, num_frames_,
target_bitrate_, num_frames_, target_level_,
in_file_path_str_.c_str());
simple_encode.ComputeFirstPassStats();
const int num_coding_frames = simple_encode.GetCodingFrameNum();
@@ -377,7 +378,7 @@ TEST_F(SimpleEncodeTest, EncodeConsistencyTest3) {
// The second encode.
SimpleEncode simple_encode_2(width_, height_, frame_rate_num_,
frame_rate_den_, target_bitrate_, num_frames_,
in_file_path_str_.c_str());
target_level_, in_file_path_str_.c_str());
simple_encode_2.ComputeFirstPassStats();
const int num_coding_frames_2 = simple_encode_2.GetCodingFrameNum();
simple_encode_2.StartEncode();
@@ -417,7 +418,7 @@ TEST_F(SimpleEncodeTest, EncodeConsistencySetExternalGroupOfPicturesMap) {
// The first encode.
SimpleEncode simple_encode(width_, height_, frame_rate_num_,
frame_rate_den_, target_bitrate_, num_frames_,
in_file_path_str_.c_str());
target_level_, in_file_path_str_.c_str());
simple_encode.ComputeFirstPassStats();
simple_encode.StartEncode();
@@ -449,7 +450,7 @@ TEST_F(SimpleEncodeTest, EncodeConsistencySetExternalGroupOfPicturesMap) {
// The external arfs are the same as the first encode.
SimpleEncode simple_encode(width_, height_, frame_rate_num_,
frame_rate_den_, target_bitrate_, num_frames_,
in_file_path_str_.c_str());
target_level_, in_file_path_str_.c_str());
simple_encode.ComputeFirstPassStats();
simple_encode.SetExternalGroupOfPicturesMap(gop_map.data(), gop_map.size());
const int num_coding_frames = simple_encode.GetCodingFrameNum();
@@ -471,7 +472,7 @@ TEST_F(SimpleEncodeTest, EncodeConsistencySetExternalGroupOfPicturesMap) {
TEST_F(SimpleEncodeTest, SetExternalGroupOfPicturesMap) {
SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
target_bitrate_, num_frames_,
target_bitrate_, num_frames_, target_level_,
in_file_path_str_.c_str());
simple_encode.ComputeFirstPassStats();
@@ -541,7 +542,7 @@ TEST_F(SimpleEncodeTest, GetEncodeFrameInfo) {
// Makes sure that the encode_frame_info obtained from GetEncodeFrameInfo()
// matches the counterpart in encode_frame_result obtained from EncodeFrame()
SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
target_bitrate_, num_frames_,
target_bitrate_, num_frames_, target_level_,
in_file_path_str_.c_str());
simple_encode.ComputeFirstPassStats();
const int num_coding_frames = simple_encode.GetCodingFrameNum();
@@ -558,7 +559,7 @@ TEST_F(SimpleEncodeTest, GetEncodeFrameInfo) {
TEST_F(SimpleEncodeTest, GetFramePixelCount) {
SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_,
target_bitrate_, num_frames_,
target_bitrate_, num_frames_, target_level_,
in_file_path_str_.c_str());
EXPECT_EQ(simple_encode.GetFramePixelCount(),
static_cast<uint64_t>(width_ * height_ * 3 / 2));

View File

@@ -782,11 +782,12 @@ static void UpdateEncodeConfig(const EncodeConfig &config,
static VP9EncoderConfig GetEncodeConfig(
int frame_width, int frame_height, vpx_rational_t frame_rate,
int target_bitrate, int encode_speed, vpx_enc_pass enc_pass,
int target_bitrate, int encode_speed, int target_level,
vpx_enc_pass enc_pass,
const std::vector<EncodeConfig> &encode_config_list) {
VP9EncoderConfig oxcf =
vp9_get_encoder_config(frame_width, frame_height, frame_rate,
target_bitrate, encode_speed, enc_pass);
VP9EncoderConfig oxcf = vp9_get_encoder_config(
frame_width, frame_height, frame_rate, target_bitrate, encode_speed,
target_level, enc_pass);
for (const auto &config : encode_config_list) {
UpdateEncodeConfig(config, &oxcf);
}
@@ -799,7 +800,7 @@ static VP9EncoderConfig GetEncodeConfig(
SimpleEncode::SimpleEncode(int frame_width, int frame_height,
int frame_rate_num, int frame_rate_den,
int target_bitrate, int num_frames,
int target_bitrate, int num_frames, int target_level,
const char *infile_path, const char *outfile_path) {
impl_ptr_ = std::unique_ptr<EncodeImpl>(new EncodeImpl());
frame_width_ = frame_width;
@@ -809,6 +810,7 @@ SimpleEncode::SimpleEncode(int frame_width, int frame_height,
target_bitrate_ = target_bitrate;
num_frames_ = num_frames;
encode_speed_ = 0;
target_level_ = target_level;
frame_coding_index_ = 0;
show_frame_count_ = 0;
@@ -860,9 +862,9 @@ StatusCode SimpleEncode::DumpEncodeConfigs(int pass, FILE *fp) {
}
const vpx_rational_t frame_rate =
make_vpx_rational(frame_rate_num_, frame_rate_den_);
const VP9EncoderConfig oxcf =
GetEncodeConfig(frame_width_, frame_height_, frame_rate, target_bitrate_,
encode_speed_, enc_pass, impl_ptr_->encode_config_list);
const VP9EncoderConfig oxcf = GetEncodeConfig(
frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_,
target_level_, enc_pass, impl_ptr_->encode_config_list);
vp9_dump_encoder_config(&oxcf, fp);
return StatusOk;
}
@@ -872,7 +874,7 @@ void SimpleEncode::ComputeFirstPassStats() {
make_vpx_rational(frame_rate_num_, frame_rate_den_);
const VP9EncoderConfig oxcf = GetEncodeConfig(
frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_,
VPX_RC_FIRST_PASS, impl_ptr_->encode_config_list);
target_level_, VPX_RC_FIRST_PASS, impl_ptr_->encode_config_list);
impl_ptr_->cpi = init_encoder(&oxcf, impl_ptr_->img_fmt);
struct lookahead_ctx *lookahead = impl_ptr_->cpi->lookahead;
int i;
@@ -1038,7 +1040,7 @@ void SimpleEncode::StartEncode() {
make_vpx_rational(frame_rate_num_, frame_rate_den_);
VP9EncoderConfig oxcf = GetEncodeConfig(
frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_,
VPX_RC_LAST_PASS, impl_ptr_->encode_config_list);
target_level_, VPX_RC_LAST_PASS, impl_ptr_->encode_config_list);
vpx_fixed_buf_t stats;
stats.buf = GetVectorData(impl_ptr_->first_pass_stats);
@@ -1266,7 +1268,7 @@ int SimpleEncode::GetCodingFrameNum() const {
make_vpx_rational(frame_rate_num_, frame_rate_den_);
const VP9EncoderConfig oxcf = GetEncodeConfig(
frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_,
VPX_RC_LAST_PASS, impl_ptr_->encode_config_list);
target_level_, VPX_RC_LAST_PASS, impl_ptr_->encode_config_list);
FRAME_INFO frame_info = vp9_get_frame_info(&oxcf);
fps_init_first_pass_info(&twopass.first_pass_info,
GetVectorData(impl_ptr_->first_pass_stats),
@@ -1285,7 +1287,7 @@ std::vector<int> SimpleEncode::ComputeKeyFrameMap() const {
make_vpx_rational(frame_rate_num_, frame_rate_den_);
const VP9EncoderConfig oxcf = GetEncodeConfig(
frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_,
VPX_RC_LAST_PASS, impl_ptr_->encode_config_list);
target_level_, VPX_RC_LAST_PASS, impl_ptr_->encode_config_list);
TWO_PASS twopass;
fps_init_first_pass_info(&twopass.first_pass_info,
GetVectorData(impl_ptr_->first_pass_stats),

View File

@@ -44,6 +44,26 @@ enum RefFrameType {
kRefFrameTypeNone = -1,
};
enum VP9_LEVEL {
LEVEL_UNKNOWN = 0,
LEVEL_AUTO = 1,
LEVEL_1 = 10,
LEVEL_1_1 = 11,
LEVEL_2 = 20,
LEVEL_2_1 = 21,
LEVEL_3 = 30,
LEVEL_3_1 = 31,
LEVEL_4 = 40,
LEVEL_4_1 = 41,
LEVEL_5 = 50,
LEVEL_5_1 = 51,
LEVEL_5_2 = 52,
LEVEL_6 = 60,
LEVEL_6_1 = 61,
LEVEL_6_2 = 62,
LEVEL_MAX = 255
};
enum GopMapFlag {
kGopMapFlagStart =
1 << 0, // Indicate this location is the start of a group of pictures.
@@ -343,7 +363,8 @@ class SimpleEncode {
// format.
SimpleEncode(int frame_width, int frame_height, int frame_rate_num,
int frame_rate_den, int target_bitrate, int num_frames,
const char *infile_path, const char *outfile_path = nullptr);
int target_level, const char *infile_path,
const char *outfile_path = nullptr);
~SimpleEncode();
SimpleEncode(SimpleEncode &) = delete;
SimpleEncode &operator=(const SimpleEncode &) = delete;
@@ -513,6 +534,7 @@ class SimpleEncode {
int target_bitrate_;
int num_frames_;
int encode_speed_;
int target_level_;
std::FILE *in_file_;
std::FILE *out_file_;

View File

@@ -2143,6 +2143,7 @@ static vp9_extracfg get_extra_cfg() {
VP9EncoderConfig vp9_get_encoder_config(int frame_width, int frame_height,
vpx_rational_t frame_rate,
int target_bitrate, int encode_speed,
int target_level,
vpx_enc_pass enc_pass) {
/* This function will generate the same VP9EncoderConfig used by the
* vpxenc command given below.
@@ -2154,6 +2155,7 @@ VP9EncoderConfig vp9_get_encoder_config(int frame_width, int frame_height,
* FPS: frame_rate
* BITRATE: target_bitrate
* CPU_USED:encode_speed
* TARGET_LEVEL: target_level
*
* INPUT, OUTPUT, LIMIT will not affect VP9EncoderConfig
*
@@ -2166,6 +2168,7 @@ VP9EncoderConfig vp9_get_encoder_config(int frame_width, int frame_height,
* FPS=30/1
* LIMIT=150
* CPU_USED=0
* TARGET_LEVEL=0
* ./vpxenc --limit=$LIMIT --width=$WIDTH --height=$HEIGHT --fps=$FPS
* --lag-in-frames=25 \
* --codec=vp9 --good --cpu-used=CPU_USED --threads=0 --profile=0 \
@@ -2174,7 +2177,7 @@ VP9EncoderConfig vp9_get_encoder_config(int frame_width, int frame_height,
* --minsection-pct=0 --maxsection-pct=150 --arnr-maxframes=7 --psnr \
* --arnr-strength=5 --sharpness=0 --undershoot-pct=100 --overshoot-pct=100 \
* --frame-parallel=0 --tile-columns=0 --cpu-used=0 --end-usage=vbr \
* --target-bitrate=$BITRATE -o $OUTPUT $INPUT
* --target-bitrate=$BITRATE --target-level=0 -o $OUTPUT $INPUT
*/
VP9EncoderConfig oxcf;
@@ -2192,6 +2195,7 @@ VP9EncoderConfig vp9_get_encoder_config(int frame_width, int frame_height,
oxcf.frame_parallel_decoding_mode = 0;
oxcf.two_pass_vbrmax_section = 150;
oxcf.speed = abs(encode_speed);
oxcf.target_level = target_level;
return oxcf;
}

View File

@@ -20,6 +20,7 @@ extern "C" {
VP9EncoderConfig vp9_get_encoder_config(int frame_width, int frame_height,
vpx_rational_t frame_rate,
int target_bitrate, int encode_speed,
int target_level,
vpx_enc_pass enc_pass);
void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf, FILE *fp);