Move hash tables in MACROBLOCK to a separate struct

BUG=aomedia:2618

Change-Id: I65a6549335e5d5ce22f986a789385a25576086d2
diff --git a/av1/encoder/block.h b/av1/encoder/block.h
index 55391c7..5a74567 100644
--- a/av1/encoder/block.h
+++ b/av1/encoder/block.h
@@ -307,16 +307,8 @@
 
   struct inter_modes_info *inter_modes_info;
 
-  // buffer for hash value calculation of a block
-  // used only in av1_get_block_hash_value()
-  // [first hash/second hash]
-  // [two buffers used ping-pong]
-  uint32_t *hash_value_buffer[2][2];
-  hash_table intrabc_hash_table;
-
-  CRC_CALCULATOR crc_calculator1;
-  CRC_CALCULATOR crc_calculator2;
-  int g_crc_initialized;
+  // Contains the hash table, hash function, and buffer used for intrabc
+  IntraBCHashInfo intrabc_hash_info;
 
   // These define limits to motion vector components to prevent them
   // from extending outside the UMV borders
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index eb102aa..53b47d4 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -5629,6 +5629,7 @@
   RD_COUNTS *const rdc = &cpi->td.rd_counts;
   GlobalMotionInfo *const gm_info = &cpi->gm_info;
   FrameProbInfo *const frame_probs = &cpi->frame_probs;
+  IntraBCHashInfo *const intrabc_hash_info = &x->intrabc_hash_info;
   int i;
 
   if (!cpi->sf.rt_sf.use_nonrd_pick_mode) {
@@ -5690,11 +5691,11 @@
       }
     }
 
-    av1_hash_table_init(&x->intrabc_hash_table, x);
-    av1_hash_table_create(&x->intrabc_hash_table);
+    av1_hash_table_init(intrabc_hash_info);
+    av1_hash_table_create(&intrabc_hash_info->intrabc_hash_table);
     hash_table_created = 1;
-    av1_generate_block_2x2_hash_value(cpi->source, block_hash_values[0],
-                                      is_block_same[0], &cpi->td.mb);
+    av1_generate_block_2x2_hash_value(intrabc_hash_info, cpi->source,
+                                      block_hash_values[0], is_block_same[0]);
     // Hash data generated for screen contents is used for intraBC ME
     const int min_alloc_size = block_size_wide[mi_params->mi_alloc_bsize];
     const int max_sb_size =
@@ -5703,12 +5704,12 @@
     for (int size = 4; size <= max_sb_size; size *= 2, src_idx = !src_idx) {
       const int dst_idx = !src_idx;
       av1_generate_block_hash_value(
-          cpi->source, size, block_hash_values[src_idx],
+          intrabc_hash_info, cpi->source, size, block_hash_values[src_idx],
           block_hash_values[dst_idx], is_block_same[src_idx],
-          is_block_same[dst_idx], &cpi->td.mb);
+          is_block_same[dst_idx]);
       if (size >= min_alloc_size) {
         av1_add_to_hash_map_by_row_with_precal_data(
-            &x->intrabc_hash_table, block_hash_values[dst_idx],
+            &intrabc_hash_info->intrabc_hash_table, block_hash_values[dst_idx],
             is_block_same[dst_idx][2], pic_width, pic_height, size);
       }
     }
@@ -6022,7 +6023,7 @@
   if ((!is_stat_generation_stage(cpi) && av1_use_hash_me(cpi) &&
        !cpi->sf.rt_sf.use_nonrd_pick_mode) ||
       hash_table_created) {
-    av1_hash_table_destroy(&x->intrabc_hash_table);
+    av1_hash_table_destroy(&intrabc_hash_info->intrabc_hash_table);
   }
 }
 
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 026634b..2d2e020 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -849,8 +849,8 @@
 
   for (int i = 0; i < 2; i++)
     for (int j = 0; j < 2; j++) {
-      aom_free(cpi->td.mb.hash_value_buffer[i][j]);
-      cpi->td.mb.hash_value_buffer[i][j] = NULL;
+      aom_free(cpi->td.mb.intrabc_hash_info.hash_value_buffer[i][j]);
+      cpi->td.mb.intrabc_hash_info.hash_value_buffer[i][j] = NULL;
     }
   aom_free(cpi->td.mb.mask_buf);
   cpi->td.mb.mask_buf = NULL;
@@ -3199,11 +3199,12 @@
   for (int x = 0; x < 2; x++)
     for (int y = 0; y < 2; y++)
       CHECK_MEM_ERROR(
-          cm, cpi->td.mb.hash_value_buffer[x][y],
-          (uint32_t *)aom_malloc(AOM_BUFFER_SIZE_FOR_BLOCK_HASH *
-                                 sizeof(*cpi->td.mb.hash_value_buffer[0][0])));
+          cm, cpi->td.mb.intrabc_hash_info.hash_value_buffer[x][y],
+          (uint32_t *)aom_malloc(
+              AOM_BUFFER_SIZE_FOR_BLOCK_HASH *
+              sizeof(*cpi->td.mb.intrabc_hash_info.hash_value_buffer[0][0])));
 
-  cpi->td.mb.g_crc_initialized = 0;
+  cpi->td.mb.intrabc_hash_info.g_crc_initialized = 0;
 
   CHECK_MEM_ERROR(cm, cpi->td.mb.mask_buf,
                   (int32_t *)aom_memalign(
diff --git a/av1/encoder/ethread.c b/av1/encoder/ethread.c
index b1c83ff..693270b 100644
--- a/av1/encoder/ethread.c
+++ b/av1/encoder/ethread.c
@@ -585,10 +585,10 @@
       for (int x = 0; x < 2; x++) {
         for (int y = 0; y < 2; y++) {
           memcpy(thread_data->td->hash_value_buffer[x][y],
-                 cpi->td.mb.hash_value_buffer[x][y],
+                 cpi->td.mb.intrabc_hash_info.hash_value_buffer[x][y],
                  AOM_BUFFER_SIZE_FOR_BLOCK_HASH *
                      sizeof(*thread_data->td->hash_value_buffer[0][0]));
-          thread_data->td->mb.hash_value_buffer[x][y] =
+          thread_data->td->mb.intrabc_hash_info.hash_value_buffer[x][y] =
               thread_data->td->hash_value_buffer[x][y];
         }
       }
diff --git a/av1/encoder/hash.c b/av1/encoder/hash.c
index c9348ce..3091037 100644
--- a/av1/encoder/hash.c
+++ b/av1/encoder/hash.c
@@ -61,8 +61,8 @@
   crc_calculator_init_table(p_crc_calculator);
 }
 
-uint32_t av1_get_crc_value(void *crc_calculator, uint8_t *p, int length) {
-  CRC_CALCULATOR *p_crc_calculator = (CRC_CALCULATOR *)crc_calculator;
+uint32_t av1_get_crc_value(CRC_CALCULATOR *p_crc_calculator, uint8_t *p,
+                           int length) {
   crc_calculator_reset(p_crc_calculator);
   crc_calculator_process_data(p_crc_calculator, p, length);
   return crc_calculator_get_crc(p_crc_calculator);
diff --git a/av1/encoder/hash.h b/av1/encoder/hash.h
index 826c004..d8e8cc3 100644
--- a/av1/encoder/hash.h
+++ b/av1/encoder/hash.h
@@ -32,7 +32,8 @@
 // calling av1_get_crc_value().
 void av1_crc_calculator_init(CRC_CALCULATOR *p_crc_calculator, uint32_t bits,
                              uint32_t truncPoly);
-uint32_t av1_get_crc_value(void *crc_calculator, uint8_t *p, int length);
+uint32_t av1_get_crc_value(CRC_CALCULATOR *p_crc_calculator, uint8_t *p,
+                           int length);
 
 // CRC32C: POLY = 0x82f63b78;
 typedef struct _CRC32C {
diff --git a/av1/encoder/hash_motion.c b/av1/encoder/hash_motion.c
index 96a9de4..310cde8 100644
--- a/av1/encoder/hash_motion.c
+++ b/av1/encoder/hash_motion.c
@@ -23,9 +23,10 @@
 
 // TODO(youzhou@microsoft.com): is higher than 8 bits screen content supported?
 // If yes, fix this function
-static void get_pixels_in_1D_char_array_by_block_2x2(uint8_t *y_src, int stride,
+static void get_pixels_in_1D_char_array_by_block_2x2(const uint8_t *y_src,
+                                                     int stride,
                                                      uint8_t *p_pixels_in1D) {
-  uint8_t *p_pel = y_src;
+  const uint8_t *p_pel = y_src;
   int index = 0;
   for (int i = 0; i < 2; i++) {
     for (int j = 0; j < 2; j++) {
@@ -35,10 +36,10 @@
   }
 }
 
-static void get_pixels_in_1D_short_array_by_block_2x2(uint16_t *y_src,
+static void get_pixels_in_1D_short_array_by_block_2x2(const uint16_t *y_src,
                                                       int stride,
                                                       uint16_t *p_pixels_in1D) {
-  uint16_t *p_pel = y_src;
+  const uint16_t *p_pel = y_src;
   int index = 0;
   for (int i = 0; i < 2; i++) {
     for (int j = 0; j < 2; j++) {
@@ -48,28 +49,28 @@
   }
 }
 
-static int is_block_2x2_row_same_value(uint8_t *p) {
+static int is_block_2x2_row_same_value(const uint8_t *p) {
   if (p[0] != p[1] || p[2] != p[3]) {
     return 0;
   }
   return 1;
 }
 
-static int is_block16_2x2_row_same_value(uint16_t *p) {
+static int is_block16_2x2_row_same_value(const uint16_t *p) {
   if (p[0] != p[1] || p[2] != p[3]) {
     return 0;
   }
   return 1;
 }
 
-static int is_block_2x2_col_same_value(uint8_t *p) {
+static int is_block_2x2_col_same_value(const uint8_t *p) {
   if ((p[0] != p[2]) || (p[1] != p[3])) {
     return 0;
   }
   return 1;
 }
 
-static int is_block16_2x2_col_same_value(uint16_t *p) {
+static int is_block16_2x2_col_same_value(const uint16_t *p) {
   if ((p[0] != p[2]) || (p[1] != p[3])) {
     return 0;
   }
@@ -91,13 +92,13 @@
   }
 }
 
-void av1_hash_table_init(hash_table *p_hash_table, MACROBLOCK *x) {
-  if (x->g_crc_initialized == 0) {
-    av1_crc_calculator_init(&x->crc_calculator1, 24, 0x5D6DCB);
-    av1_crc_calculator_init(&x->crc_calculator2, 24, 0x864CFB);
-    x->g_crc_initialized = 1;
+void av1_hash_table_init(IntraBCHashInfo *intrabc_hash_info) {
+  if (!intrabc_hash_info->g_crc_initialized) {
+    av1_crc_calculator_init(&intrabc_hash_info->crc_calculator1, 24, 0x5D6DCB);
+    av1_crc_calculator_init(&intrabc_hash_info->crc_calculator2, 24, 0x864CFB);
+    intrabc_hash_info->g_crc_initialized = 1;
   }
-  p_hash_table->p_lookup_table = NULL;
+  intrabc_hash_info->intrabc_hash_table.p_lookup_table = NULL;
 }
 
 void av1_hash_table_clear_all(hash_table *p_hash_table) {
@@ -179,14 +180,16 @@
   return 0;
 }
 
-void av1_generate_block_2x2_hash_value(const YV12_BUFFER_CONFIG *picture,
+void av1_generate_block_2x2_hash_value(IntraBCHashInfo *intrabc_hash_info,
+                                       const YV12_BUFFER_CONFIG *picture,
                                        uint32_t *pic_block_hash[2],
-                                       int8_t *pic_block_same_info[3],
-                                       MACROBLOCK *x) {
+                                       int8_t *pic_block_same_info[3]) {
   const int width = 2;
   const int height = 2;
   const int x_end = picture->y_crop_width - width + 1;
   const int y_end = picture->y_crop_height - height + 1;
+  CRC_CALCULATOR *calc_1 = &intrabc_hash_info->crc_calculator1;
+  CRC_CALCULATOR *calc_2 = &intrabc_hash_info->crc_calculator2;
 
   const int length = width * 2;
   if (picture->flags & YV12_FLAG_HIGHBITDEPTH) {
@@ -201,10 +204,10 @@
         pic_block_same_info[0][pos] = is_block16_2x2_row_same_value(p);
         pic_block_same_info[1][pos] = is_block16_2x2_col_same_value(p);
 
-        pic_block_hash[0][pos] = av1_get_crc_value(
-            &x->crc_calculator1, (uint8_t *)p, length * sizeof(p[0]));
-        pic_block_hash[1][pos] = av1_get_crc_value(
-            &x->crc_calculator2, (uint8_t *)p, length * sizeof(p[0]));
+        pic_block_hash[0][pos] =
+            av1_get_crc_value(calc_1, (uint8_t *)p, length * sizeof(p[0]));
+        pic_block_hash[1][pos] =
+            av1_get_crc_value(calc_2, (uint8_t *)p, length * sizeof(p[0]));
         pos++;
       }
       pos += width - 1;
@@ -221,9 +224,9 @@
         pic_block_same_info[1][pos] = is_block_2x2_col_same_value(p);
 
         pic_block_hash[0][pos] =
-            av1_get_crc_value(&x->crc_calculator1, p, length * sizeof(p[0]));
+            av1_get_crc_value(calc_1, p, length * sizeof(p[0]));
         pic_block_hash[1][pos] =
-            av1_get_crc_value(&x->crc_calculator2, p, length * sizeof(p[0]));
+            av1_get_crc_value(calc_2, p, length * sizeof(p[0]));
         pos++;
       }
       pos += width - 1;
@@ -231,13 +234,16 @@
   }
 }
 
-void av1_generate_block_hash_value(const YV12_BUFFER_CONFIG *picture,
+void av1_generate_block_hash_value(IntraBCHashInfo *intrabc_hash_info,
+                                   const YV12_BUFFER_CONFIG *picture,
                                    int block_size,
                                    uint32_t *src_pic_block_hash[2],
                                    uint32_t *dst_pic_block_hash[2],
                                    int8_t *src_pic_block_same_info[3],
-                                   int8_t *dst_pic_block_same_info[3],
-                                   MACROBLOCK *x) {
+                                   int8_t *dst_pic_block_same_info[3]) {
+  CRC_CALCULATOR *calc_1 = &intrabc_hash_info->crc_calculator1;
+  CRC_CALCULATOR *calc_2 = &intrabc_hash_info->crc_calculator2;
+
   const int pic_width = picture->y_crop_width;
   const int x_end = picture->y_crop_width - block_size + 1;
   const int y_end = picture->y_crop_height - block_size + 1;
@@ -256,14 +262,14 @@
       p[2] = src_pic_block_hash[0][pos + src_size * pic_width];
       p[3] = src_pic_block_hash[0][pos + src_size * pic_width + src_size];
       dst_pic_block_hash[0][pos] =
-          av1_get_crc_value(&x->crc_calculator1, (uint8_t *)p, length);
+          av1_get_crc_value(calc_1, (uint8_t *)p, length);
 
       p[0] = src_pic_block_hash[1][pos];
       p[1] = src_pic_block_hash[1][pos + src_size];
       p[2] = src_pic_block_hash[1][pos + src_size * pic_width];
       p[3] = src_pic_block_hash[1][pos + src_size * pic_width + src_size];
       dst_pic_block_hash[1][pos] =
-          av1_get_crc_value(&x->crc_calculator2, (uint8_t *)p, length);
+          av1_get_crc_value(calc_2, (uint8_t *)p, length);
 
       dst_pic_block_same_info[0][pos] =
           src_pic_block_same_info[0][pos] &&
@@ -390,15 +396,20 @@
   return 1;
 }
 
-void av1_get_block_hash_value(uint8_t *y_src, int stride, int block_size,
+void av1_get_block_hash_value(IntraBCHashInfo *intrabc_hash_info,
+                              const uint8_t *y_src, int stride, int block_size,
                               uint32_t *hash_value1, uint32_t *hash_value2,
-                              int use_highbitdepth, MACROBLOCK *x) {
-  uint32_t to_hash[4];
+                              int use_highbitdepth) {
   int add_value = hash_block_size_to_index(block_size);
   assert(add_value >= 0);
   add_value <<= kSrcBits;
   const int crc_mask = (1 << kSrcBits) - 1;
 
+  CRC_CALCULATOR *calc_1 = &intrabc_hash_info->crc_calculator1;
+  CRC_CALCULATOR *calc_2 = &intrabc_hash_info->crc_calculator2;
+  uint32_t **buf_1 = intrabc_hash_info->hash_value_buffer[0];
+  uint32_t **buf_2 = intrabc_hash_info->hash_value_buffer[1];
+
   // 2x2 subblock hash values in current CU
   int sub_block_in_width = (block_size >> 1);
   if (use_highbitdepth) {
@@ -410,12 +421,10 @@
         get_pixels_in_1D_short_array_by_block_2x2(
             y16_src + y_pos * stride + x_pos, stride, pixel_to_hash);
         assert(pos < AOM_BUFFER_SIZE_FOR_BLOCK_HASH);
-        x->hash_value_buffer[0][0][pos] =
-            av1_get_crc_value(&x->crc_calculator1, (uint8_t *)pixel_to_hash,
-                              sizeof(pixel_to_hash));
-        x->hash_value_buffer[1][0][pos] =
-            av1_get_crc_value(&x->crc_calculator2, (uint8_t *)pixel_to_hash,
-                              sizeof(pixel_to_hash));
+        buf_1[0][pos] = av1_get_crc_value(calc_1, (uint8_t *)pixel_to_hash,
+                                          sizeof(pixel_to_hash));
+        buf_2[0][pos] = av1_get_crc_value(calc_2, (uint8_t *)pixel_to_hash,
+                                          sizeof(pixel_to_hash));
       }
     }
   } else {
@@ -426,10 +435,10 @@
         get_pixels_in_1D_char_array_by_block_2x2(y_src + y_pos * stride + x_pos,
                                                  stride, pixel_to_hash);
         assert(pos < AOM_BUFFER_SIZE_FOR_BLOCK_HASH);
-        x->hash_value_buffer[0][0][pos] = av1_get_crc_value(
-            &x->crc_calculator1, pixel_to_hash, sizeof(pixel_to_hash));
-        x->hash_value_buffer[1][0][pos] = av1_get_crc_value(
-            &x->crc_calculator2, pixel_to_hash, sizeof(pixel_to_hash));
+        buf_1[0][pos] =
+            av1_get_crc_value(calc_1, pixel_to_hash, sizeof(pixel_to_hash));
+        buf_2[0][pos] =
+            av1_get_crc_value(calc_2, pixel_to_hash, sizeof(pixel_to_hash));
       }
     }
   }
@@ -441,6 +450,7 @@
   int dst_idx = 0;
 
   // 4x4 subblock hash values to current block hash values
+  uint32_t to_hash[4];
   for (int sub_width = 4; sub_width <= block_size; sub_width *= 2) {
     src_idx = 1 - src_idx;
     dst_idx = 1 - dst_idx;
@@ -454,24 +464,20 @@
         assert(srcPos + src_sub_block_in_width + 1 <
                AOM_BUFFER_SIZE_FOR_BLOCK_HASH);
         assert(dst_pos < AOM_BUFFER_SIZE_FOR_BLOCK_HASH);
-        to_hash[0] = x->hash_value_buffer[0][src_idx][srcPos];
-        to_hash[1] = x->hash_value_buffer[0][src_idx][srcPos + 1];
-        to_hash[2] =
-            x->hash_value_buffer[0][src_idx][srcPos + src_sub_block_in_width];
-        to_hash[3] = x->hash_value_buffer[0][src_idx]
-                                         [srcPos + src_sub_block_in_width + 1];
+        to_hash[0] = buf_1[src_idx][srcPos];
+        to_hash[1] = buf_1[src_idx][srcPos + 1];
+        to_hash[2] = buf_1[src_idx][srcPos + src_sub_block_in_width];
+        to_hash[3] = buf_1[src_idx][srcPos + src_sub_block_in_width + 1];
 
-        x->hash_value_buffer[0][dst_idx][dst_pos] = av1_get_crc_value(
-            &x->crc_calculator1, (uint8_t *)to_hash, sizeof(to_hash));
+        buf_1[dst_idx][dst_pos] =
+            av1_get_crc_value(calc_1, (uint8_t *)to_hash, sizeof(to_hash));
 
-        to_hash[0] = x->hash_value_buffer[1][src_idx][srcPos];
-        to_hash[1] = x->hash_value_buffer[1][src_idx][srcPos + 1];
-        to_hash[2] =
-            x->hash_value_buffer[1][src_idx][srcPos + src_sub_block_in_width];
-        to_hash[3] = x->hash_value_buffer[1][src_idx]
-                                         [srcPos + src_sub_block_in_width + 1];
-        x->hash_value_buffer[1][dst_idx][dst_pos] = av1_get_crc_value(
-            &x->crc_calculator2, (uint8_t *)to_hash, sizeof(to_hash));
+        to_hash[0] = buf_2[src_idx][srcPos];
+        to_hash[1] = buf_2[src_idx][srcPos + 1];
+        to_hash[2] = buf_2[src_idx][srcPos + src_sub_block_in_width];
+        to_hash[3] = buf_2[src_idx][srcPos + src_sub_block_in_width + 1];
+        buf_2[dst_idx][dst_pos] =
+            av1_get_crc_value(calc_2, (uint8_t *)to_hash, sizeof(to_hash));
         dst_pos++;
       }
     }
@@ -480,6 +486,6 @@
     sub_block_in_width >>= 1;
   }
 
-  *hash_value1 = (x->hash_value_buffer[0][dst_idx][0] & crc_mask) + add_value;
-  *hash_value2 = x->hash_value_buffer[1][dst_idx][0];
+  *hash_value1 = (buf_1[dst_idx][0] & crc_mask) + add_value;
+  *hash_value2 = buf_2[dst_idx][0];
 }
diff --git a/av1/encoder/hash_motion.h b/av1/encoder/hash_motion.h
index e21c339..e4ea1f3 100644
--- a/av1/encoder/hash_motion.h
+++ b/av1/encoder/hash_motion.h
@@ -16,6 +16,7 @@
 
 #include "aom/aom_integer.h"
 #include "aom_scale/yv12config.h"
+#include "av1/encoder/hash.h"
 #include "third_party/vector/vector.h"
 #ifdef __cplusplus
 extern "C" {
@@ -37,7 +38,22 @@
   Vector **p_lookup_table;
 } hash_table;
 
-void av1_hash_table_init(hash_table *p_hash_table, struct macroblock *x);
+struct intrabc_hash_info;
+
+typedef struct intrabc_hash_info {
+  // buffer for hash value calculation of a block
+  // used only in av1_get_block_hash_value()
+  // [first hash/second hash]
+  // [two buffers used ping-pong]
+  uint32_t *hash_value_buffer[2][2];
+  hash_table intrabc_hash_table;
+
+  CRC_CALCULATOR crc_calculator1;
+  CRC_CALCULATOR crc_calculator2;
+  int g_crc_initialized;
+} IntraBCHashInfo;
+
+void av1_hash_table_init(IntraBCHashInfo *intra_bc_hash_info);
 void av1_hash_table_clear_all(hash_table *p_hash_table);
 void av1_hash_table_destroy(hash_table *p_hash_table);
 void av1_hash_table_create(hash_table *p_hash_table);
@@ -47,17 +63,17 @@
                                      uint32_t hash_value);
 int32_t av1_has_exact_match(hash_table *p_hash_table, uint32_t hash_value1,
                             uint32_t hash_value2);
-void av1_generate_block_2x2_hash_value(const YV12_BUFFER_CONFIG *picture,
+void av1_generate_block_2x2_hash_value(IntraBCHashInfo *intra_bc_hash_info,
+                                       const YV12_BUFFER_CONFIG *picture,
                                        uint32_t *pic_block_hash[2],
-                                       int8_t *pic_block_same_info[3],
-                                       struct macroblock *x);
-void av1_generate_block_hash_value(const YV12_BUFFER_CONFIG *picture,
+                                       int8_t *pic_block_same_info[3]);
+void av1_generate_block_hash_value(IntraBCHashInfo *intra_bc_hash_info,
+                                   const YV12_BUFFER_CONFIG *picture,
                                    int block_size,
                                    uint32_t *src_pic_block_hash[2],
                                    uint32_t *dst_pic_block_hash[2],
                                    int8_t *src_pic_block_same_info[3],
-                                   int8_t *dst_pic_block_same_info[3],
-                                   struct macroblock *x);
+                                   int8_t *dst_pic_block_same_info[3]);
 void av1_add_to_hash_map_by_row_with_precal_data(hash_table *p_hash_table,
                                                  uint32_t *pic_hash[2],
                                                  int8_t *pic_is_same,
@@ -72,9 +88,11 @@
 // block_size x block_size has the same color in all columns
 int av1_hash_is_vertical_perfect(const YV12_BUFFER_CONFIG *picture,
                                  int block_size, int x_start, int y_start);
-void av1_get_block_hash_value(uint8_t *y_src, int stride, int block_size,
+
+void av1_get_block_hash_value(IntraBCHashInfo *intrabc_hash_info,
+                              const uint8_t *y_src, int stride, int block_size,
                               uint32_t *hash_value1, uint32_t *hash_value2,
-                              int use_highbitdepth, struct macroblock *x);
+                              int use_highbitdepth);
 
 #ifdef __cplusplus
 }  // extern "C"
diff --git a/av1/encoder/mcomp.c b/av1/encoder/mcomp.c
index 750cdbb..43f7f5c 100644
--- a/av1/encoder/mcomp.c
+++ b/av1/encoder/mcomp.c
@@ -1500,66 +1500,67 @@
   return var;
 }
 
-void av1_intrabc_hash_search(const AV1_COMP *cpi, MACROBLOCK *x,
-                             BLOCK_SIZE bsize, const MV *ref_mv, int *bestsme,
-                             FULLPEL_MV *best_mv) {
-  if (!av1_use_hash_me(cpi)) return;
+int av1_intrabc_hash_search(const AV1_COMP *cpi, const MACROBLOCKD *xd,
+                            const FULLPEL_MOTION_SEARCH_PARAMS *ms_params,
+                            IntraBCHashInfo *intrabc_hash_info,
+                            FULLPEL_MV *best_mv) {
+  if (!av1_use_hash_me(cpi)) return INT_MAX;
 
-  const aom_variance_fn_ptr_t *fn_ptr = &cpi->fn_ptr[bsize];
-  const int block_height = block_size_high[bsize];
+  const BLOCK_SIZE bsize = ms_params->bsize;
   const int block_width = block_size_wide[bsize];
-  const int mi_row = x->e_mbd.mi_row;
-  const int mi_col = x->e_mbd.mi_col;
+  const int block_height = block_size_high[bsize];
+
+  if (block_width != block_height) return INT_MAX;
+
+  const FullMvLimits *mv_limits = &ms_params->mv_limits;
+  const MSBuffers *ms_buffer = &ms_params->ms_buffers;
+
+  const uint8_t *src = ms_buffer->src->buf;
+  const int src_stride = ms_buffer->src->stride;
+
+  const int mi_row = xd->mi_row;
+  const int mi_col = xd->mi_col;
   const int x_pos = mi_col * MI_SIZE;
   const int y_pos = mi_row * MI_SIZE;
 
-  if (block_height == block_width) {
-    uint8_t *what = x->plane[0].src.buf;
-    const int what_stride = x->plane[0].src.stride;
-    uint32_t hash_value1, hash_value2;
-    FULLPEL_MV best_hash_mv;
-    int best_hash_cost = INT_MAX;
+  uint32_t hash_value1, hash_value2;
+  int best_hash_cost = INT_MAX;
 
-    // for the hashMap
-    hash_table *ref_frame_hash = &x->intrabc_hash_table;
+  // for the hashMap
+  hash_table *ref_frame_hash = &intrabc_hash_info->intrabc_hash_table;
 
-    av1_get_block_hash_value(what, what_stride, block_width, &hash_value1,
-                             &hash_value2, is_cur_buf_hbd(&x->e_mbd), x);
+  av1_get_block_hash_value(intrabc_hash_info, src, src_stride, block_width,
+                           &hash_value1, &hash_value2, is_cur_buf_hbd(xd));
 
-    const int count = av1_hash_table_count(ref_frame_hash, hash_value1);
-    // for intra, at lest one matching can be found, itself.
-    if (count <= 1) {
-      return;
-    }
+  const int count = av1_hash_table_count(ref_frame_hash, hash_value1);
+  if (count <= 1) {
+    return INT_MAX;
+  }
 
-    Iterator iterator =
-        av1_hash_get_first_iterator(ref_frame_hash, hash_value1);
-    for (int i = 0; i < count; i++, aom_iterator_increment(&iterator)) {
-      block_hash ref_block_hash = *(block_hash *)(aom_iterator_get(&iterator));
-      if (hash_value2 == ref_block_hash.hash_value2) {
-        // Make sure the prediction is from valid area.
-        const MV dv = { GET_MV_SUBPEL(ref_block_hash.y - y_pos),
-                        GET_MV_SUBPEL(ref_block_hash.x - x_pos) };
-        if (!av1_is_dv_valid(dv, &cpi->common, &x->e_mbd, mi_row, mi_col, bsize,
-                             cpi->common.seq_params.mib_size_log2))
-          continue;
+  Iterator iterator = av1_hash_get_first_iterator(ref_frame_hash, hash_value1);
+  for (int i = 0; i < count; i++, aom_iterator_increment(&iterator)) {
+    block_hash ref_block_hash = *(block_hash *)(aom_iterator_get(&iterator));
+    if (hash_value2 == ref_block_hash.hash_value2) {
+      // Make sure the prediction is from valid area.
+      const MV dv = { GET_MV_SUBPEL(ref_block_hash.y - y_pos),
+                      GET_MV_SUBPEL(ref_block_hash.x - x_pos) };
+      if (!av1_is_dv_valid(dv, &cpi->common, xd, mi_row, mi_col, bsize,
+                           cpi->common.seq_params.mib_size_log2))
+        continue;
 
-        FULLPEL_MV hash_mv;
-        hash_mv.col = ref_block_hash.x - x_pos;
-        hash_mv.row = ref_block_hash.y - y_pos;
-        if (!av1_is_fullmv_in_range(&x->mv_limits, hash_mv)) continue;
-        const int refCost = av1_get_mvpred_var(x, &hash_mv, ref_mv, fn_ptr);
-        if (refCost < best_hash_cost) {
-          best_hash_cost = refCost;
-          best_hash_mv = hash_mv;
-        }
+      FULLPEL_MV hash_mv;
+      hash_mv.col = ref_block_hash.x - x_pos;
+      hash_mv.row = ref_block_hash.y - y_pos;
+      if (!av1_is_fullmv_in_range(mv_limits, hash_mv)) continue;
+      const int refCost = get_mvpred_var_cost(ms_params, &hash_mv);
+      if (refCost < best_hash_cost) {
+        best_hash_cost = refCost;
+        *best_mv = hash_mv;
       }
     }
-    if (best_hash_cost < *bestsme) {
-      *best_mv = best_hash_mv;
-      *bestsme = best_hash_cost;
-    }
   }
+
+  return best_hash_cost;
 }
 
 static int vector_match(int16_t *ref, int16_t *src, int bwl) {
@@ -3341,23 +3342,6 @@
                            x->errorperbit, mv_cost_type);
 }
 
-int av1_get_mvpred_var(const MACROBLOCK *x, const FULLPEL_MV *best_mv,
-                       const MV *ref_mv, const aom_variance_fn_ptr_t *vfp) {
-  const MACROBLOCKD *const xd = &x->e_mbd;
-  const struct buf_2d *const what = &x->plane[0].src;
-  const struct buf_2d *const in_what = &xd->plane[0].pre[0];
-  const MV mv = get_mv_from_fullmv(best_mv);
-  const MV_COST_TYPE mv_cost_type = x->mv_cost_type;
-  unsigned int sse, var;
-
-  var = vfp->vf(what->buf, what->stride, get_buf_from_fullmv(in_what, best_mv),
-                in_what->stride, &sse);
-
-  return var + mv_err_cost(&mv, ref_mv, x->nmv_vec_cost,
-                           CONVERT_TO_CONST_MVCOST(x->mv_cost_stack),
-                           x->errorperbit, mv_cost_type);
-}
-
 static INLINE int get_mvpred_av_var(const MV_COST_PARAMS *mv_cost_params,
                                     const FULLPEL_MV best_mv,
                                     const uint8_t *second_pred,
diff --git a/av1/encoder/mcomp.h b/av1/encoder/mcomp.h
index eb2024c..73135d8 100644
--- a/av1/encoder/mcomp.h
+++ b/av1/encoder/mcomp.h
@@ -75,8 +75,6 @@
 
 int av1_get_mvpred_sse(const MACROBLOCK *x, const FULLPEL_MV *best_mv,
                        const MV *ref_mv, const aom_variance_fn_ptr_t *vfp);
-int av1_get_mvpred_var(const MACROBLOCK *x, const FULLPEL_MV *best_mv,
-                       const MV *ref_mv, const aom_variance_fn_ptr_t *vfp);
 int av1_get_mvpred_compound_var(const MV_COST_PARAMS *ms_params,
                                 const FULLPEL_MV best_mv,
                                 const uint8_t *second_pred, const uint8_t *mask,
@@ -220,9 +218,10 @@
                           const int step_param, int *cost_list,
                           FULLPEL_MV *best_mv, FULLPEL_MV *second_best_mv);
 
-void av1_intrabc_hash_search(const struct AV1_COMP *cpi, MACROBLOCK *x,
-                             BLOCK_SIZE bsize, const MV *ref_mv, int *bestsme,
-                             FULLPEL_MV *best_mv);
+int av1_intrabc_hash_search(const struct AV1_COMP *cpi, const MACROBLOCKD *xd,
+                            const FULLPEL_MOTION_SEARCH_PARAMS *ms_params,
+                            IntraBCHashInfo *intrabc_hash_info,
+                            FULLPEL_MV *best_mv);
 
 int av1_obmc_full_pixel_search(const FULLPEL_MV start_mv,
                                const FULLPEL_MOTION_SEARCH_PARAMS *ms_params,
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index f406939..9f27786 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -2747,12 +2747,17 @@
 
     const int step_param = cpi->mv_search_params.mv_step_param;
     const FULLPEL_MV start_mv = get_fullmv_from_mv(&dv_ref.as_mv);
-    int_mv best_mv;
+    IntraBCHashInfo *intrabc_hash_info = &x->intrabc_hash_info;
+    int_mv best_mv, best_hash_mv;
 
     int bestsme = av1_full_pixel_search(start_mv, &fullms_params, step_param,
                                         NULL, &best_mv.as_fullmv, NULL);
-    av1_intrabc_hash_search(cpi, x, bsize, &dv_ref.as_mv, &bestsme,
-                            &best_mv.as_fullmv);
+    const int hashsme = av1_intrabc_hash_search(
+        cpi, xd, &fullms_params, intrabc_hash_info, &best_hash_mv.as_fullmv);
+    if (hashsme < bestsme) {
+      best_mv = best_hash_mv;
+      bestsme = hashsme;
+    }
 
     if (bestsme == INT_MAX) continue;
     const MV dv = get_mv_from_fullmv(&best_mv.as_fullmv);