shithub: libvpx

Download patch

ref: 246a65c6961cfa314d41780ec3909a2308a568c6
parent: d6f2ae2c127b4dd61fd7bedf725152138d02b20e
author: angiebird <angiebird@google.com>
date: Fri Aug 7 14:39:18 EDT 2020

Make target_frame_bits error margin configurable.

Change-Id: I05dd4d60741743c13951727ce6608acf4224ebec

--- a/test/simple_encode_test.cc
+++ b/test/simple_encode_test.cc
@@ -182,9 +182,13 @@
       target_frame_bits = 2000;
     }
 
+    double percent_diff = 15;
+    if (encode_frame_info.frame_type == kFrameTypeOverlay) {
+      percent_diff = 100;
+    }
     EncodeFrameResult encode_frame_result;
-    simple_encode.EncodeFrameWithTargetFrameBits(&encode_frame_result,
-                                                 target_frame_bits);
+    simple_encode.EncodeFrameWithTargetFrameBits(
+        &encode_frame_result, target_frame_bits, percent_diff);
     const int recode_count = encode_frame_result.recode_count;
     // TODO(angiebird): Replace 7 by RATE_CTRL_MAX_RECODE_NUM
     EXPECT_LE(recode_count, 7);
@@ -192,7 +196,7 @@
 
     double diff = fabs((double)encode_frame_result.coding_data_bit_size -
                        target_frame_bits);
-    EXPECT_LE(diff * 100 / target_frame_bits, 15);
+    EXPECT_LE(diff * 100 / target_frame_bits, percent_diff);
   }
   simple_encode.EndEncode();
 }
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -4526,7 +4526,7 @@
       rq_model_update(rq_history, rc->this_frame_target, rq_model);
 
       // Check if we hit the target bitrate.
-      if (percent_diff <= 15 ||
+      if (percent_diff <= cpi->encode_command.target_frame_bits_error_percent ||
           rq_history->recode_count >= RATE_CTRL_MAX_RECODE_NUM ||
           rq_history->q_index_low >= rq_history->q_index_high) {
         break;
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -598,8 +598,11 @@
 typedef struct ENCODE_COMMAND {
   int use_external_quantize_index;
   int external_quantize_index;
+
   int use_external_target_frame_bits;
   int target_frame_bits;
+  double target_frame_bits_error_percent;
+
   GOP_COMMAND gop_command;
 } ENCODE_COMMAND;
 
@@ -621,9 +624,12 @@
 }
 
 static INLINE void encode_command_set_target_frame_bits(
-    ENCODE_COMMAND *encode_command, int target_frame_bits) {
+    ENCODE_COMMAND *encode_command, int target_frame_bits,
+    double target_frame_bits_error_percent) {
   encode_command->use_external_target_frame_bits = 1;
   encode_command->target_frame_bits = target_frame_bits;
+  encode_command->target_frame_bits_error_percent =
+      target_frame_bits_error_percent;
 }
 
 static INLINE void encode_command_reset_target_frame_bits(
@@ -630,6 +636,7 @@
     ENCODE_COMMAND *encode_command) {
   encode_command->use_external_target_frame_bits = 0;
   encode_command->target_frame_bits = -1;
+  encode_command->target_frame_bits_error_percent = 0;
 }
 
 static INLINE void encode_command_init(ENCODE_COMMAND *encode_command) {
--- a/vp9/simple_encode.cc
+++ b/vp9/simple_encode.cc
@@ -1098,9 +1098,10 @@
 }
 
 void SimpleEncode::EncodeFrameWithTargetFrameBits(
-    EncodeFrameResult *encode_frame_result, int target_frame_bits) {
+    EncodeFrameResult *encode_frame_result, int target_frame_bits,
+    double percent_diff) {
   encode_command_set_target_frame_bits(&impl_ptr_->cpi->encode_command,
-                                       target_frame_bits);
+                                       target_frame_bits, percent_diff);
   EncodeFrame(encode_frame_result);
   encode_command_reset_target_frame_bits(&impl_ptr_->cpi->encode_command);
 }
--- a/vp9/simple_encode.h
+++ b/vp9/simple_encode.h
@@ -398,9 +398,14 @@
 
   // Encode a frame with target frame bits usage.
   // The encoder will find a quantize index to make the actual frame bits usage
-  // match the target.
+  // match the target. EncodeFrameWithTargetFrameBits() will recode the frame
+  // update to 7 times to find a q_index to make the actual_frame_bits to
+  // satisfy following inequality.
+  // |actual_frame_bits - target_frame_bits| * 100 / target_frame_bits
+  // <= percent_diff.
   void EncodeFrameWithTargetFrameBits(EncodeFrameResult *encode_frame_result,
-                                      int target_frame_bits);
+                                      int target_frame_bits,
+                                      double percent_diff);
 
   // Gets the number of coding frames for the video. The coding frames include
   // show frame and no show frame.