return 1;
}
+// Assume every config in VP9EncoderConfig is less than 100 characters.
+#define ENCODE_CONFIG_BUF_SIZE 100
+struct EncodeConfig {
+ char name[ENCODE_CONFIG_BUF_SIZE];
+ char value[ENCODE_CONFIG_BUF_SIZE];
+};
+
class SimpleEncode::EncodeImpl {
public:
VP9_COMP *cpi;
vpx_img_fmt_t img_fmt;
vpx_image_t tmp_img;
std::vector<FIRSTPASS_STATS> first_pass_stats;
+ std::vector<EncodeConfig> encode_config_list;
};
static VP9_COMP *init_encoder(const VP9EncoderConfig *oxcf,
start_ref_frame_info, group_of_picture);
}
+#define SET_STRUCT_VALUE(config, structure, ret, field) \
+ if (strcmp(config.name, #field) == 0) { \
+ structure->field = atoi(config.value); \
+ ret = 1; \
+ }
+
+static void UpdateEncodeConfig(const EncodeConfig &config,
+ VP9EncoderConfig *oxcf) {
+ int ret = 0;
+ SET_STRUCT_VALUE(config, oxcf, ret, key_freq);
+ SET_STRUCT_VALUE(config, oxcf, ret, two_pass_vbrmin_section);
+ SET_STRUCT_VALUE(config, oxcf, ret, two_pass_vbrmax_section);
+ SET_STRUCT_VALUE(config, oxcf, ret, under_shoot_pct);
+ SET_STRUCT_VALUE(config, oxcf, ret, over_shoot_pct);
+ SET_STRUCT_VALUE(config, oxcf, ret, max_threads);
+ SET_STRUCT_VALUE(config, oxcf, ret, frame_parallel_decoding_mode);
+ SET_STRUCT_VALUE(config, oxcf, ret, tile_columns);
+ SET_STRUCT_VALUE(config, oxcf, ret, arnr_max_frames);
+ SET_STRUCT_VALUE(config, oxcf, ret, arnr_strength);
+ SET_STRUCT_VALUE(config, oxcf, ret, lag_in_frames);
+ SET_STRUCT_VALUE(config, oxcf, ret, encode_breakout);
+ SET_STRUCT_VALUE(config, oxcf, ret, enable_tpl_model);
+ SET_STRUCT_VALUE(config, oxcf, ret, enable_auto_arf);
+ if (ret == 0) {
+ fprintf(stderr, "Ignored unsupported encode_config %s\n", config.name);
+ }
+}
+
+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,
+ 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);
+ for (const auto &config : encode_config_list) {
+ UpdateEncodeConfig(config, &oxcf);
+ }
+ if (enc_pass == VPX_RC_FIRST_PASS) {
+ oxcf.lag_in_frames = 0;
+ }
+ return oxcf;
+}
+
SimpleEncode::SimpleEncode(int frame_width, int frame_height,
int frame_rate_num, int frame_rate_den,
int target_bitrate, int num_frames,
encode_speed_ = encode_speed;
}
+StatusCode SimpleEncode::SetEncodeConfig(const char *name, const char *value) {
+ if (name == nullptr || value == nullptr) {
+ fprintf(stderr, "SetEncodeConfig: null pointer, name %p value %p\n", name,
+ value);
+ return StatusError;
+ }
+ EncodeConfig config;
+ snprintf(config.name, ENCODE_CONFIG_BUF_SIZE, "%s", name);
+ snprintf(config.value, ENCODE_CONFIG_BUF_SIZE, "%s", value);
+ impl_ptr_->encode_config_list.push_back(config);
+ return StatusOk;
+}
+
+StatusCode SimpleEncode::DumpEncodeConfigs(int pass, FILE *fp) {
+ if (fp == nullptr) {
+ fprintf(stderr, "DumpEncodeConfigs: null pointer, fp %p\n", fp);
+ return StatusError;
+ }
+ vpx_enc_pass enc_pass;
+ if (pass == 1) {
+ enc_pass = VPX_RC_FIRST_PASS;
+ } else {
+ enc_pass = VPX_RC_LAST_PASS;
+ }
+ 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);
+ vp9_dump_encoder_config(&oxcf, fp);
+ return StatusOk;
+}
+
void SimpleEncode::ComputeFirstPassStats() {
vpx_rational_t frame_rate =
make_vpx_rational(frame_rate_num_, frame_rate_den_);
- const VP9EncoderConfig oxcf =
- vp9_get_encoder_config(frame_width_, frame_height_, frame_rate,
- target_bitrate_, encode_speed_, VPX_RC_FIRST_PASS);
+ const VP9EncoderConfig oxcf = GetEncodeConfig(
+ frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_,
+ VPX_RC_FIRST_PASS, impl_ptr_->encode_config_list);
VP9_COMP *cpi = init_encoder(&oxcf, impl_ptr_->img_fmt);
struct lookahead_ctx *lookahead = cpi->lookahead;
int i;
assert(impl_ptr_->first_pass_stats.size() > 0);
vpx_rational_t frame_rate =
make_vpx_rational(frame_rate_num_, frame_rate_den_);
- VP9EncoderConfig oxcf =
- vp9_get_encoder_config(frame_width_, frame_height_, frame_rate,
- target_bitrate_, encode_speed_, VPX_RC_LAST_PASS);
+ VP9EncoderConfig oxcf = GetEncodeConfig(
+ frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_,
+ VPX_RC_LAST_PASS, impl_ptr_->encode_config_list);
+
vpx_fixed_buf_t stats;
stats.buf = GetVectorData(impl_ptr_->first_pass_stats);
stats.sz = sizeof(impl_ptr_->first_pass_stats[0]) *
const int allow_alt_ref = 1;
vpx_rational_t frame_rate =
make_vpx_rational(frame_rate_num_, frame_rate_den_);
- const VP9EncoderConfig oxcf =
- vp9_get_encoder_config(frame_width_, frame_height_, frame_rate,
- target_bitrate_, encode_speed_, VPX_RC_LAST_PASS);
+ const VP9EncoderConfig oxcf = GetEncodeConfig(
+ frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_,
+ VPX_RC_LAST_PASS, impl_ptr_->encode_config_list);
FRAME_INFO frame_info = vp9_get_frame_info(&oxcf);
FIRST_PASS_INFO first_pass_info;
fps_init_first_pass_info(&first_pass_info,
assert(impl_ptr_->first_pass_stats.size() == num_frames_ + 1);
vpx_rational_t frame_rate =
make_vpx_rational(frame_rate_num_, frame_rate_den_);
- const VP9EncoderConfig oxcf =
- vp9_get_encoder_config(frame_width_, frame_height_, frame_rate,
- target_bitrate_, encode_speed_, VPX_RC_LAST_PASS);
+ const VP9EncoderConfig oxcf = GetEncodeConfig(
+ frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_,
+ VPX_RC_LAST_PASS, impl_ptr_->encode_config_list);
FRAME_INFO frame_info = vp9_get_frame_info(&oxcf);
FIRST_PASS_INFO first_pass_info;
fps_init_first_pass_info(&first_pass_info,
}
if (get_level_index(oxcf->target_level) >= 0) config_target_level(oxcf);
- // vp9_dump_encoder_config(oxcf);
+ // vp9_dump_encoder_config(oxcf, stderr);
return VPX_CODEC_OK;
}
return oxcf;
}
-#define DUMP_STRUCT_VALUE(struct, value) \
- printf(#value " %" PRId64 "\n", (int64_t)(struct)->value)
+#define DUMP_STRUCT_VALUE(fp, structure, value) \
+ fprintf(fp, #value " %" PRId64 "\n", (int64_t)(structure)->value)
-void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf) {
- DUMP_STRUCT_VALUE(oxcf, profile);
- DUMP_STRUCT_VALUE(oxcf, bit_depth);
- DUMP_STRUCT_VALUE(oxcf, width);
- DUMP_STRUCT_VALUE(oxcf, height);
- DUMP_STRUCT_VALUE(oxcf, input_bit_depth);
- DUMP_STRUCT_VALUE(oxcf, init_framerate);
+void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf, FILE *fp) {
+ DUMP_STRUCT_VALUE(fp, oxcf, profile);
+ DUMP_STRUCT_VALUE(fp, oxcf, bit_depth);
+ DUMP_STRUCT_VALUE(fp, oxcf, width);
+ DUMP_STRUCT_VALUE(fp, oxcf, height);
+ DUMP_STRUCT_VALUE(fp, oxcf, input_bit_depth);
+ DUMP_STRUCT_VALUE(fp, oxcf, init_framerate);
// TODO(angiebird): dump g_timebase
// TODO(angiebird): dump g_timebase_in_ts
- DUMP_STRUCT_VALUE(oxcf, target_bandwidth);
+ DUMP_STRUCT_VALUE(fp, oxcf, target_bandwidth);
- DUMP_STRUCT_VALUE(oxcf, noise_sensitivity);
- DUMP_STRUCT_VALUE(oxcf, sharpness);
- DUMP_STRUCT_VALUE(oxcf, speed);
- DUMP_STRUCT_VALUE(oxcf, rc_max_intra_bitrate_pct);
- DUMP_STRUCT_VALUE(oxcf, rc_max_inter_bitrate_pct);
- DUMP_STRUCT_VALUE(oxcf, gf_cbr_boost_pct);
+ DUMP_STRUCT_VALUE(fp, oxcf, noise_sensitivity);
+ DUMP_STRUCT_VALUE(fp, oxcf, sharpness);
+ DUMP_STRUCT_VALUE(fp, oxcf, speed);
+ DUMP_STRUCT_VALUE(fp, oxcf, rc_max_intra_bitrate_pct);
+ DUMP_STRUCT_VALUE(fp, oxcf, rc_max_inter_bitrate_pct);
+ DUMP_STRUCT_VALUE(fp, oxcf, gf_cbr_boost_pct);
- DUMP_STRUCT_VALUE(oxcf, mode);
- DUMP_STRUCT_VALUE(oxcf, pass);
+ DUMP_STRUCT_VALUE(fp, oxcf, mode);
+ DUMP_STRUCT_VALUE(fp, oxcf, pass);
// Key Framing Operations
- DUMP_STRUCT_VALUE(oxcf, auto_key);
- DUMP_STRUCT_VALUE(oxcf, key_freq);
+ DUMP_STRUCT_VALUE(fp, oxcf, auto_key);
+ DUMP_STRUCT_VALUE(fp, oxcf, key_freq);
- DUMP_STRUCT_VALUE(oxcf, lag_in_frames);
+ DUMP_STRUCT_VALUE(fp, oxcf, lag_in_frames);
// ----------------------------------------------------------------
// DATARATE CONTROL OPTIONS
// vbr, cbr, constrained quality or constant quality
- DUMP_STRUCT_VALUE(oxcf, rc_mode);
+ DUMP_STRUCT_VALUE(fp, oxcf, rc_mode);
// buffer targeting aggressiveness
- DUMP_STRUCT_VALUE(oxcf, under_shoot_pct);
- DUMP_STRUCT_VALUE(oxcf, over_shoot_pct);
+ DUMP_STRUCT_VALUE(fp, oxcf, under_shoot_pct);
+ DUMP_STRUCT_VALUE(fp, oxcf, over_shoot_pct);
// buffering parameters
// TODO(angiebird): dump tarting_buffer_level_ms
// TODO(angiebird): dump maximum_buffer_size_ms
// Frame drop threshold.
- DUMP_STRUCT_VALUE(oxcf, drop_frames_water_mark);
+ DUMP_STRUCT_VALUE(fp, oxcf, drop_frames_water_mark);
// controlling quality
- DUMP_STRUCT_VALUE(oxcf, fixed_q);
- DUMP_STRUCT_VALUE(oxcf, worst_allowed_q);
- DUMP_STRUCT_VALUE(oxcf, best_allowed_q);
- DUMP_STRUCT_VALUE(oxcf, cq_level);
- DUMP_STRUCT_VALUE(oxcf, aq_mode);
+ DUMP_STRUCT_VALUE(fp, oxcf, fixed_q);
+ DUMP_STRUCT_VALUE(fp, oxcf, worst_allowed_q);
+ DUMP_STRUCT_VALUE(fp, oxcf, best_allowed_q);
+ DUMP_STRUCT_VALUE(fp, oxcf, cq_level);
+ DUMP_STRUCT_VALUE(fp, oxcf, aq_mode);
// Special handling of Adaptive Quantization for AltRef frames
- DUMP_STRUCT_VALUE(oxcf, alt_ref_aq);
+ DUMP_STRUCT_VALUE(fp, oxcf, alt_ref_aq);
// Internal frame size scaling.
- DUMP_STRUCT_VALUE(oxcf, resize_mode);
- DUMP_STRUCT_VALUE(oxcf, scaled_frame_width);
- DUMP_STRUCT_VALUE(oxcf, scaled_frame_height);
+ DUMP_STRUCT_VALUE(fp, oxcf, resize_mode);
+ DUMP_STRUCT_VALUE(fp, oxcf, scaled_frame_width);
+ DUMP_STRUCT_VALUE(fp, oxcf, scaled_frame_height);
// Enable feature to reduce the frame quantization every x frames.
- DUMP_STRUCT_VALUE(oxcf, frame_periodic_boost);
+ DUMP_STRUCT_VALUE(fp, oxcf, frame_periodic_boost);
// two pass datarate control
- DUMP_STRUCT_VALUE(oxcf, two_pass_vbrbias);
- DUMP_STRUCT_VALUE(oxcf, two_pass_vbrmin_section);
- DUMP_STRUCT_VALUE(oxcf, two_pass_vbrmax_section);
- DUMP_STRUCT_VALUE(oxcf, vbr_corpus_complexity);
+ DUMP_STRUCT_VALUE(fp, oxcf, two_pass_vbrbias);
+ DUMP_STRUCT_VALUE(fp, oxcf, two_pass_vbrmin_section);
+ DUMP_STRUCT_VALUE(fp, oxcf, two_pass_vbrmax_section);
+ DUMP_STRUCT_VALUE(fp, oxcf, vbr_corpus_complexity);
// END DATARATE CONTROL OPTIONS
// ----------------------------------------------------------------
// Spatial and temporal scalability.
- DUMP_STRUCT_VALUE(oxcf, ss_number_layers);
- DUMP_STRUCT_VALUE(oxcf, ts_number_layers);
+ DUMP_STRUCT_VALUE(fp, oxcf, ss_number_layers);
+ DUMP_STRUCT_VALUE(fp, oxcf, ts_number_layers);
// Bitrate allocation for spatial layers.
// TODO(angiebird): dump layer_target_bitrate[VPX_MAX_LAYERS]
// TODO(angiebird): dump ss_enable_auto_arf[VPX_SS_MAX_LAYERS]
// TODO(angiebird): dump ts_rate_decimator[VPX_TS_MAX_LAYERS]
- DUMP_STRUCT_VALUE(oxcf, enable_auto_arf);
- DUMP_STRUCT_VALUE(oxcf, encode_breakout);
- DUMP_STRUCT_VALUE(oxcf, error_resilient_mode);
- DUMP_STRUCT_VALUE(oxcf, frame_parallel_decoding_mode);
+ DUMP_STRUCT_VALUE(fp, oxcf, enable_auto_arf);
+ DUMP_STRUCT_VALUE(fp, oxcf, encode_breakout);
+ DUMP_STRUCT_VALUE(fp, oxcf, error_resilient_mode);
+ DUMP_STRUCT_VALUE(fp, oxcf, frame_parallel_decoding_mode);
- DUMP_STRUCT_VALUE(oxcf, arnr_max_frames);
- DUMP_STRUCT_VALUE(oxcf, arnr_strength);
+ DUMP_STRUCT_VALUE(fp, oxcf, arnr_max_frames);
+ DUMP_STRUCT_VALUE(fp, oxcf, arnr_strength);
- DUMP_STRUCT_VALUE(oxcf, min_gf_interval);
- DUMP_STRUCT_VALUE(oxcf, max_gf_interval);
+ DUMP_STRUCT_VALUE(fp, oxcf, min_gf_interval);
+ DUMP_STRUCT_VALUE(fp, oxcf, max_gf_interval);
- DUMP_STRUCT_VALUE(oxcf, tile_columns);
- DUMP_STRUCT_VALUE(oxcf, tile_rows);
+ DUMP_STRUCT_VALUE(fp, oxcf, tile_columns);
+ DUMP_STRUCT_VALUE(fp, oxcf, tile_rows);
- DUMP_STRUCT_VALUE(oxcf, enable_tpl_model);
+ DUMP_STRUCT_VALUE(fp, oxcf, enable_tpl_model);
- DUMP_STRUCT_VALUE(oxcf, max_threads);
+ DUMP_STRUCT_VALUE(fp, oxcf, max_threads);
- DUMP_STRUCT_VALUE(oxcf, target_level);
+ DUMP_STRUCT_VALUE(fp, oxcf, target_level);
// TODO(angiebird): dump two_pass_stats_in
// TODO(angiebird): dump firstpass_mb_stats_in
#endif
- DUMP_STRUCT_VALUE(oxcf, tuning);
- DUMP_STRUCT_VALUE(oxcf, content);
+ DUMP_STRUCT_VALUE(fp, oxcf, tuning);
+ DUMP_STRUCT_VALUE(fp, oxcf, content);
#if CONFIG_VP9_HIGHBITDEPTH
- DUMP_STRUCT_VALUE(oxcf, use_highbitdepth);
+ DUMP_STRUCT_VALUE(fp, oxcf, use_highbitdepth);
#endif
- DUMP_STRUCT_VALUE(oxcf, color_space);
- DUMP_STRUCT_VALUE(oxcf, color_range);
- DUMP_STRUCT_VALUE(oxcf, render_width);
- DUMP_STRUCT_VALUE(oxcf, render_height);
- DUMP_STRUCT_VALUE(oxcf, temporal_layering_mode);
-
- DUMP_STRUCT_VALUE(oxcf, row_mt);
- DUMP_STRUCT_VALUE(oxcf, motion_vector_unit_test);
+ DUMP_STRUCT_VALUE(fp, oxcf, color_space);
+ DUMP_STRUCT_VALUE(fp, oxcf, color_range);
+ DUMP_STRUCT_VALUE(fp, oxcf, render_width);
+ DUMP_STRUCT_VALUE(fp, oxcf, render_height);
+ DUMP_STRUCT_VALUE(fp, oxcf, temporal_layering_mode);
+
+ DUMP_STRUCT_VALUE(fp, oxcf, row_mt);
+ DUMP_STRUCT_VALUE(fp, oxcf, motion_vector_unit_test);
}
FRAME_INFO vp9_get_frame_info(const VP9EncoderConfig *oxcf) {