shithub: libvpx

Download patch

ref: f6bc783d630cd191567259279be1b578a4825244
parent: 2873d5608be29ad86837e4859c441626548575fb
parent: 939791a129819951bbdd187ba022d456efbc21d6
author: Yunqing Wang <[email protected]>
date: Tue Sep 10 06:04:30 EDT 2013

Merge "Modify encode breakout for static frames"

--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -1717,6 +1717,8 @@
     old_boost_score = boost_score;
   }
 
+  cpi->gf_zeromotion_pct = (int)(zero_motion_accumulator * 1000.0);
+
   // Don't allow a gf too near the next kf
   if ((cpi->twopass.frames_to_key - i) < MIN_GF_INTERVAL) {
     while (i < cpi->twopass.frames_to_key) {
@@ -2162,6 +2164,8 @@
     // Define next gf group and assign bits to it
     this_frame_copy = this_frame;
 
+    cpi->gf_zeromotion_pct = 0;
+
 #if CONFIG_MULTIPLE_ARF
     if (cpi->multi_arf_enabled) {
       define_fixed_arf_period(cpi);
@@ -2171,6 +2175,15 @@
 #if CONFIG_MULTIPLE_ARF
     }
 #endif
+
+    if (cpi->gf_zeromotion_pct > 995) {
+      // As long as max_thresh for encode breakout is small enough, it is ok
+      // to enable it for no-show frame, i.e. set enable_encode_breakout to 2.
+      if (!cpi->common.show_frame)
+        cpi->enable_encode_breakout = 0;
+      else
+        cpi->enable_encode_breakout = 2;
+    }
 
     // If we are going to code an altref frame at the end of the group
     // and the current frame is not a key frame....
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -1590,6 +1590,8 @@
 
   cpi->output_pkt_list = oxcf->output_pkt_list;
 
+  cpi->enable_encode_breakout = 1;
+
   if (cpi->pass == 1) {
     vp9_init_first_pass(cpi);
   } else if (cpi->pass == 2) {
@@ -3618,6 +3620,8 @@
 
 static void Pass2Encode(VP9_COMP *cpi, unsigned long *size,
                         unsigned char *dest, unsigned int *frame_flags) {
+
+  cpi->enable_encode_breakout = 1;
 
   if (!cpi->refresh_alt_ref_frame)
     vp9_second_pass(cpi);
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -495,6 +495,7 @@
   int last_boost;
   int kf_boost;
   int kf_zeromotion_pct;
+  int gf_zeromotion_pct;
 
   int64_t target_bandwidth;
   struct vpx_codec_pkt_list  *output_pkt_list;
@@ -656,6 +657,8 @@
   int initial_height;
 
   int number_spatial_layers;
+  int enable_encode_breakout;   // Default value is 1. From first pass stats,
+                                // encode_breakout may be disabled.
 
 #if CONFIG_MULTIPLE_ARF
   // ARF tracking variables.
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -2861,7 +2861,7 @@
   if (cpi->common.mcomp_filter_type == SWITCHABLE)
     *rate2 += get_switchable_rate(x);
 
-  if (!is_comp_pred) {
+  if (!is_comp_pred && cpi->enable_encode_breakout) {
     if (cpi->active_map_enabled && x->active_ptr[0] == 0)
       x->skip = 1;
     else if (x->encode_breakout) {
@@ -2872,17 +2872,22 @@
       unsigned int thresh_ac;
       // The encode_breakout input
       unsigned int encode_breakout = x->encode_breakout << 4;
+      int max_thresh = 36000;
 
+      // Use extreme low threshold for static frames to limit skipping.
+      if (cpi->enable_encode_breakout == 2)
+        max_thresh = 128;
+
       // Calculate threshold according to dequant value.
       thresh_ac = (xd->plane[0].dequant[1] * xd->plane[0].dequant[1]) / 9;
 
-      // Set a maximum for threshold to avoid big PSNR loss in low bitrate case.
-      if (thresh_ac > 36000)
-        thresh_ac = 36000;
-
       // Use encode_breakout input if it is bigger than internal threshold.
       if (thresh_ac < encode_breakout)
         thresh_ac = encode_breakout;
+
+      // Set a maximum for threshold to avoid big PSNR loss in low bitrate case.
+      if (thresh_ac > max_thresh)
+        thresh_ac = max_thresh;
 
       var = cpi->fn_ptr[y_size].vf(x->plane[0].src.buf, x->plane[0].src.stride,
                                    xd->plane[0].dst.buf,