shithub: libvpx

Download patch

ref: 463d33145de28770f815466db0ffc85d14442043
parent: b8273e8ae5c14bccefde96170507336a4f15c98c
author: Cheng Chen <chengchen@google.com>
date: Thu May 27 11:38:28 EDT 2021

L2E: properly init two pass rc parameters

Two pass rc parameters are only initialized in the second pass
in vp9 normal two pass encoding.
However, the simple_encode API queries the keyframe group, arf group,
and number of coding frames without going throught the two pass
route.
Since recent libvpx rc changes, parameters in the TWO_PASS
struct have a great influence on the determination of the above
information.
We therefore need to properly init two pass rc parameters in
the simple_encode related environment.

Change-Id: Ie14b86d6e7ebf171b638d2da24a7fdcf5a15c3d9

--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -3487,7 +3487,7 @@
 
 // Configure image size specific vizier parameters.
 // Later these will be set via additional command line options
-static void init_vizier_params(TWO_PASS *const twopass, int screen_area) {
+void vp9_init_vizier_params(TWO_PASS *const twopass, int screen_area) {
   // When |use_vizier_rc_params| is 1, we expect the rc parameters below to
   // have been initialised on the command line as adjustment factors such
   // that a factor of 1.0 will match the default behavior when
@@ -3561,7 +3561,7 @@
   if (cm->current_video_frame == 0) {
     unsigned int screen_area = (cm->width * cm->height);
 
-    init_vizier_params(twopass, screen_area);
+    vp9_init_vizier_params(twopass, screen_area);
   }
 
   // If this is an arf frame then we dont want to read the stats file or
@@ -3877,7 +3877,7 @@
 // Under CONFIG_RATE_CTRL, once the first_pass_info is ready, the number of
 // coding frames (including show frame and alt ref) can be determined.
 int vp9_get_coding_frame_num(const VP9EncoderConfig *oxcf,
-                             const TWO_PASS *const twopass,
+                             TWO_PASS *const twopass,
                              const FRAME_INFO *frame_info, int multi_layer_arf,
                              int allow_alt_ref) {
   const FIRST_PASS_INFO *first_pass_info = &twopass->first_pass_info;
--- a/vp9/encoder/vp9_firstpass.h
+++ b/vp9/encoder/vp9_firstpass.h
@@ -257,6 +257,7 @@
 
 void vp9_init_second_pass(struct VP9_COMP *cpi);
 void vp9_rc_get_second_pass_params(struct VP9_COMP *cpi);
+void vp9_init_vizier_params(TWO_PASS *const twopass, int screen_area);
 
 // Post encode update of the rate control parameters for 2-pass
 void vp9_twopass_postencode_update(struct VP9_COMP *cpi);
@@ -304,7 +305,7 @@
                                    int last_gop_use_alt_ref, int *use_alt_ref);
 
 int vp9_get_coding_frame_num(const struct VP9EncoderConfig *oxcf,
-                             const TWO_PASS *const twopass,
+                             TWO_PASS *const twopass,
                              const FRAME_INFO *frame_info, int multi_layer_arf,
                              int allow_alt_ref);
 
--- a/vp9/simple_encode.cc
+++ b/vp9/simple_encode.cc
@@ -926,9 +926,6 @@
   impl_ptr_->first_pass_stats.push_back(
       vp9_get_total_stats(&impl_ptr_->cpi->twopass));
   vp9_end_first_pass(impl_ptr_->cpi);
-  fps_init_first_pass_info(&cpi->twopass.first_pass_info,
-                           GetVectorData(impl_ptr_->first_pass_stats),
-                           num_frames_);
 
   // Generate key_frame_map based on impl_ptr_->first_pass_stats.
   key_frame_map_ = ComputeKeyFrameMap();
@@ -1057,6 +1054,11 @@
   frame_coding_index_ = 0;
   show_frame_count_ = 0;
 
+  assert(impl_ptr_->cpi != nullptr);
+  FRAME_INFO frame_info = vp9_get_frame_info(&oxcf);
+  unsigned int screen_area = frame_info.frame_width * frame_info.frame_height;
+  vp9_init_vizier_params(&impl_ptr_->cpi->twopass, screen_area);
+
   UpdateKeyFrameGroup(show_frame_count_);
 
   const GOP_COMMAND gop_command = GetGopCommand(gop_map_, show_frame_count_);
@@ -1257,7 +1259,7 @@
   }
 
   // These are the default settings for now.
-  VP9_COMP *cpi = impl_ptr_->cpi;
+  TWO_PASS twopass;
   const int multi_layer_arf = 0;
   const int allow_alt_ref = 1;
   vpx_rational_t frame_rate =
@@ -1266,15 +1268,16 @@
       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);
-  fps_init_first_pass_info(&cpi->twopass.first_pass_info,
+  fps_init_first_pass_info(&twopass.first_pass_info,
                            GetVectorData(impl_ptr_->first_pass_stats),
                            num_frames_);
-  return vp9_get_coding_frame_num(&oxcf, &cpi->twopass, &frame_info,
-                                  multi_layer_arf, allow_alt_ref);
+  unsigned int screen_area = frame_info.frame_width * frame_info.frame_height;
+  vp9_init_vizier_params(&twopass, screen_area);
+  return vp9_get_coding_frame_num(&oxcf, &twopass, &frame_info, multi_layer_arf,
+                                  allow_alt_ref);
 }
 
 std::vector<int> SimpleEncode::ComputeKeyFrameMap() const {
-  const VP9_COMP *cpi = impl_ptr_->cpi;
   // The last entry of first_pass_stats is the overall stats.
   assert(impl_ptr_->first_pass_stats.size() == num_frames_ + 1);
   vpx_rational_t frame_rate =
@@ -1282,8 +1285,12 @@
   const VP9EncoderConfig oxcf = GetEncodeConfig(
       frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_,
       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),
+                           num_frames_);
   std::vector<int> key_frame_map(num_frames_, 0);
-  vp9_get_key_frame_map(&oxcf, &cpi->twopass, GetVectorData(key_frame_map));
+  vp9_get_key_frame_map(&oxcf, &twopass, GetVectorData(key_frame_map));
   return key_frame_map;
 }