shithub: libvpx

Download patch

ref: 255866419de9b802db5d9beb504af1f1ba72e5f2
parent: add0587faeb9e6a52695d6e94353c640c3a8bf58
parent: 0c65aed099565c3117dc4d3f89d0e782b4ff7577
author: Jerome Jiang <jianj@google.com>
date: Tue Jan 17 16:02:52 EST 2017

Merge "vp9: Set low variance flag when partition is copied."

--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -924,7 +924,7 @@
   const int low_res = (cm->width <= 352 && cm->height <= 288);
   int variance4x4downsample[16];
   int segment_id;
-  int offset = cm->mi_stride * mi_row + mi_col;
+  int sb_offset = (cm->mi_stride >> 3) * (mi_row >> 3) + (mi_col >> 3);
 
   set_offsets(cpi, tile, x, mi_row, mi_col, BLOCK_64X64);
   segment_id = xd->mi[0]->segment_id;
@@ -1035,6 +1035,7 @@
       if (mi_col + block_width / 2 < cm->mi_cols &&
           mi_row + block_height / 2 < cm->mi_rows) {
         set_block_size(cpi, x, xd, mi_row, mi_col, BLOCK_64X64);
+        x->variance_low[0] = 1;
         chroma_check(cpi, x, bsize, y_sad, is_key_frame);
         return 0;
       }
@@ -1045,11 +1046,13 @@
     // TODO(jianj) : tune the threshold.
     if (cpi->sf.copy_partition_flag && cpi->rc.frames_since_key > 1 &&
         segment_id == CR_SEGMENT_ID_BASE &&
-        cpi->prev_segment_id[offset] == CR_SEGMENT_ID_BASE &&
+        cpi->prev_segment_id[sb_offset] == CR_SEGMENT_ID_BASE &&
         y_sad_last < cpi->vbp_threshold_copy) {
       if (cpi->prev_partition != NULL) {
         copy_prev_partition(cpi, BLOCK_64X64, mi_row, mi_col);
         chroma_check(cpi, x, bsize, y_sad, is_key_frame);
+        memcpy(x->variance_low, &(cpi->prev_variance_low[sb_offset * 25]),
+               sizeof(x->variance_low));
         return 0;
       }
     }
@@ -1249,7 +1252,9 @@
 
   if (cm->frame_type != KEY_FRAME && cpi->sf.copy_partition_flag) {
     update_prev_partition(cpi, BLOCK_64X64, mi_row, mi_col);
-    cpi->prev_segment_id[offset] = segment_id;
+    cpi->prev_segment_id[sb_offset] = segment_id;
+    memcpy(&(cpi->prev_variance_low[sb_offset * 25]), x->variance_low,
+           sizeof(x->variance_low));
   }
 
   if (cpi->sf.short_circuit_low_temp_var) {
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -456,6 +456,9 @@
   vpx_free(cpi->prev_segment_id);
   cpi->prev_segment_id = NULL;
 
+  vpx_free(cpi->prev_variance_low);
+  cpi->prev_variance_low = NULL;
+
   vp9_cyclic_refresh_free(cpi->cyclic_refresh);
   cpi->cyclic_refresh = NULL;
 
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -633,6 +633,12 @@
   // Previous Partition Info
   BLOCK_SIZE *prev_partition;
   int8_t *prev_segment_id;
+  // Used to save the status of whether a block has a low variance in
+  // choose_partitioning. 0 for 64x64, 1~2 for 64x32, 3~4 for 32x64, 5~8 for
+  // 32x32, 9~24 for 16x16.
+  // This is for the last frame and is copied to the current frame
+  // when partition copy happens.
+  uint8_t *prev_variance_low;
 
   LevelConstraint level_constraint;
 } VP9_COMP;
--- a/vp9/encoder/vp9_speed_features.c
+++ b/vp9/encoder/vp9_speed_features.c
@@ -509,8 +509,13 @@
             cm->mi_stride * cm->mi_rows, sizeof(BLOCK_SIZE));
       }
       if (cpi->prev_segment_id == NULL) {
-        cpi->prev_segment_id =
-            (int8_t *)vpx_calloc(cm->mi_stride * cm->mi_rows, sizeof(int8_t));
+        cpi->prev_segment_id = (int8_t *)vpx_calloc(
+            (cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1), sizeof(int8_t));
+      }
+      if (cpi->prev_variance_low == NULL) {
+        cpi->prev_variance_low = (uint8_t *)vpx_calloc(
+            (cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1) * 25,
+            sizeof(uint8_t));
       }
     }
     sf->mv.subpel_force_stop = (content == VP9E_CONTENT_SCREEN) ? 3 : 2;