Modify encode breakout for static frames
authorYunqing Wang <yunqingwang@google.com>
Fri, 6 Sep 2013 00:10:58 +0000 (17:10 -0700)
committerYunqing Wang <yunqingwang@google.com>
Tue, 10 Sep 2013 16:06:03 +0000 (09:06 -0700)
Thank Paul for the suggestions. While turning on static-thresh
for static-image videos, a big jump on bitrate was seen. In this
patch, we detected static frames in the video using first-pass
stats. For different cases, disable encode breakout or reduce
encode breakout threshold to limit the skipping.

More modification need be done to break incorrect partition
picking pattern for static frames while skipping happens.

Change-Id: Ia25f47041af0f04e229c70a0185e12b0ffa6047f

vp9/encoder/vp9_firstpass.c
vp9/encoder/vp9_onyx_if.c
vp9/encoder/vp9_onyx_int.h
vp9/encoder/vp9_rdopt.c

index 0cbe3abb867d096504da6cd5a1be2639d86b77f1..c5b34858226e1f855043ece4c157f54aa46b4c42 100644 (file)
@@ -1717,6 +1717,8 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
     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 @@ void vp9_second_pass(VP9_COMP *cpi) {
     // 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);
@@ -2172,6 +2176,15 @@ void vp9_second_pass(VP9_COMP *cpi) {
     }
 #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....
     // If the previous group used an arf this frame has already benefited
index 94ac89d48df4c7b42c0924b6ca80bd69e5a3df6e..d53d2f26fa37214090bb547f47550fe2285e67d5 100644 (file)
@@ -1590,6 +1590,8 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) {
 
   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) {
@@ -3619,6 +3621,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
 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);
 
index 334a23c05641261e26dbc5a8c737d1268577528b..d83c3f7e05c72a1228317fc2bfbc84ada21fbd90 100644 (file)
@@ -495,6 +495,7 @@ typedef struct VP9_COMP {
   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 @@ typedef struct VP9_COMP {
   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.
index 53a064c393bd89c044346c412f9ed0f3e8d4c2ae..07850d4f64e0a725ebcf0456ae3bbf260e93ff3d 100644 (file)
@@ -2861,7 +2861,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
   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,18 +2872,23 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
       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,
                                    xd->plane[0].dst.stride, &sse);