Pack MVCost variables in MACROBLOCK to its own struct

BUG=aomedia:2618

Change-Id: I3d0e401d9ba504ab83f897fdb3b7ccac4cc839c0
diff --git a/av1/encoder/av1_quantize.c b/av1/encoder/av1_quantize.c
index 569784a..390124f 100644
--- a/av1/encoder/av1_quantize.c
+++ b/av1/encoder/av1_quantize.c
@@ -729,9 +729,9 @@
   x->skip_block = segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP);
   x->qindex = qindex;
 
-  set_error_per_bit(x, rdmult);
-
-  av1_initialize_me_consts(cpi, x, qindex);
+  MvCostInfo *mv_cost_info = &x->mv_cost_info;
+  av1_set_error_per_bit(mv_cost_info, rdmult);
+  av1_set_sad_per_bit(cpi, mv_cost_info, qindex);
 }
 
 void av1_frame_init_quantizer(AV1_COMP *cpi) {
diff --git a/av1/encoder/block.h b/av1/encoder/block.h
index 5a74567..826107a 100644
--- a/av1/encoder/block.h
+++ b/av1/encoder/block.h
@@ -209,13 +209,28 @@
   uint8_t *tmp_best_mask_buf;  // backup of the best segmentation mask
 } CompoundTypeRdBuffers;
 
-enum {
-  MV_COST_ENTROPY,    // Use the entropy rate of the mv as the cost
-  MV_COST_L1_LOWRES,  // Use the l1 norm of the mv as the cost (<480p)
-  MV_COST_L1_MIDRES,  // Use the l1 norm of the mv as the cost (>=480p)
-  MV_COST_L1_HDRES,   // Use the l1 norm of the mv as the cost (>=720p)
-  MV_COST_NONE        // Use 0 as as cost irrespective of the current mv
-} UENUM1BYTE(MV_COST_TYPE);
+typedef struct {
+  // A multiplier that converts mv cost to l2 error.
+  int errorperbit;
+  // A multiplier that converts mv cost to l1 error.
+  int sadperbit;
+
+  int nmv_joint_cost[MV_JOINTS];
+
+  // Below are the entropy costs needed to encode a given mv.
+  // nmv_costs_(hp_)alloc are two arrays that holds the memory
+  // for holding the mv cost. But since the motion vectors can be negative, we
+  // shift them to the middle and store the resulting pointer in nmvcost(_hp)
+  // for easier referencing. Finally, nmv_cost_stack points to the nmvcost array
+  // with the mv precision we are currently working with. In essence, only
+  // mv_cost_stack is needed for motion search, the other can be considered
+  // private.
+  int nmv_cost_alloc[2][MV_VALS];
+  int nmv_cost_hp_alloc[2][MV_VALS];
+  int *nmv_cost[2];
+  int *nmv_cost_hp[2];
+  int **mv_cost_stack;
+} MvCostInfo;
 
 struct inter_modes_info;
 typedef struct macroblock MACROBLOCK;
@@ -252,12 +267,6 @@
   int skip_block;
   int qindex;
 
-  // The equivalent error at the current rdmult of one whole bit (not one
-  // bitcost unit).
-  int errorperbit;
-  // The equivalend SAD error of one (whole) bit at the current quantizer
-  // for large blocks.
-  int sadperbit;
   int rdmult;
   int mb_energy;
   int sb_energy_level;
@@ -279,13 +288,6 @@
   int pred_mv_sad[REF_FRAMES];
   int best_pred_mv_sad;
 
-  int nmv_vec_cost[MV_JOINTS];
-  int nmv_costs[2][MV_VALS];
-  int nmv_costs_hp[2][MV_VALS];
-  int *nmvcost[2];
-  int *nmvcost_hp[2];
-  int **mv_cost_stack;
-
   int32_t *wsrc_buf;
   int32_t *mask_buf;
   uint8_t *above_pred_buf;
@@ -314,6 +316,9 @@
   // from extending outside the UMV borders
   FullMvLimits mv_limits;
 
+  // Stores the entropy cost needed to encode a motion vector.
+  MvCostInfo mv_cost_info;
+
   uint8_t blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE];
   uint8_t tx_type_map[MAX_MIB_SIZE * MAX_MIB_SIZE];
 
@@ -466,9 +471,6 @@
              [INTER_REFS_PER_FRAME];
   int cost_stride;
 
-  // The type of mv cost used during motion search
-  MV_COST_TYPE mv_cost_type;
-
   uint8_t search_ref_frame[REF_FRAMES];
 
 #if CONFIG_AV1_HIGHBITDEPTH
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 6fd73e7..429405d 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -246,7 +246,7 @@
 }
 
 static AOM_INLINE void set_ssim_rdmult(const AV1_COMP *const cpi,
-                                       MACROBLOCK *const x,
+                                       MvCostInfo *const mv_cost_info,
                                        const BLOCK_SIZE bsize, const int mi_row,
                                        const int mi_col, int *const rdmult) {
   const AV1_COMMON *const cm = &cpi->common;
@@ -278,7 +278,7 @@
 
   *rdmult = (int)((double)(*rdmult) * geom_mean_of_scale + 0.5);
   *rdmult = AOMMAX(*rdmult, 0);
-  set_error_per_bit(x, *rdmult);
+  av1_set_error_per_bit(mv_cost_info, *rdmult);
   aom_clear_system_state();
 }
 
@@ -321,7 +321,7 @@
   geom_mean_of_scale = exp(geom_mean_of_scale / base_block_count);
   int rdmult = (int)((double)orig_rdmult * geom_mean_of_scale + 0.5);
   rdmult = AOMMAX(rdmult, 0);
-  set_error_per_bit(x, rdmult);
+  av1_set_error_per_bit(&x->mv_cost_info, rdmult);
   aom_clear_system_state();
   if (bsize == cm->seq_params.sb_size) {
     const int rdmult_sb = set_deltaq_rdmult(cpi, xd);
@@ -374,7 +374,7 @@
   }
 
   if (cpi->oxcf.tuning == AOM_TUNE_SSIM) {
-    set_ssim_rdmult(cpi, x, bsize, mi_row, mi_col, &x->rdmult);
+    set_ssim_rdmult(cpi, &x->mv_cost_info, bsize, mi_row, mi_col, &x->rdmult);
   }
 #if CONFIG_TUNE_VMAF
   if (cpi->oxcf.tuning == AOM_TUNE_VMAF_WITHOUT_PREPROCESSING ||
@@ -821,7 +821,7 @@
   const int orig_rdmult = x->rdmult;
   setup_block_rdmult(cpi, x, mi_row, mi_col, bsize, aq_mode, mbmi);
   // Set error per bit for current rdmult
-  set_error_per_bit(x, x->rdmult);
+  av1_set_error_per_bit(&x->mv_cost_info, x->rdmult);
   av1_rd_cost_update(x->rdmult, &best_rd);
 
   // Find best coding mode & reconstruct the MB so it is available
@@ -4986,7 +4986,7 @@
           mi_col != tile_info->mi_col_start)
         break;
       av1_fill_mv_costs(xd->tile_ctx, cm->features.cur_frame_force_integer_mv,
-                        cm->features.allow_high_precision_mv, x);
+                        cm->features.allow_high_precision_mv, &x->mv_cost_info);
       break;
     default: assert(0);
   }
@@ -5898,7 +5898,7 @@
 
   av1_frame_init_quantizer(cpi);
   av1_initialize_rd_consts(cpi);
-  av1_initialize_me_consts(cpi, x, quant_params->base_qindex);
+  av1_set_sad_per_bit(cpi, &x->mv_cost_info, quant_params->base_qindex);
 
   init_encode_frame_mb_context(cpi);
   set_default_interp_skip_flags(cm, &cpi->interp_search_flags);
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c
index 706c24d..41331f4 100644
--- a/av1/encoder/firstpass.c
+++ b/av1/encoder/firstpass.c
@@ -219,7 +219,6 @@
   FULLPEL_MV start_mv = get_fullmv_from_mv(ref_mv);
   int tmp_err;
   const BLOCK_SIZE bsize = xd->mi[0]->sb_type;
-  aom_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize];
   const int new_mv_mode_penalty = NEW_MV_MODE_PENALTY;
   const int sr = get_search_range(&cpi->initial_dimensions);
   const int step_param = 3 + sr;
@@ -237,7 +236,10 @@
                                   &this_best_mv, NULL);
 
   if (tmp_err < INT_MAX) {
-    tmp_err = av1_get_mvpred_sse(x, &this_best_mv, ref_mv, &v_fn_ptr) +
+    aom_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize];
+    const MSBuffers *ms_buffers = &ms_params.ms_buffers;
+    tmp_err = av1_get_mvpred_sse(&ms_params.mv_cost_params, this_best_mv,
+                                 &v_fn_ptr, ms_buffers->src, ms_buffers->ref) +
               new_mv_mode_penalty;
   }
 
diff --git a/av1/encoder/mcomp.c b/av1/encoder/mcomp.c
index 424c162..13fa807 100644
--- a/av1/encoder/mcomp.c
+++ b/av1/encoder/mcomp.c
@@ -33,15 +33,16 @@
 #include "av1/encoder/reconinter_enc.h"
 
 static INLINE void init_mv_cost_params(MV_COST_PARAMS *mv_cost_params,
-                                       const MACROBLOCK *x, const MV *ref_mv) {
+                                       const MvCostInfo *mv_cost_info,
+                                       const MV *ref_mv) {
   mv_cost_params->ref_mv = ref_mv;
   mv_cost_params->full_ref_mv = get_fullmv_from_mv(ref_mv);
-  mv_cost_params->error_per_bit = x->errorperbit;
-  mv_cost_params->sad_per_bit = x->sadperbit;
-  mv_cost_params->mvjcost = x->nmv_vec_cost;
-  mv_cost_params->mvcost[0] = x->mv_cost_stack[0];
-  mv_cost_params->mvcost[1] = x->mv_cost_stack[1];
-  mv_cost_params->mv_cost_type = x->mv_cost_type;
+  mv_cost_params->mv_cost_type = MV_COST_ENTROPY;
+  mv_cost_params->error_per_bit = mv_cost_info->errorperbit;
+  mv_cost_params->sad_per_bit = mv_cost_info->sadperbit;
+  mv_cost_params->mvjcost = mv_cost_info->nmv_joint_cost;
+  mv_cost_params->mvcost[0] = mv_cost_info->mv_cost_stack[0];
+  mv_cost_params->mvcost[1] = mv_cost_info->mv_cost_stack[1];
 }
 
 static INLINE void init_ms_buffers(MSBuffers *ms_buffers, const MACROBLOCK *x) {
@@ -84,7 +85,7 @@
   av1_set_mv_search_range(&ms_params->mv_limits, ref_mv);
 
   // Mvcost params
-  init_mv_cost_params(&ms_params->mv_cost_params, x, ref_mv);
+  init_mv_cost_params(&ms_params->mv_cost_params, &x->mv_cost_info, ref_mv);
 }
 
 void av1_make_default_subpel_ms_params(SUBPEL_MOTION_SEARCH_PARAMS *ms_params,
@@ -101,7 +102,7 @@
   av1_set_subpel_mv_search_range(&ms_params->mv_limits, &x->mv_limits, ref_mv);
 
   // Mvcost params
-  init_mv_cost_params(&ms_params->mv_cost_params, x, ref_mv);
+  init_mv_cost_params(&ms_params->mv_cost_params, &x->mv_cost_info, ref_mv);
 
   // Subpel variance params
   ms_params->var_params.vfp = &cpi->fn_ptr[bsize];
@@ -3385,22 +3386,18 @@
 // =============================================================================
 //  Public cost function: mv_cost + pred error
 // =============================================================================
-int av1_get_mvpred_sse(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;
+int av1_get_mvpred_sse(const MV_COST_PARAMS *mv_cost_params,
+                       const FULLPEL_MV best_mv,
+                       const aom_variance_fn_ptr_t *vfp,
+                       const struct buf_2d *src, const struct buf_2d *pre) {
+  const MV mv = get_mv_from_fullmv(&best_mv);
   unsigned int sse, var;
 
-  var = vfp->vf(what->buf, what->stride, get_buf_from_fullmv(in_what, best_mv),
-                in_what->stride, &sse);
+  var = vfp->vf(src->buf, src->stride, get_buf_from_fullmv(pre, &best_mv),
+                pre->stride, &sse);
   (void)var;
 
-  return sse + mv_err_cost(&mv, ref_mv, x->nmv_vec_cost,
-                           CONVERT_TO_CONST_MVCOST(x->mv_cost_stack),
-                           x->errorperbit, mv_cost_type);
+  return sse + mv_err_cost_(&mv, mv_cost_params);
 }
 
 static INLINE int get_mvpred_av_var(const MV_COST_PARAMS *mv_cost_params,
@@ -3409,13 +3406,11 @@
                                     const aom_variance_fn_ptr_t *vfp,
                                     const struct buf_2d *src,
                                     const struct buf_2d *pre) {
-  const struct buf_2d *const what = src;
-  const struct buf_2d *const in_what = pre;
   const MV mv = get_mv_from_fullmv(&best_mv);
   unsigned int unused;
 
-  return vfp->svaf(get_buf_from_fullmv(in_what, &best_mv), in_what->stride, 0,
-                   0, what->buf, what->stride, &unused, second_pred) +
+  return vfp->svaf(get_buf_from_fullmv(pre, &best_mv), pre->stride, 0, 0,
+                   src->buf, src->stride, &unused, second_pred) +
          mv_err_cost_(&mv, mv_cost_params);
 }
 
@@ -3424,14 +3419,12 @@
     const uint8_t *second_pred, const uint8_t *mask, int mask_stride,
     int invert_mask, const aom_variance_fn_ptr_t *vfp, const struct buf_2d *src,
     const struct buf_2d *pre) {
-  const struct buf_2d *const what = src;
-  const struct buf_2d *const in_what = pre;
   const MV mv = get_mv_from_fullmv(&best_mv);
   unsigned int unused;
 
-  return vfp->msvf(what->buf, what->stride, 0, 0,
-                   get_buf_from_fullmv(in_what, &best_mv), in_what->stride,
-                   second_pred, mask, mask_stride, invert_mask, &unused) +
+  return vfp->msvf(src->buf, src->stride, 0, 0,
+                   get_buf_from_fullmv(pre, &best_mv), pre->stride, second_pred,
+                   mask, mask_stride, invert_mask, &unused) +
          mv_err_cost_(&mv, mv_cost_params);
 }
 
diff --git a/av1/encoder/mcomp.h b/av1/encoder/mcomp.h
index 7d1b3f0..b3db173 100644
--- a/av1/encoder/mcomp.h
+++ b/av1/encoder/mcomp.h
@@ -60,21 +60,32 @@
 // =============================================================================
 //  Cost functions
 // =============================================================================
+
+enum {
+  MV_COST_ENTROPY,    // Use the entropy rate of the mv as the cost
+  MV_COST_L1_LOWRES,  // Use the l1 norm of the mv as the cost (<480p)
+  MV_COST_L1_MIDRES,  // Use the l1 norm of the mv as the cost (>=480p)
+  MV_COST_L1_HDRES,   // Use the l1 norm of the mv as the cost (>=720p)
+  MV_COST_NONE        // Use 0 as as cost irrespective of the current mv
+} UENUM1BYTE(MV_COST_TYPE);
+
 typedef struct {
   const MV *ref_mv;
   FULLPEL_MV full_ref_mv;
+  MV_COST_TYPE mv_cost_type;
   const int *mvjcost;
   const int *mvcost[2];
   int error_per_bit;
   int sad_per_bit;
-  MV_COST_TYPE mv_cost_type;
 } MV_COST_PARAMS;
 
 int av1_mv_bit_cost(const MV *mv, const MV *ref_mv, const int *mvjcost,
                     int *mvcost[2], int weight);
 
-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_sse(const MV_COST_PARAMS *mv_cost_params,
+                       const FULLPEL_MV best_mv,
+                       const aom_variance_fn_ptr_t *vfp,
+                       const struct buf_2d *src, const struct buf_2d *pre);
 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,
diff --git a/av1/encoder/motion_search_facade.c b/av1/encoder/motion_search_facade.c
index 83e8318..92aae90 100644
--- a/av1/encoder/motion_search_facade.c
+++ b/av1/encoder/motion_search_facade.c
@@ -60,6 +60,7 @@
       av1_get_scaled_ref_frame(cpi, ref);
   const int mi_row = xd->mi_row;
   const int mi_col = xd->mi_col;
+  const MvCostInfo *mv_cost_info = &x->mv_cost_info;
 
   if (scaled_ref_frame) {
     // Swap out the reference frame for a version that's been scaled to
@@ -270,8 +271,8 @@
     this_mv.as_mv = get_mv_from_fullmv(&best_mv->as_fullmv);
     const int ref_mv_idx = mbmi->ref_mv_idx;
     const int this_mv_rate =
-        av1_mv_bit_cost(&this_mv.as_mv, &ref_mv, x->nmv_vec_cost,
-                        x->mv_cost_stack, MV_COST_WEIGHT);
+        av1_mv_bit_cost(&this_mv.as_mv, &ref_mv, mv_cost_info->nmv_joint_cost,
+                        mv_cost_info->mv_cost_stack, MV_COST_WEIGHT);
     mode_info[ref_mv_idx].full_search_mv.as_int = this_mv.as_int;
     mode_info[ref_mv_idx].full_mv_rate = this_mv_rate;
 
@@ -347,8 +348,9 @@
       default: assert(0 && "Invalid motion mode!\n");
     }
   }
-  *rate_mv = av1_mv_bit_cost(&best_mv->as_mv, &ref_mv, x->nmv_vec_cost,
-                             x->mv_cost_stack, MV_COST_WEIGHT);
+  *rate_mv =
+      av1_mv_bit_cost(&best_mv->as_mv, &ref_mv, mv_cost_info->nmv_joint_cost,
+                      mv_cost_info->mv_cost_stack, MV_COST_WEIGHT);
 
   if (cpi->sf.mv_sf.adaptive_motion_search &&
       mbmi->motion_mode == SIMPLE_TRANSLATION)
@@ -370,6 +372,7 @@
   assert(has_second_ref(mbmi));
   const int_mv init_mv[2] = { cur_mv[0], cur_mv[1] };
   const int refs[2] = { mbmi->ref_frame[0], mbmi->ref_frame[1] };
+  const MvCostInfo *mv_cost_info = &x->mv_cost_info;
   int_mv ref_mv[2];
   int ite, ref;
 
@@ -525,9 +528,9 @@
 
   for (ref = 0; ref < 2; ++ref) {
     const int_mv curr_ref_mv = av1_get_ref_mv(x, ref);
-    *rate_mv +=
-        av1_mv_bit_cost(&cur_mv[ref].as_mv, &curr_ref_mv.as_mv, x->nmv_vec_cost,
-                        x->mv_cost_stack, MV_COST_WEIGHT);
+    *rate_mv += av1_mv_bit_cost(&cur_mv[ref].as_mv, &curr_ref_mv.as_mv,
+                                mv_cost_info->nmv_joint_cost,
+                                mv_cost_info->mv_cost_stack, MV_COST_WEIGHT);
   }
 }
 
@@ -545,6 +548,7 @@
   const int ref = mbmi->ref_frame[ref_idx];
   const int_mv ref_mv = av1_get_ref_mv(x, ref_idx);
   struct macroblockd_plane *const pd = &xd->plane[0];
+  const MvCostInfo *mv_cost_info = &x->mv_cost_info;
 
   struct buf_2d backup_yv12[MAX_MB_PLANE];
   const YV12_BUFFER_CONFIG *const scaled_ref_frame =
@@ -632,8 +636,9 @@
 
   *rate_mv = 0;
 
-  *rate_mv += av1_mv_bit_cost(this_mv, &ref_mv.as_mv, x->nmv_vec_cost,
-                              x->mv_cost_stack, MV_COST_WEIGHT);
+  *rate_mv +=
+      av1_mv_bit_cost(this_mv, &ref_mv.as_mv, mv_cost_info->nmv_joint_cost,
+                      mv_cost_info->mv_cost_stack, MV_COST_WEIGHT);
 }
 
 static AOM_INLINE void build_second_inter_pred(const AV1_COMP *cpi,
diff --git a/av1/encoder/mv_prec.h b/av1/encoder/mv_prec.h
index 8df8b96..9e31c74 100644
--- a/av1/encoder/mv_prec.h
+++ b/av1/encoder/mv_prec.h
@@ -32,15 +32,16 @@
 static AOM_INLINE void av1_set_high_precision_mv(
     AV1_COMP *cpi, int allow_high_precision_mv,
     int cur_frame_force_integer_mv) {
-  MACROBLOCK *const x = &cpi->td.mb;
+  MvCostInfo *const mv_cost_info = &cpi->td.mb.mv_cost_info;
   const int copy_hp = cpi->common.features.allow_high_precision_mv =
       allow_high_precision_mv && !cur_frame_force_integer_mv;
-  x->nmvcost[0] = &x->nmv_costs[0][MV_MAX];
-  x->nmvcost[1] = &x->nmv_costs[1][MV_MAX];
-  x->nmvcost_hp[0] = &x->nmv_costs_hp[0][MV_MAX];
-  x->nmvcost_hp[1] = &x->nmv_costs_hp[1][MV_MAX];
-  int *(*src)[2] = copy_hp ? &x->nmvcost_hp : &x->nmvcost;
-  x->mv_cost_stack = *src;
+
+  mv_cost_info->nmv_cost[0] = &mv_cost_info->nmv_cost_alloc[0][MV_MAX];
+  mv_cost_info->nmv_cost[1] = &mv_cost_info->nmv_cost_alloc[1][MV_MAX];
+  mv_cost_info->nmv_cost_hp[0] = &mv_cost_info->nmv_cost_hp_alloc[0][MV_MAX];
+  mv_cost_info->nmv_cost_hp[1] = &mv_cost_info->nmv_cost_hp_alloc[1][MV_MAX];
+  mv_cost_info->mv_cost_stack =
+      copy_hp ? mv_cost_info->nmv_cost_hp : mv_cost_info->nmv_cost;
 }
 
 void av1_pick_and_set_high_precision_mv(AV1_COMP *cpi, int qindex);
diff --git a/av1/encoder/nonrd_pickmode.c b/av1/encoder/nonrd_pickmode.c
index 43b1928..5564f0d 100644
--- a/av1/encoder/nonrd_pickmode.c
+++ b/av1/encoder/nonrd_pickmode.c
@@ -167,8 +167,8 @@
   // calculate the bit cost on motion vector
   MV mvp_full = get_mv_from_fullmv(&tmp_mv->as_fullmv);
 
-  *rate_mv = av1_mv_bit_cost(&mvp_full, &ref_mv, x->nmv_vec_cost,
-                             x->mv_cost_stack, MV_COST_WEIGHT);
+  *rate_mv = av1_mv_bit_cost(&mvp_full, &ref_mv, x->mv_cost_info.nmv_joint_cost,
+                             x->mv_cost_info.mv_cost_stack, MV_COST_WEIGHT);
 
   // TODO(kyslov) Account for Rate Mode!
   rv = !(RDCOST(x->rdmult, (*rate_mv), 0) > best_rd_sofar);
@@ -182,8 +182,9 @@
         xd, cm, &ms_params, subpel_start_mv, &tmp_mv->as_mv, &dis,
         &x->pred_sse[ref], NULL);
 
-    *rate_mv = av1_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmv_vec_cost,
-                               x->mv_cost_stack, MV_COST_WEIGHT);
+    *rate_mv =
+        av1_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->mv_cost_info.nmv_joint_cost,
+                        x->mv_cost_info.mv_cost_stack, MV_COST_WEIGHT);
   }
 
   if (scaled_ref_frame) {
@@ -222,9 +223,9 @@
     best_mv.as_mv.col >>= 3;
     MV ref_mv = av1_get_ref_mv(x, 0).as_mv;
 
-    *rate_mv =
-        av1_mv_bit_cost(&frame_mv[NEWMV][ref_frame].as_mv, &ref_mv,
-                        x->nmv_vec_cost, x->mv_cost_stack, MV_COST_WEIGHT);
+    *rate_mv = av1_mv_bit_cost(&frame_mv[NEWMV][ref_frame].as_mv, &ref_mv,
+                               x->mv_cost_info.nmv_joint_cost,
+                               x->mv_cost_info.mv_cost_stack, MV_COST_WEIGHT);
     frame_mv[NEWMV][ref_frame].as_mv.row >>= 3;
     frame_mv[NEWMV][ref_frame].as_mv.col >>= 3;
 
diff --git a/av1/encoder/rd.c b/av1/encoder/rd.c
index e48c771..81a77a2 100644
--- a/av1/encoder/rd.c
+++ b/av1/encoder/rd.c
@@ -437,11 +437,16 @@
   return AOMMAX((int)(pow(q, RD_THRESH_POW) * 5.12), 8);
 }
 
-void av1_initialize_me_consts(const AV1_COMP *cpi, MACROBLOCK *x, int qindex) {
+void av1_set_sad_per_bit(const AV1_COMP *cpi, MvCostInfo *mv_cost_info,
+                         int qindex) {
   switch (cpi->common.seq_params.bit_depth) {
-    case AOM_BITS_8: x->sadperbit = sad_per_bit_lut_8[qindex]; break;
-    case AOM_BITS_10: x->sadperbit = sad_per_bit_lut_10[qindex]; break;
-    case AOM_BITS_12: x->sadperbit = sad_per_bit_lut_12[qindex]; break;
+    case AOM_BITS_8: mv_cost_info->sadperbit = sad_per_bit_lut_8[qindex]; break;
+    case AOM_BITS_10:
+      mv_cost_info->sadperbit = sad_per_bit_lut_10[qindex];
+      break;
+    case AOM_BITS_12:
+      mv_cost_info->sadperbit = sad_per_bit_lut_12[qindex];
+      break;
     default:
       assert(0 && "bit_depth should be AOM_BITS_8, AOM_BITS_10 or AOM_BITS_12");
   }
@@ -565,20 +570,21 @@
 }
 
 void av1_fill_mv_costs(const FRAME_CONTEXT *fc, int integer_mv, int usehp,
-                       MACROBLOCK *x) {
-  x->nmvcost[0] = &x->nmv_costs[0][MV_MAX];
-  x->nmvcost[1] = &x->nmv_costs[1][MV_MAX];
-  x->nmvcost_hp[0] = &x->nmv_costs_hp[0][MV_MAX];
-  x->nmvcost_hp[1] = &x->nmv_costs_hp[1][MV_MAX];
+                       MvCostInfo *mv_cost_info) {
+  mv_cost_info->nmv_cost[0] = &mv_cost_info->nmv_cost_alloc[0][MV_MAX];
+  mv_cost_info->nmv_cost[1] = &mv_cost_info->nmv_cost_alloc[1][MV_MAX];
+  mv_cost_info->nmv_cost_hp[0] = &mv_cost_info->nmv_cost_hp_alloc[0][MV_MAX];
+  mv_cost_info->nmv_cost_hp[1] = &mv_cost_info->nmv_cost_hp_alloc[1][MV_MAX];
   if (integer_mv) {
-    av1_build_nmv_cost_table(x->nmv_vec_cost, x->nmvcost, &fc->nmvc,
+    mv_cost_info->mv_cost_stack = (int **)&mv_cost_info->nmv_cost;
+    av1_build_nmv_cost_table(mv_cost_info->nmv_joint_cost,
+                             mv_cost_info->mv_cost_stack, &fc->nmvc,
                              MV_SUBPEL_NONE);
-    x->mv_cost_stack = (int **)&x->nmvcost;
   } else {
-    int *(*src)[2] = usehp ? &x->nmvcost_hp : &x->nmvcost;
-    x->mv_cost_stack = *src;
-    av1_build_nmv_cost_table(
-        x->nmv_vec_cost, usehp ? x->nmvcost_hp : x->nmvcost, &fc->nmvc, usehp);
+    mv_cost_info->mv_cost_stack =
+        usehp ? mv_cost_info->nmv_cost_hp : mv_cost_info->nmv_cost;
+    av1_build_nmv_cost_table(mv_cost_info->nmv_joint_cost,
+                             mv_cost_info->mv_cost_stack, &fc->nmvc, usehp);
   }
 }
 
@@ -586,13 +592,14 @@
   AV1_COMMON *const cm = &cpi->common;
   MACROBLOCK *const x = &cpi->td.mb;
   RD_OPT *const rd = &cpi->rd;
+  MvCostInfo *mv_cost_info = &x->mv_cost_info;
 
   aom_clear_system_state();
 
   rd->RDMULT = av1_compute_rd_mult(
       cpi, cm->quant_params.base_qindex + cm->quant_params.y_dc_delta_q);
 
-  set_error_per_bit(x, rd->RDMULT);
+  av1_set_error_per_bit(mv_cost_info, rd->RDMULT);
 
   set_block_thresholds(cm, rd);
 
@@ -600,7 +607,7 @@
        cpi->oxcf.mv_cost_upd_freq != COST_UPD_OFF) ||
       frame_is_intra_only(cm) || (cm->current_frame.frame_number & 0x07) == 1)
     av1_fill_mv_costs(cm->fc, cm->features.cur_frame_force_integer_mv,
-                      cm->features.allow_high_precision_mv, x);
+                      cm->features.allow_high_precision_mv, mv_cost_info);
 
   if (!cpi->sf.rt_sf.use_nonrd_pick_mode && frame_is_intra_only(cm) &&
       cm->features.allow_screen_content_tools &&
diff --git a/av1/encoder/rd.h b/av1/encoder/rd.h
index 1addbae..d56813e 100644
--- a/av1/encoder/rd.h
+++ b/av1/encoder/rd.h
@@ -231,8 +231,9 @@
 
 void av1_initialize_rd_consts(struct AV1_COMP *cpi);
 
-void av1_initialize_me_consts(const struct AV1_COMP *cpi, MACROBLOCK *x,
-                              int qindex);
+// Sets the multiplier to convert mv cost to l1 error during motion search.
+void av1_set_sad_per_bit(const struct AV1_COMP *cpi, MvCostInfo *mv_cost_info,
+                         int qindex);
 
 void av1_model_rd_from_var_lapndz(int64_t var, unsigned int n,
                                   unsigned int qstep, int *rate, int64_t *dist);
@@ -280,9 +281,9 @@
                  uint8_t *ref_y_buffer, int ref_y_stride, int ref_frame,
                  BLOCK_SIZE block_size);
 
-static INLINE void set_error_per_bit(MACROBLOCK *x, int rdmult) {
-  x->errorperbit = rdmult >> RD_EPB_SHIFT;
-  x->errorperbit += (x->errorperbit == 0);
+// Sets the multiplier to convert mv cost to l2 error during motion search.
+static INLINE void av1_set_error_per_bit(MvCostInfo *mv_cost_info, int rdmult) {
+  mv_cost_info->errorperbit = AOMMAX(rdmult >> RD_EPB_SHIFT, 1);
 }
 
 // Get the threshold for R-D optimization of coefficients depending upon mode
@@ -357,7 +358,7 @@
                           const int num_planes);
 
 void av1_fill_mv_costs(const FRAME_CONTEXT *fc, int integer_mv, int usehp,
-                       MACROBLOCK *x);
+                       MvCostInfo *mv_cost_info);
 
 int av1_get_adaptive_rdmult(const struct AV1_COMP *cpi, double beta);
 
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 3c3fccd..9152ad5 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -1085,9 +1085,9 @@
         *rate_mv = 0;
         for (int i = 0; i < 2; ++i) {
           const int_mv ref_mv = av1_get_ref_mv(x, i);
-          *rate_mv +=
-              av1_mv_bit_cost(&cur_mv[i].as_mv, &ref_mv.as_mv, x->nmv_vec_cost,
-                              x->mv_cost_stack, MV_COST_WEIGHT);
+          *rate_mv += av1_mv_bit_cost(
+              &cur_mv[i].as_mv, &ref_mv.as_mv, x->mv_cost_info.nmv_joint_cost,
+              x->mv_cost_info.mv_cost_stack, MV_COST_WEIGHT);
         }
       }
     } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
@@ -1103,9 +1103,9 @@
                                                      NULL, 0, rate_mv, 1);
       } else {
         const int_mv ref_mv = av1_get_ref_mv(x, 1);
-        *rate_mv =
-            av1_mv_bit_cost(&cur_mv[1].as_mv, &ref_mv.as_mv, x->nmv_vec_cost,
-                            x->mv_cost_stack, MV_COST_WEIGHT);
+        *rate_mv = av1_mv_bit_cost(
+            &cur_mv[1].as_mv, &ref_mv.as_mv, x->mv_cost_info.nmv_joint_cost,
+            x->mv_cost_info.mv_cost_stack, MV_COST_WEIGHT);
       }
     } else {
       assert(this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV);
@@ -1121,9 +1121,9 @@
                                                      NULL, 0, rate_mv, 0);
       } else {
         const int_mv ref_mv = av1_get_ref_mv(x, 0);
-        *rate_mv =
-            av1_mv_bit_cost(&cur_mv[0].as_mv, &ref_mv.as_mv, x->nmv_vec_cost,
-                            x->mv_cost_stack, MV_COST_WEIGHT);
+        *rate_mv = av1_mv_bit_cost(
+            &cur_mv[0].as_mv, &ref_mv.as_mv, x->mv_cost_info.nmv_joint_cost,
+            x->mv_cost_info.mv_cost_stack, MV_COST_WEIGHT);
       }
     }
   } else {
@@ -1391,9 +1391,10 @@
 
           // Keep the refined MV and WM parameters.
           if (mv0.as_int != mbmi->mv[0].as_int) {
-            tmp_rate_mv = av1_mv_bit_cost(&mbmi->mv[0].as_mv, &ref_mv.as_mv,
-                                          x->nmv_vec_cost, x->mv_cost_stack,
-                                          MV_COST_WEIGHT);
+            tmp_rate_mv =
+                av1_mv_bit_cost(&mbmi->mv[0].as_mv, &ref_mv.as_mv,
+                                x->mv_cost_info.nmv_joint_cost,
+                                x->mv_cost_info.mv_cost_stack, MV_COST_WEIGHT);
             if (cpi->sf.mv_sf.adaptive_motion_search) {
               x->pred_mv[mbmi->ref_frame[0]] = mbmi->mv[0].as_mv;
             }
@@ -2390,8 +2391,9 @@
                     mode_info[i].rate_mv + mode_info[i].drl_cost;
                 const int_mv ref_mv = av1_get_ref_mv(x, 0);
                 this_rate_mv = av1_mv_bit_cost(
-                    &mode_info[i].mv.as_mv, &ref_mv.as_mv, x->nmv_vec_cost,
-                    x->mv_cost_stack, MV_COST_WEIGHT);
+                    &mode_info[i].mv.as_mv, &ref_mv.as_mv,
+                    x->mv_cost_info.nmv_joint_cost,
+                    x->mv_cost_info.mv_cost_stack, MV_COST_WEIGHT);
                 const int this_cost = this_rate_mv + drl_cost;
 
                 if (compare_cost <= this_cost) {
diff --git a/av1/encoder/temporal_filter.c b/av1/encoder/temporal_filter.c
index 4b76a54..98ce7e4 100644
--- a/av1/encoder/temporal_filter.c
+++ b/av1/encoder/temporal_filter.c
@@ -91,7 +91,6 @@
   MACROBLOCKD *const mbd = &mb->e_mbd;
   const struct buf_2d ori_src_buf = mb->plane[0].src;
   const struct buf_2d ori_pre_buf = mbd->plane[0].pre[0];
-  const MV_COST_TYPE ori_mv_cost_type = mb->mv_cost_type;
 
   // Parameters used for motion search.
   FULLPEL_MOTION_SEARCH_PARAMS full_ms_params;
@@ -127,20 +126,18 @@
   int_mv best_mv;  // Searched motion vector.
   int block_mse = INT_MAX;
   MV block_mv = kZeroMv;
-  mb->mv_cost_type = mv_cost_type;
 
   av1_make_default_fullpel_ms_params(&full_ms_params, cpi, mb, block_size,
                                      &baseline_mv, &ss_cfg,
                                      /*fine_search_interval=*/0);
   full_ms_params.run_mesh_search = 1;
   full_ms_params.search_method = full_search_method;
+  full_ms_params.mv_cost_params.mv_cost_type = mv_cost_type;
+
   av1_full_pixel_search(start_mv, &full_ms_params, step_param,
                         cond_cost_list(cpi, cost_list), &best_mv.as_fullmv,
                         NULL);
 
-  // Since we are merely refining the result from full pixel search, we don't
-  // need regularization for subpel search
-  mb->mv_cost_type = MV_COST_NONE;
   if (force_integer_mv == 1) {  // Only do full search on the entire block.
     const int mv_row = best_mv.as_mv.row;
     const int mv_col = best_mv.as_mv.col;
@@ -157,6 +154,10 @@
                                       &baseline_mv, cost_list);
     ms_params.forced_stop = EIGHTH_PEL;
     ms_params.var_params.subpel_search_type = subpel_search_type;
+    // Since we are merely refining the result from full pixel search, we don't
+    // need regularization for subpel search
+    ms_params.mv_cost_params.mv_cost_type = MV_COST_NONE;
+
     MV subpel_start_mv = get_mv_from_fullmv(&best_mv.as_fullmv);
     error = cpi->mv_search_params.find_fractional_mv_step(
         &mb->e_mbd, &cpi->common, &ms_params, subpel_start_mv, &best_mv.as_mv,
@@ -177,24 +178,26 @@
         const int offset = i * y_stride + j;
         mb->plane[0].src.buf = frame_to_filter->y_buffer + y_offset + offset;
         mbd->plane[0].pre[0].buf = ref_frame->y_buffer + y_offset + offset;
-        mb->mv_cost_type = mv_cost_type;
 
         av1_make_default_fullpel_ms_params(&full_ms_params, cpi, mb,
                                            subblock_size, &baseline_mv, &ss_cfg,
                                            /*fine_search_interval=*/0);
         full_ms_params.run_mesh_search = 1;
         full_ms_params.search_method = full_search_method;
+        full_ms_params.mv_cost_params.mv_cost_type = mv_cost_type;
+
         av1_full_pixel_search(start_mv, &full_ms_params, step_param,
                               cond_cost_list(cpi, cost_list),
                               &best_mv.as_fullmv, NULL);
 
-        // Since we are merely refining the result from full pixel search, we
-        // don't need regularization for subpel search
-        mb->mv_cost_type = MV_COST_NONE;
         av1_make_default_subpel_ms_params(&ms_params, cpi, mb, subblock_size,
                                           &baseline_mv, cost_list);
         ms_params.forced_stop = EIGHTH_PEL;
         ms_params.var_params.subpel_search_type = subpel_search_type;
+        // Since we are merely refining the result from full pixel search, we
+        // don't need regularization for subpel search
+        ms_params.mv_cost_params.mv_cost_type = MV_COST_NONE;
+
         subpel_start_mv = get_mv_from_fullmv(&best_mv.as_fullmv);
         error = cpi->mv_search_params.find_fractional_mv_step(
             &mb->e_mbd, &cpi->common, &ms_params, subpel_start_mv,
@@ -209,7 +212,6 @@
   // Restore input state.
   mb->plane[0].src = ori_src_buf;
   mbd->plane[0].pre[0] = ori_pre_buf;
-  mb->mv_cost_type = ori_mv_cost_type;
 
   // Make partition decision.
   tf_determine_block_partition(block_mv, block_mse, subblock_mvs,
@@ -961,13 +963,14 @@
 
   // TODO(yunqing): For INTNL_ARF_UPDATE type, the following me initialization
   // is used somewhere unexpectedly. Should be resolved later.
-  // Initialize errorperbit, sadperbit16 and sadperbit4.
+  // Initialize errorperbit and sadperbit
   const int rdmult = av1_compute_rd_mult_based_on_qindex(cpi, TF_QINDEX);
-  set_error_per_bit(&cpi->td.mb, rdmult);
-  av1_initialize_me_consts(cpi, &cpi->td.mb, TF_QINDEX);
+  MvCostInfo *mv_cost_info = &cpi->td.mb.mv_cost_info;
+  av1_set_error_per_bit(mv_cost_info, rdmult);
+  av1_set_sad_per_bit(cpi, mv_cost_info, TF_QINDEX);
   av1_fill_mv_costs(cpi->common.fc,
                     cpi->common.features.cur_frame_force_integer_mv,
-                    cpi->common.features.allow_high_precision_mv, &cpi->td.mb);
+                    cpi->common.features.allow_high_precision_mv, mv_cost_info);
 
   // Setup frame buffer for filtering.
   YV12_BUFFER_CONFIG *frames[MAX_LAG_BUFFERS] = { NULL };
diff --git a/av1/encoder/tpl_model.c b/av1/encoder/tpl_model.c
index b63aada..471bcff 100644
--- a/av1/encoder/tpl_model.c
+++ b/av1/encoder/tpl_model.c
@@ -27,6 +27,7 @@
 #include "av1/encoder/encoder.h"
 #include "av1/encoder/encode_strategy.h"
 #include "av1/encoder/hybrid_fwd_txfm.h"
+#include "av1/encoder/rd.h"
 #include "av1/encoder/rdopt.h"
 #include "av1/encoder/reconinter_enc.h"
 #include "av1/encoder/tpl_model.h"
@@ -738,8 +739,9 @@
   // Get rd multiplier set up.
   rdmult = (int)av1_compute_rd_mult(cpi, base_qindex);
   if (rdmult < 1) rdmult = 1;
-  set_error_per_bit(x, rdmult);
-  av1_initialize_me_consts(cpi, x, base_qindex);
+  MvCostInfo *mv_cost_info = &x->mv_cost_info;
+  av1_set_error_per_bit(mv_cost_info, rdmult);
+  av1_set_sad_per_bit(cpi, mv_cost_info, base_qindex);
 
   tpl_frame->is_valid = 1;
 
diff --git a/av1/encoder/tune_vmaf.c b/av1/encoder/tune_vmaf.c
index 1527c7e..66bd07d 100644
--- a/av1/encoder/tune_vmaf.c
+++ b/av1/encoder/tune_vmaf.c
@@ -623,7 +623,7 @@
 
   *rdmult = (int)((double)(*rdmult) * geom_mean_of_scale + 0.5);
   *rdmult = AOMMAX(*rdmult, 0);
-  set_error_per_bit(x, *rdmult);
+  av1_set_error_per_bit(&x->mv_cost_info, *rdmult);
   aom_clear_system_state();
 }