shithub: libvpx

Download patch

ref: 90d13337daa6ab282ef4f2492ab069d440f600f2
parent: 276e568997bd1c1f049a48d92d1d1f4ee1afccd0
author: Deb Mukherjee <debargha@google.com>
date: Tue Feb 25 12:22:34 EST 2014

Refines variance based partitioning search

Instead of using source variance, this patch uses variance of the
frame difference between the source and the current frame to make
fixed size partition decisions. Also disables adjusting partitioning
if variance based or fixed size partitioning is used.

The latter change improves the speed substantially for speed 6, so
that speed 7 is now less than 3x the speed of speed 6. But speed
6 is 48% better in psnr on the rtc set compared to speed 7.

As compared to speed 5,
speed 6 is -37% in psnr at about 2.5x the speed,
speed 7 is -55% in psnr at about 7x the speed.

Change-Id: If61d80431d3e04ed304ac05832e773cdb2c0a578

--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -94,7 +94,8 @@
   128, 128, 128, 128, 128, 128, 128, 128
 };
 
-static unsigned int get_sby_perpixel_variance(VP9_COMP *cpi, MACROBLOCK *x,
+static unsigned int get_sby_perpixel_variance(VP9_COMP *cpi,
+                                              MACROBLOCK *x,
                                               BLOCK_SIZE bs) {
   unsigned int var, sse;
   var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf, x->plane[0].src.stride,
@@ -102,19 +103,49 @@
   return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
 }
 
-static BLOCK_SIZE get_rd_var_based_fixed_partition(VP9_COMP *cpi) {
-  unsigned int var = get_sby_perpixel_variance(cpi, &cpi->mb, BLOCK_64X64);
-  if (var < 256)
+static unsigned int get_sby_perpixel_diff_variance(VP9_COMP *cpi,
+                                                   MACROBLOCK *x,
+                                                   int mi_row,
+                                                   int mi_col,
+                                                   BLOCK_SIZE bs) {
+  const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
+  int offset = (mi_row * MI_SIZE) * yv12->y_stride + (mi_col * MI_SIZE);
+  unsigned int var, sse;
+  var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf,
+                           x->plane[0].src.stride,
+                           yv12->y_buffer + offset,
+                           yv12->y_stride,
+                           &sse);
+  return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
+}
+
+static BLOCK_SIZE get_rd_var_based_fixed_partition(VP9_COMP *cpi,
+                                                   int mi_row,
+                                                   int mi_col) {
+  unsigned int var = get_sby_perpixel_diff_variance(cpi, &cpi->mb,
+                                                    mi_row, mi_col,
+                                                    BLOCK_64X64);
+  if (var < 8)
     return BLOCK_64X64;
-  else
+  else if (var < 128)
     return BLOCK_32X32;
+  else if (var < 2048)
+    return BLOCK_16X16;
+  else
+    return BLOCK_8X8;
 }
 
-static BLOCK_SIZE get_nonrd_var_based_fixed_partition(VP9_COMP *cpi) {
-  unsigned int var = get_sby_perpixel_variance(cpi, &cpi->mb, BLOCK_64X64);
-  if (var < 1024)
+static BLOCK_SIZE get_nonrd_var_based_fixed_partition(VP9_COMP *cpi,
+                                                      int mi_row,
+                                                      int mi_col) {
+  unsigned int var = get_sby_perpixel_diff_variance(cpi, &cpi->mb,
+                                                    mi_row, mi_col,
+                                                    BLOCK_64X64);
+  if (var < 8)
+    return BLOCK_64X64;
+  else if (var < 64)
     return BLOCK_32X32;
-  else if (var < 4096)
+  else if (var < 2048)
     return BLOCK_16X16;
   else
     return BLOCK_8X8;
@@ -1262,7 +1293,8 @@
     x->mb_energy = vp9_block_energy(cpi, x, bsize);
   }
 
-  if (cpi->sf.adjust_partitioning_from_last_frame) {
+  if (cpi->sf.partition_search_type == SEARCH_PARTITION &&
+      cpi->sf.adjust_partitioning_from_last_frame) {
     // Check if any of the sub blocks are further split.
     if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) {
       sub_subsize = get_subsize(subsize, PARTITION_SPLIT);
@@ -1387,6 +1419,7 @@
     last_part_rate += x->partition_cost[pl][partition];
 
   if (cpi->sf.adjust_partitioning_from_last_frame
+      && cpi->sf.partition_search_type == SEARCH_PARTITION
       && partition != PARTITION_SPLIT && bsize > BLOCK_8X8
       && (mi_row + ms < cm->mi_rows || mi_row + (ms >> 1) == cm->mi_rows)
       && (mi_col + ms < cm->mi_cols || mi_col + (ms >> 1) == cm->mi_cols)) {
@@ -1986,7 +2019,7 @@
         // map to the same thing.
         BLOCK_SIZE bsize;
         set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
-        bsize = get_rd_var_based_fixed_partition(cpi);
+        bsize = get_rd_var_based_fixed_partition(cpi, mi_row, mi_col);
         set_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, bsize);
         rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
                          &dummy_rate, &dummy_dist, 1);
@@ -2368,7 +2401,9 @@
       // TODO(debargha): Implement VAR_BASED_PARTITION as a separate case.
       // Currently both VAR_BASED_FIXED_PARTITION/VAR_BASED_PARTITION
       // map to the same thing.
-      BLOCK_SIZE bsize = get_nonrd_var_based_fixed_partition(cpi);
+      BLOCK_SIZE bsize = get_nonrd_var_based_fixed_partition(cpi,
+                                                             mi_row,
+                                                             mi_col);
       nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col,
                           bsize, &dummy_rate, &dummy_dist, 1);
     } else {