Enable more precise background detection for partition decision
authorJingning Han <jingning@google.com>
Tue, 15 Apr 2014 18:41:39 +0000 (11:41 -0700)
committerJingning Han <jingning@google.com>
Wed, 16 Apr 2014 21:00:52 +0000 (14:00 -0700)
This commit compares the current original frame to the previous
original frame at 64x64 block level and decides if the entire
block belongs to background area. If it is in the background area,
skip non-RD partition search and copy the partition types of the
collocated block in the previous frame.

For vidyo1 in the rtc set, this makes the speed -5 coding speed
about 8% faster. The overall compression performance is down by
1.37% for rtc set.

Change-Id: Iccf920562fcc88f21d377fb6a44c547c8689b7ea

vp9/encoder/vp9_encodeframe.c

index c52e4f3..d924c63 100644 (file)
@@ -1565,6 +1565,42 @@ static void set_source_var_based_partition(VP9_COMP *cpi,
   }
 }
 
+static int is_background(VP9_COMP *cpi, const TileInfo *const tile,
+                         int mi_row, int mi_col) {
+  MACROBLOCK *const x = &cpi->mb;
+  uint8_t *src, *pre;
+  int src_stride, pre_stride;
+
+  const int row8x8_remaining = tile->mi_row_end - mi_row;
+  const int col8x8_remaining = tile->mi_col_end - mi_col;
+
+  int this_sad = 0;
+  int threshold = 0;
+
+  vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col);
+  src_stride = x->plane[0].src.stride;
+  src = x->plane[0].src.buf;
+  pre_stride = cpi->Last_Source->y_stride;
+  pre = cpi->Last_Source->y_buffer + (mi_row * MI_SIZE) * pre_stride +
+          (mi_col * MI_SIZE);
+
+  if (row8x8_remaining >= MI_BLOCK_SIZE &&
+      col8x8_remaining >= MI_BLOCK_SIZE) {
+    this_sad = cpi->fn_ptr[BLOCK_64X64].sdf(src, src_stride,
+                                            pre, pre_stride, 0x7fffffff);
+    threshold = (1 << 12);
+  } else {
+    int r, c;
+    for (r = 0; r < row8x8_remaining; r += 2)
+      for (c = 0; c < col8x8_remaining; c += 2)
+        this_sad += cpi->fn_ptr[BLOCK_16X16].sdf(src, src_stride, pre,
+                                                 pre_stride, 0x7fffffff);
+    threshold = (row8x8_remaining * col8x8_remaining) << 6;
+  }
+
+  return (this_sad < 2 * threshold);
+}
+
 static int sb_has_motion(const VP9_COMMON *cm, MODE_INFO **prev_mi_8x8) {
   const int mis = cm->mi_stride;
   int block_row, block_col;
@@ -3216,7 +3252,8 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
                             1, &dummy_rate, &dummy_dist);
         break;
       case REFERENCE_PARTITION:
-        if (cpi->sf.partition_check || sb_has_motion(cm, prev_mi_8x8)) {
+        if (cpi->sf.partition_check ||
+            !is_background(cpi, tile, mi_row, mi_col)) {
           nonrd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64,
                                &dummy_rate, &dummy_dist, 1, INT64_MAX);
         } else {