shithub: libvpx

Download patch

ref: da7c503fe585de1e1f613f289a24b31567fd7113
parent: 7e8ea22e4056a3da04b139fcc812a3f6937bbed7
author: angiebird <angiebird@google.com>
date: Thu Oct 1 15:18:09 EDT 2020

Add SetEncodeConfig and DumpEncodeConfigs

Change-Id: Ie6864b1133c26021d9c4883df033ecd2969585ed

--- a/vp9/simple_encode.cc
+++ b/vp9/simple_encode.cc
@@ -90,6 +90,13 @@
   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;
@@ -96,6 +103,7 @@
   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,
@@ -711,6 +719,50 @@
                     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,
@@ -748,12 +800,45 @@
   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;
@@ -913,9 +998,10 @@
   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]) *
@@ -1132,9 +1218,9 @@
   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,
@@ -1149,9 +1235,9 @@
   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,
--- a/vp9/simple_encode.h
+++ b/vp9/simple_encode.h
@@ -19,6 +19,11 @@
 
 namespace vp9 {
 
+enum StatusCode {
+  StatusOk = 0,
+  StatusError,
+};
+
 // TODO(angiebird): Add description for each frame type.
 enum FrameType {
   kFrameTypeKey = 0,
@@ -321,6 +326,32 @@
   // Setting the encode_speed to a higher level will yield faster coding
   // at the cost of lower compression efficiency.
   void SetEncodeSpeed(int encode_speed);
+
+  // Set encoder config
+  // The following configs in VP9EncoderConfig are allowed to change in this
+  // function. See https://ffmpeg.org/ffmpeg-codecs.html#libvpx for each
+  // config's meaning.
+  // Configs in VP9EncoderConfig:      Equivalent configs in ffmpeg:
+  // 1  key_freq                       -g
+  // 2  two_pass_vbrmin_section        -minrate * 100LL / bit_rate
+  // 3  two_pass_vbrmax_section        -maxrate * 100LL / bit_rate
+  // 4  under_shoot_pct                -undershoot-pct
+  // 5  over_shoot_pct                 -overshoot-pct
+  // 6  max_threads                    -threads
+  // 7  frame_parallel_decoding_mode   -frame-parallel
+  // 8  tile_column                    -tile-columns
+  // 9  arnr_max_frames                -arnr-maxframes
+  // 10 arnr_strength                  -arnr-strength
+  // 11 lag_in_frames                  -rc_lookahead
+  // 12 encode_breakout                -static-thresh
+  // 13 enable_tpl_model               -enable-tpl
+  // 14 enable_auto_arf                -auto-alt-ref
+  StatusCode SetEncodeConfig(const char *name, const char *value);
+
+  // A debug function that dumps configs from VP9EncoderConfig
+  // pass = 1: first pass, pass = 2: second pass
+  // fp: file pointer for dumping config
+  StatusCode DumpEncodeConfigs(int pass, FILE *fp);
 
   // Makes encoder compute the first pass stats and store it at
   // impl_ptr_->first_pass_stats. key_frame_map_ is also computed based on the
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -633,7 +633,7 @@
   }
 
   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;
 }
 
@@ -1970,46 +1970,46 @@
   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
@@ -2017,37 +2017,37 @@
   // 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]
@@ -2055,25 +2055,25 @@
   // 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
 
@@ -2081,19 +2081,19 @@
   // 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(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(oxcf, row_mt);
-  DUMP_STRUCT_VALUE(oxcf, motion_vector_unit_test);
+  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) {
--- a/vp9/vp9_cx_iface.h
+++ b/vp9/vp9_cx_iface.h
@@ -22,7 +22,7 @@
                                         int target_bitrate, int encode_speed,
                                         vpx_enc_pass enc_pass);
 
-void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf);
+void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf, FILE *fp);
 
 FRAME_INFO vp9_get_frame_info(const VP9EncoderConfig *oxcf);