shithub: libvpx

Download patch

ref: 09ea74f194f12a78ba685e99f577ca698bf2b568
parent: 2040bb58fbec7d06d5bdb1f6628bb058d3132ebf
author: Marco <marpan@google.com>
date: Thu Oct 9 12:01:52 EDT 2014

Some updates for Speed 6/VAR_BASED_PARTITION.

Reduce the intra_cost_penalty for non-rd mode,
and some updates to VAR_BASED_PARTITION.

Visual tests show some improvement at Speed 6, for RTC clips.

Change-Id: If9090daf7aed14906a32d931a538ab544bbca606

--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -412,29 +412,47 @@
     return 1;
   }
 
-  // Vertical split is available on all but the bottom border.
-  if (mi_row + block_height / 2 < cm->mi_rows &&
-      vt.part_variances->vert[0].variance < threshold &&
-      vt.part_variances->vert[1].variance < threshold) {
-    BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_VERT);
-    set_block_size(cpi, mi_row, mi_col, subsize);
-    set_block_size(cpi, mi_row, mi_col + block_width / 2, subsize);
-    return 1;
+  // Only allow split for blocks above 16x16.
+  if (bsize > BLOCK_16X16) {
+    // Vertical split is available on all but the bottom border.
+    if (mi_row + block_height / 2 < cm->mi_rows &&
+        vt.part_variances->vert[0].variance < threshold &&
+        vt.part_variances->vert[1].variance < threshold) {
+      BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_VERT);
+      set_block_size(cpi, mi_row, mi_col, subsize);
+      set_block_size(cpi, mi_row, mi_col + block_width / 2, subsize);
+      return 1;
+    }
+
+    // Horizontal split is available on all but the right border.
+    if (mi_col + block_width / 2 < cm->mi_cols &&
+        vt.part_variances->horz[0].variance < threshold &&
+        vt.part_variances->horz[1].variance < threshold) {
+      BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_HORZ);
+      set_block_size(cpi, mi_row, mi_col, subsize);
+      set_block_size(cpi, mi_row + block_height / 2, mi_col, subsize);
+      return 1;
+    }
   }
 
-  // Horizontal split is available on all but the right border.
-  if (mi_col + block_width / 2 < cm->mi_cols &&
-      vt.part_variances->horz[0].variance < threshold &&
-      vt.part_variances->horz[1].variance < threshold) {
-    BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_HORZ);
-    set_block_size(cpi, mi_row, mi_col, subsize);
-    set_block_size(cpi, mi_row + block_height / 2, mi_col, subsize);
-    return 1;
+  // This will only allow 8x8 if the 16x16 variance is very large.
+  if (bsize == BLOCK_16X16) {
+    if (mi_col + block_width / 2 < cm->mi_cols &&
+        mi_row + block_height / 2 < cm->mi_rows &&
+        vt.part_variances->none.variance < (threshold << 6)) {
+      set_block_size(cpi, mi_row, mi_col, bsize);
+      return 1;
+    }
   }
   return 0;
 }
 
-// TODO(debargha): Fix this function and make it work as expected.
+// This function chooses partitioning based on the variance
+// between source and reconstructed last, where variance is
+// computed for 8x8 downsampled inputs. Some things to check:
+// using the last source rather than reconstructed last, and
+// allowing for small downsampling (4x4 or 2x2) for selection
+// of smaller block sizes (i.e., < 16x16).
 static void choose_partitioning(VP9_COMP *cpi,
                                 const TileInfo *const tile,
                                 int mi_row, int mi_col) {
@@ -549,27 +567,11 @@
         for (j = 0; j < 4; ++j) {
           const int x16_idx = ((j & 1) << 1);
           const int y16_idx = ((j >> 1) << 1);
-          // NOTE: This is a temporary hack to disable 8x8 partitions,
-          // since it works really bad - possibly due to a bug
-#define DISABLE_8X8_VAR_BASED_PARTITION
-#ifdef DISABLE_8X8_VAR_BASED_PARTITION
-          if (mi_row + y32_idx + y16_idx + 1 < cm->mi_rows &&
-              mi_row + x32_idx + x16_idx + 1 < cm->mi_cols) {
-            set_block_size(cpi,
-                           (mi_row + y32_idx + y16_idx),
-                           (mi_col + x32_idx + x16_idx),
-                           BLOCK_16X16);
-          } else {
-            for (k = 0; k < 4; ++k) {
-              const int x8_idx = (k & 1);
-              const int y8_idx = (k >> 1);
-              set_block_size(cpi,
-                             (mi_row + y32_idx + y16_idx + y8_idx),
-                             (mi_col + x32_idx + x16_idx + x8_idx),
-                             BLOCK_8X8);
-            }
-          }
-#else
+          // NOTE: Since this uses 8x8 downsampling for variance calculation
+          // we cannot really select block size 8x8 (or even 8x16/16x8),
+          // since we do not sufficient samples for variance.
+          // For now, 8x8 partition is only set if the variance of the 16x16
+          // block is very high. This is controlled in set_vt_partitioning.
           if (!set_vt_partitioning(cpi, &vt.split[i].split[j],
                                    BLOCK_16X16,
                                    mi_row + y32_idx + y16_idx,
@@ -583,7 +585,6 @@
                              BLOCK_8X8);
             }
           }
-#endif
         }
       }
     }
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -486,8 +486,12 @@
   // var_y and sse_y are saved to be used in skipping checking
   unsigned int var_y = UINT_MAX;
   unsigned int sse_y = UINT_MAX;
+  // Reduce the intra cost penalty for small blocks (<=16x16).
+  const int reduction_fac =
+      (cpi->sf.partition_search_type == VAR_BASED_PARTITION &&
+       bsize <= BLOCK_16X16) ? 4 : 1;
   const int intra_cost_penalty = vp9_get_intra_cost_penalty(
-      cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
+      cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth) / reduction_fac;
   const int64_t inter_mode_thresh = RDCOST(x->rdmult, x->rddiv,
                                            intra_cost_penalty, 0);
   const int intra_mode_cost = 50;