shithub: libvpx

Download patch

ref: 42916ce60416d00f1188afd09c6a088ae9c91de9
parent: f0878a719ab79c743e561e2eb35855219f73d969
author: angiebird <[email protected]>
date: Tue Dec 3 10:34:03 EST 2019

Fix the encode inconsistency of SimpleEncode

Make sure restore_coding_context() is always called in the end
of encode_with_recode_loop().

Add EncodeConsistencyTest.

Change-Id: I3c8e4c8fcff4e3f7afef9bec469beef2a5fb6eeb

--- a/test/simple_encode_test.cc
+++ b/test/simple_encode_test.cc
@@ -107,6 +107,48 @@
   }
   simple_encode.EndEncode();
 }
+
+TEST(SimpleEncode, EncodeConsistencyTest) {
+  std::vector<int> quantize_index_list;
+  std::vector<uint64_t> ref_sse_list;
+  std::vector<double> ref_psnr_list;
+  std::vector<size_t> ref_bit_size_list;
+  {
+    SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den,
+                               target_bitrate, num_frames, infile_path);
+    simple_encode.ComputeFirstPassStats();
+    const int num_coding_frames = simple_encode.GetCodingFrameNum();
+    simple_encode.StartEncode();
+    for (int i = 0; i < num_coding_frames; ++i) {
+      EncodeFrameResult encode_frame_result;
+      simple_encode.EncodeFrame(&encode_frame_result);
+      quantize_index_list.push_back(encode_frame_result.quantize_index);
+      ref_sse_list.push_back(encode_frame_result.sse);
+      ref_psnr_list.push_back(encode_frame_result.psnr);
+      ref_bit_size_list.push_back(encode_frame_result.coding_data_bit_size);
+    }
+    simple_encode.EndEncode();
+  }
+  {
+    SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den,
+                               target_bitrate, num_frames, infile_path);
+    simple_encode.ComputeFirstPassStats();
+    const int num_coding_frames = simple_encode.GetCodingFrameNum();
+    EXPECT_EQ(static_cast<size_t>(num_coding_frames),
+              quantize_index_list.size());
+    simple_encode.StartEncode();
+    for (int i = 0; i < num_coding_frames; ++i) {
+      EncodeFrameResult encode_frame_result;
+      simple_encode.EncodeFrameWithQuantizeIndex(&encode_frame_result,
+                                                 quantize_index_list[i]);
+      EXPECT_EQ(encode_frame_result.quantize_index, quantize_index_list[i]);
+      EXPECT_EQ(encode_frame_result.sse, ref_sse_list[i]);
+      EXPECT_DOUBLE_EQ(encode_frame_result.psnr, ref_psnr_list[i]);
+      EXPECT_EQ(encode_frame_result.coding_data_bit_size, ref_bit_size_list[i]);
+    }
+    simple_encode.EndEncode();
+  }
+}
 }  // namespace
 
 }  // namespace vp9
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -4334,7 +4334,7 @@
 
 #if CONFIG_RATE_CTRL
     // This part needs to be after save_coding_context() because
-    // restore_coding_context may be called in the end of this function.
+    // restore_coding_context will be called in the end of this function.
     // TODO(angiebird): This is a hack for making sure the encoder use the
     // external_quantize_index exactly. Avoid this kind of hack later.
     if (cpi->encode_command.use_external_quantize_index) {
@@ -4518,7 +4518,7 @@
     }
 
     if (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF)
-      if (loop || !enable_acl) restore_coding_context(cpi);
+      if (loop) restore_coding_context(cpi);
   } while (loop);
 
 #ifdef AGGRESSIVE_VBR
@@ -4544,13 +4544,11 @@
     // Skip recoding, if model diff is below threshold
     const int thresh = compute_context_model_thresh(cpi);
     const int diff = compute_context_model_diff(cm);
-    if (diff < thresh) {
-      vpx_clear_system_state();
-      restore_coding_context(cpi);
-      return;
+    if (diff >= thresh) {
+      vp9_encode_frame(cpi);
     }
-
-    vp9_encode_frame(cpi);
+  }
+  if (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF) {
     vpx_clear_system_state();
     restore_coding_context(cpi);
   }