Refactor CommonModeInfoParams from AV1_COMMON

Also, refactor local variables/args for mi_params when we can.

BUG=aomedia:2610

Change-Id: Ifb53494d0e1dd476c2b4a473817ebc583e94a371
diff --git a/av1/av1_dx_iface.c b/av1/av1_dx_iface.c
index d36cb85..ef436f1 100644
--- a/av1/av1_dx_iface.c
+++ b/av1/av1_dx_iface.c
@@ -804,7 +804,8 @@
                   mi_row * (MI_SIZE >> ssy) * ctx->img.stride[plane];
             }
           }
-          ctx->img.d_h = AOMMIN(tile_height, cm->mi_rows - mi_row) * MI_SIZE;
+          ctx->img.d_h =
+              AOMMIN(tile_height, cm->mi_params.mi_rows - mi_row) * MI_SIZE;
         }
 
         if (pbi->ext_tile_debug && tiles->single_tile_decoding &&
@@ -823,7 +824,8 @@
                   mi_col * (MI_SIZE >> ssx) * (1 + is_hbd);
             }
           }
-          ctx->img.d_w = AOMMIN(tile_width, cm->mi_cols - mi_col) * MI_SIZE;
+          ctx->img.d_w =
+              AOMMIN(tile_width, cm->mi_params.mi_cols - mi_col) * MI_SIZE;
         }
 
         ctx->img.fb_priv = output_frame_buf->raw_frame_buffer.priv;
diff --git a/av1/common/alloccommon.c b/av1/common/alloccommon.c
index e4a3cfb..7c5d545 100644
--- a/av1/common/alloccommon.c
+++ b/av1/common/alloccommon.c
@@ -164,7 +164,7 @@
 }
 
 void av1_free_context_buffers(AV1_COMMON *cm) {
-  cm->free_mi(cm);
+  cm->mi_params.free_mi(&cm->mi_params);
 
   av1_free_above_context_buffers(cm, cm->num_allocated_above_contexts);
 
@@ -178,7 +178,7 @@
   const int num_planes = av1_num_planes(cm);
   int plane_idx;
   const int aligned_mi_cols =
-      ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2);
+      ALIGN_POWER_OF_TWO(cm->mi_params.mi_cols, MAX_MIB_SIZE_LOG2);
 
   // Allocate above context buffers
   cm->num_allocated_above_contexts = num_alloc_above_contexts;
@@ -218,15 +218,14 @@
 }
 
 int av1_alloc_context_buffers(AV1_COMMON *cm, int width, int height) {
-  cm->set_mb_mi(cm, width, height);
-
-  if (cm->alloc_mi(cm)) goto fail;
-
+  CommonModeInfoParams *const mi_params = &cm->mi_params;
+  mi_params->set_mb_mi(mi_params, width, height);
+  if (mi_params->alloc_mi(mi_params)) goto fail;
   return 0;
 
 fail:
   // clear the mi_* values to force a realloc on resync
-  cm->set_mb_mi(cm, 0, 0);
+  mi_params->set_mb_mi(mi_params, 0, 0);
   av1_free_context_buffers(cm);
   return 1;
 }
@@ -240,7 +239,9 @@
   cm->default_frame_context = NULL;
 }
 
-void av1_init_context_buffers(AV1_COMMON *cm) { cm->setup_mi(cm); }
+void av1_init_mi_buffers(CommonModeInfoParams *mi_params) {
+  mi_params->setup_mi(mi_params);
+}
 
 #if CONFIG_LPF_MASK
 int av1_alloc_loop_filter_mask(AV1_COMMON *cm) {
@@ -251,9 +252,11 @@
   // 64x64 (128x128 for ext_partitions) region.  The stride
   // and rows are rounded up / truncated to a multiple of 16
   // (32 for ext_partition).
-  cm->lf.lfm_stride = (cm->mi_cols + (MI_SIZE_64X64 - 1)) >> MIN_MIB_SIZE_LOG2;
-  cm->lf.lfm_num = ((cm->mi_rows + (MI_SIZE_64X64 - 1)) >> MIN_MIB_SIZE_LOG2) *
-                   cm->lf.lfm_stride;
+  cm->lf.lfm_stride =
+      (cm->mi_params.mi_cols + (MI_SIZE_64X64 - 1)) >> MIN_MIB_SIZE_LOG2;
+  cm->lf.lfm_num =
+      ((cm->mi_params.mi_rows + (MI_SIZE_64X64 - 1)) >> MIN_MIB_SIZE_LOG2) *
+      cm->lf.lfm_stride;
   cm->lf.lfm =
       (LoopFilterMask *)aom_calloc(cm->lf.lfm_num, sizeof(*cm->lf.lfm));
   if (!cm->lf.lfm) return 1;
diff --git a/av1/common/alloccommon.h b/av1/common/alloccommon.h
index ab226fb..f9d9166 100644
--- a/av1/common/alloccommon.h
+++ b/av1/common/alloccommon.h
@@ -22,6 +22,7 @@
 
 struct AV1Common;
 struct BufferPool;
+struct CommonModeInfoParams;
 
 void av1_remove_common(struct AV1Common *cm);
 
@@ -30,7 +31,7 @@
 void av1_free_above_context_buffers(struct AV1Common *cm,
                                     int num_free_above_contexts);
 int av1_alloc_context_buffers(struct AV1Common *cm, int width, int height);
-void av1_init_context_buffers(struct AV1Common *cm);
+void av1_init_mi_buffers(struct CommonModeInfoParams *mi_params);
 void av1_free_context_buffers(struct AV1Common *cm);
 
 void av1_free_ref_frame_buffers(struct BufferPool *pool);
diff --git a/av1/common/av1_common_int.h b/av1/common/av1_common_int.h
index 7362fdf..5ce40fb 100644
--- a/av1/common/av1_common_int.h
+++ b/av1/common/av1_common_int.h
@@ -359,6 +359,44 @@
   unsigned int single_tile_decoding;
 } CommonTileParams;
 
+// Struct containing params related to MB_MODE_INFO arrays and related info.
+typedef struct CommonModeInfoParams CommonModeInfoParams;
+struct CommonModeInfoParams {
+  // MBs, mb_rows/cols is in 16-pixel units; mi_rows/cols is in
+  // MB_MODE_INFO (4-pixel) units.
+  int MBs;
+  int mb_rows;
+  int mb_cols;
+
+  int mi_rows;
+  int mi_cols;
+
+  // Corresponds to upper left visible macroblock
+  MB_MODE_INFO *mi;
+  int mi_alloc_size;
+  // The minimum size each allocated mi can correspond to.
+  // For decoder, this is always BLOCK_4X4.
+  // For encoder, this is currently set to BLOCK_4X4 for resolution below 4k,
+  // and BLOCK_8X8 for resolution above 4k
+  BLOCK_SIZE mi_alloc_bsize;
+  int mi_alloc_rows, mi_alloc_cols, mi_alloc_stride;
+
+  // Grid of pointers to 4x4 MB_MODE_INFO structs. Any 4x4 not in the visible
+  // area will be NULL.
+  MB_MODE_INFO **mi_grid_base;
+  int mi_grid_size;
+  int mi_stride;
+
+  uint8_t *tx_type_map;
+
+  // Separate mi functions between encoder and decoder.
+  int (*alloc_mi)(struct CommonModeInfoParams *mi_params);
+  void (*free_mi)(struct CommonModeInfoParams *mi_params);
+  void (*setup_mi)(struct CommonModeInfoParams *mi_params);
+  void (*set_mb_mi)(struct CommonModeInfoParams *mi_params, int width,
+                    int height);
+};
+
 typedef struct AV1Common {
   // Information about the current frame that is being coded.
   CurrentFrame current_frame;
@@ -469,12 +507,8 @@
   // Whether some features are allowed or not.
   FeatureFlags features;
 
-  // MBs, mb_rows/cols is in 16-pixel units; mi_rows/cols is in
-  // MB_MODE_INFO (4-pixel) units.
-  int MBs;
-  int mb_rows, mi_rows;
-  int mb_cols, mi_cols;
-  int mi_stride;
+  // Params related to MB_MODE_INFO arrays and related info.
+  CommonModeInfoParams mi_params;
 
   /* profile settings */
   TX_MODE tx_mode;
@@ -511,29 +545,6 @@
   int qm_u;
   int qm_v;
 
-  /* We allocate a MB_MODE_INFO struct for each macroblock, together with
-     an extra row on top and column on the left to simplify prediction. */
-  int mi_alloc_size, mi_grid_size;
-  MB_MODE_INFO *mi; /* Corresponds to upper left visible macroblock */
-  uint8_t *tx_type_map;
-
-  // The minimum size each allocated mi can correspond to.
-  // For decoder, this is always BLOCK_4X4.
-  // For encoder, this is currently set to BLOCK_4X4 for resolution below 4k,
-  // and BLOCK_8X8 for resolution above 4k
-  BLOCK_SIZE mi_alloc_bsize;
-  int mi_alloc_rows, mi_alloc_cols, mi_alloc_stride;
-
-  // Separate mi functions between encoder and decoder.
-  int (*alloc_mi)(struct AV1Common *cm);
-  void (*free_mi)(struct AV1Common *cm);
-  void (*setup_mi)(struct AV1Common *cm);
-  void (*set_mb_mi)(struct AV1Common *cm, int height, int width);
-
-  // Grid of pointers to 4x4 MB_MODE_INFO structs. Any 4x4 not in the visible
-  // area will be NULL.
-  MB_MODE_INFO **mi_grid_base;
-
   uint8_t *last_frame_seg_map;
 
   InterpFilter interp_filter;
@@ -766,23 +777,26 @@
 static INLINE void ensure_mv_buffer(RefCntBuffer *buf, AV1_COMMON *cm) {
   const int buf_rows = buf->mi_rows;
   const int buf_cols = buf->mi_cols;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
 
-  if (buf->mvs == NULL || buf_rows != cm->mi_rows || buf_cols != cm->mi_cols) {
+  if (buf->mvs == NULL || buf_rows != mi_params->mi_rows ||
+      buf_cols != mi_params->mi_cols) {
     aom_free(buf->mvs);
-    buf->mi_rows = cm->mi_rows;
-    buf->mi_cols = cm->mi_cols;
+    buf->mi_rows = mi_params->mi_rows;
+    buf->mi_cols = mi_params->mi_cols;
     CHECK_MEM_ERROR(cm, buf->mvs,
-                    (MV_REF *)aom_calloc(
-                        ((cm->mi_rows + 1) >> 1) * ((cm->mi_cols + 1) >> 1),
-                        sizeof(*buf->mvs)));
+                    (MV_REF *)aom_calloc(((mi_params->mi_rows + 1) >> 1) *
+                                             ((mi_params->mi_cols + 1) >> 1),
+                                         sizeof(*buf->mvs)));
     aom_free(buf->seg_map);
-    CHECK_MEM_ERROR(cm, buf->seg_map,
-                    (uint8_t *)aom_calloc(cm->mi_rows * cm->mi_cols,
-                                          sizeof(*buf->seg_map)));
+    CHECK_MEM_ERROR(
+        cm, buf->seg_map,
+        (uint8_t *)aom_calloc(mi_params->mi_rows * mi_params->mi_cols,
+                              sizeof(*buf->seg_map)));
   }
 
   const int mem_size =
-      ((cm->mi_rows + MAX_MIB_SIZE) >> 1) * (cm->mi_stride >> 1);
+      ((mi_params->mi_rows + MAX_MIB_SIZE) >> 1) * (mi_params->mi_stride >> 1);
   int realloc = cm->tpl_mvs == NULL;
   if (cm->tpl_mvs) realloc |= cm->tpl_mvs_mem_size < mem_size;
 
@@ -835,7 +849,7 @@
       }
     }
   }
-  xd->mi_stride = cm->mi_stride;
+  xd->mi_stride = cm->mi_params.mi_stride;
   xd->error_info = &cm->error;
   cfl_init(&xd->cfl, &cm->seq_params);
 }
@@ -1199,26 +1213,27 @@
   set_txfm_ctx(xd->left_txfm_context, bh, n4_h);
 }
 
-static INLINE int get_mi_grid_idx(const AV1_COMMON *cm, int mi_row,
-                                  int mi_col) {
-  return mi_row * cm->mi_stride + mi_col;
+static INLINE int get_mi_grid_idx(const CommonModeInfoParams *const mi_params,
+                                  int mi_row, int mi_col) {
+  return mi_row * mi_params->mi_stride + mi_col;
 }
 
-static INLINE int get_alloc_mi_idx(const AV1_COMMON *cm, int mi_row,
-                                   int mi_col) {
-  const int mi_alloc_size_1d = mi_size_wide[cm->mi_alloc_bsize];
+static INLINE int get_alloc_mi_idx(const CommonModeInfoParams *const mi_params,
+                                   int mi_row, int mi_col) {
+  const int mi_alloc_size_1d = mi_size_wide[mi_params->mi_alloc_bsize];
   const int mi_alloc_row = mi_row / mi_alloc_size_1d;
   const int mi_alloc_col = mi_col / mi_alloc_size_1d;
 
-  return mi_alloc_row * cm->mi_alloc_stride + mi_alloc_col;
+  return mi_alloc_row * mi_params->mi_alloc_stride + mi_alloc_col;
 }
 
-static INLINE int get_mi_ext_idx(const AV1_COMMON *cm, int mi_row, int mi_col) {
-  const int mi_alloc_size_1d = mi_size_wide[cm->mi_alloc_bsize];
+static INLINE int get_mi_ext_idx(const CommonModeInfoParams *const mi_params,
+                                 int mi_row, int mi_col) {
+  const int mi_alloc_size_1d = mi_size_wide[mi_params->mi_alloc_bsize];
   const int mi_alloc_row = mi_row / mi_alloc_size_1d;
   const int mi_alloc_col = mi_col / mi_alloc_size_1d;
 
-  return mi_alloc_row * cm->mi_alloc_cols + mi_alloc_col;
+  return mi_alloc_row * mi_params->mi_alloc_cols + mi_alloc_col;
 }
 
 static INLINE void txfm_partition_update(TXFM_CONTEXT *above_ctx,
@@ -1313,10 +1328,12 @@
 static INLINE PARTITION_TYPE get_partition(const AV1_COMMON *const cm,
                                            int mi_row, int mi_col,
                                            BLOCK_SIZE bsize) {
-  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return PARTITION_INVALID;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
+  if (mi_row >= mi_params->mi_rows || mi_col >= mi_params->mi_cols)
+    return PARTITION_INVALID;
 
-  const int offset = mi_row * cm->mi_stride + mi_col;
-  MB_MODE_INFO **mi = cm->mi_grid_base + offset;
+  const int offset = mi_row * mi_params->mi_stride + mi_col;
+  MB_MODE_INFO **mi = mi_params->mi_grid_base + offset;
   const BLOCK_SIZE subsize = mi[0]->sb_type;
 
   if (subsize == bsize) return PARTITION_NONE;
@@ -1326,12 +1343,12 @@
   const int sshigh = mi_size_high[subsize];
   const int sswide = mi_size_wide[subsize];
 
-  if (bsize > BLOCK_8X8 && mi_row + bwide / 2 < cm->mi_rows &&
-      mi_col + bhigh / 2 < cm->mi_cols) {
+  if (bsize > BLOCK_8X8 && mi_row + bwide / 2 < mi_params->mi_rows &&
+      mi_col + bhigh / 2 < mi_params->mi_cols) {
     // In this case, the block might be using an extended partition
     // type.
     const MB_MODE_INFO *const mbmi_right = mi[bwide / 2];
-    const MB_MODE_INFO *const mbmi_below = mi[bhigh / 2 * cm->mi_stride];
+    const MB_MODE_INFO *const mbmi_below = mi[bhigh / 2 * mi_params->mi_stride];
 
     if (sswide == bwide) {
       // Smaller height but same width. Is PARTITION_HORZ_4, PARTITION_HORZ or
@@ -1421,17 +1438,19 @@
 }
 
 static INLINE void init_frame_info(FRAME_INFO *frame_info,
-                                   AV1_COMMON *const cm) {
+                                   const AV1_COMMON *const cm) {
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
+  const SequenceHeader *const seq_params = &cm->seq_params;
   frame_info->frame_width = cm->width;
   frame_info->frame_height = cm->height;
-  frame_info->mi_cols = cm->mi_cols;
-  frame_info->mi_rows = cm->mi_rows;
-  frame_info->mb_cols = cm->mb_cols;
-  frame_info->mb_rows = cm->mb_rows;
-  frame_info->num_mbs = cm->MBs;
-  frame_info->bit_depth = cm->seq_params.bit_depth;
-  frame_info->subsampling_x = cm->seq_params.subsampling_x;
-  frame_info->subsampling_y = cm->seq_params.subsampling_y;
+  frame_info->mi_cols = mi_params->mi_cols;
+  frame_info->mi_rows = mi_params->mi_rows;
+  frame_info->mb_cols = mi_params->mb_cols;
+  frame_info->mb_rows = mi_params->mb_rows;
+  frame_info->num_mbs = mi_params->MBs;
+  frame_info->bit_depth = seq_params->bit_depth;
+  frame_info->subsampling_x = seq_params->subsampling_x;
+  frame_info->subsampling_y = seq_params->subsampling_y;
 }
 
 #ifdef __cplusplus
diff --git a/av1/common/av1_loopfilter.c b/av1/common/av1_loopfilter.c
index b0a65d7..c756760 100644
--- a/av1/common/av1_loopfilter.c
+++ b/av1/common/av1_loopfilter.c
@@ -256,7 +256,8 @@
   // and mi_col should be odd number for chroma plane.
   const int mi_row = scale_vert | ((y << scale_vert) >> MI_SIZE_LOG2);
   const int mi_col = scale_horz | ((x << scale_horz) >> MI_SIZE_LOG2);
-  MB_MODE_INFO **mi = cm->mi_grid_base + mi_row * cm->mi_stride + mi_col;
+  MB_MODE_INFO **mi =
+      cm->mi_params.mi_grid_base + mi_row * cm->mi_params.mi_stride + mi_col;
   const MB_MODE_INFO *mbmi = mi[0];
   // If current mbmi is not correctly setup, return an invalid value to stop
   // filtering. One example is that if this tile is not coded, then its mbmi
@@ -479,9 +480,9 @@
       AV1_DEBLOCKING_PARAMETERS params;
       memset(&params, 0, sizeof(params));
 
-      tx_size =
-          set_lpf_parameters(&params, (cm->mi_stride << scale_vert), cm, xd,
-                             HORZ_EDGE, curr_x, curr_y, plane, plane_ptr);
+      tx_size = set_lpf_parameters(
+          &params, (cm->mi_params.mi_stride << scale_vert), cm, xd, HORZ_EDGE,
+          curr_x, curr_y, plane, plane_ptr);
       if (tx_size == TX_INVALID) {
         params.filter_length = 0;
         tx_size = TX_4X4;
@@ -581,8 +582,8 @@
   const uint32_t scale_vert = plane_ptr->subsampling_y;
   uint8_t *const dst_ptr = plane_ptr->dst.buf;
   const int dst_stride = plane_ptr->dst.stride;
-  const int y_range = cm->mi_rows >> scale_vert;
-  const int x_range = cm->mi_cols >> scale_horz;
+  const int y_range = cm->mi_params.mi_rows >> scale_vert;
+  const int x_range = cm->mi_params.mi_cols >> scale_horz;
   for (int y = 0; y < y_range; y++) {
     uint8_t *p = dst_ptr + y * MI_SIZE * dst_stride;
     for (int x = 0; x < x_range;) {
@@ -623,8 +624,8 @@
   const uint32_t scale_vert = plane_ptr->subsampling_y;
   uint8_t *const dst_ptr = plane_ptr->dst.buf;
   const int dst_stride = plane_ptr->dst.stride;
-  const int y_range = cm->mi_rows >> scale_vert;
-  const int x_range = cm->mi_cols >> scale_horz;
+  const int y_range = cm->mi_params.mi_rows >> scale_vert;
+  const int x_range = cm->mi_params.mi_cols >> scale_horz;
   for (int x = 0; x < x_range; x++) {
     uint8_t *p = dst_ptr + x * MI_SIZE;
     for (int y = 0; y < y_range;) {
@@ -639,9 +640,9 @@
       AV1_DEBLOCKING_PARAMETERS params;
       memset(&params, 0, sizeof(params));
 
-      tx_size =
-          set_lpf_parameters(&params, (cm->mi_stride << scale_vert), cm, xd,
-                             HORZ_EDGE, curr_x, curr_y, plane, plane_ptr);
+      tx_size = set_lpf_parameters(
+          &params, (cm->mi_params.mi_stride << scale_vert), cm, xd, HORZ_EDGE,
+          curr_x, curr_y, plane, plane_ptr);
       if (tx_size == TX_INVALID) {
         params.filter_length = 0;
         tx_size = TX_4X4;
@@ -663,7 +664,7 @@
                              int plane_start, int plane_end) {
   struct macroblockd_plane *pd = xd->plane;
   const int col_start = 0;
-  const int col_end = cm->mi_cols;
+  const int col_end = cm->mi_params.mi_cols;
   int mi_row, mi_col;
   int plane;
 
@@ -773,11 +774,11 @@
   int start_mi_row, end_mi_row, mi_rows_to_filter;
 
   start_mi_row = 0;
-  mi_rows_to_filter = cm->mi_rows;
-  if (partial_frame && cm->mi_rows > 8) {
-    start_mi_row = cm->mi_rows >> 1;
+  mi_rows_to_filter = cm->mi_params.mi_rows;
+  if (partial_frame && cm->mi_params.mi_rows > 8) {
+    start_mi_row = cm->mi_params.mi_rows >> 1;
     start_mi_row &= 0xfffffff8;
-    mi_rows_to_filter = AOMMAX(cm->mi_rows / 8, 8);
+    mi_rows_to_filter = AOMMAX(cm->mi_params.mi_rows / 8, 8);
   }
   end_mi_row = start_mi_row + mi_rows_to_filter;
   av1_loop_filter_frame_init(cm, plane_start, plane_end);
diff --git a/av1/common/cdef.c b/av1/common/cdef.c
index 1aa3c97..ef7b866 100644
--- a/av1/common/cdef.c
+++ b/av1/common/cdef.c
@@ -33,11 +33,12 @@
   return 1;
 }
 
-int av1_cdef_compute_sb_list(const AV1_COMMON *const cm, int mi_row, int mi_col,
-                             cdef_list *dlist, BLOCK_SIZE bs) {
-  MB_MODE_INFO **grid = cm->mi_grid_base;
-  int maxc = cm->mi_cols - mi_col;
-  int maxr = cm->mi_rows - mi_row;
+int av1_cdef_compute_sb_list(const CommonModeInfoParams *const mi_params,
+                             int mi_row, int mi_col, cdef_list *dlist,
+                             BLOCK_SIZE bs) {
+  MB_MODE_INFO **grid = mi_params->mi_grid_base;
+  int maxc = mi_params->mi_cols - mi_col;
+  int maxr = mi_params->mi_rows - mi_row;
 
   if (bs == BLOCK_128X128 || bs == BLOCK_128X64)
     maxc = AOMMIN(maxc, MI_SIZE_128X128);
@@ -55,7 +56,8 @@
   int count = 0;
   for (int r = 0; r < maxr; r += r_step) {
     for (int c = 0; c < maxc; c += c_step) {
-      if (!is_8x8_block_skip(grid, mi_row + r, mi_col + c, cm->mi_stride)) {
+      if (!is_8x8_block_skip(grid, mi_row + r, mi_col + c,
+                             mi_params->mi_stride)) {
         dlist[count].by = r >> r_shift;
         dlist[count].bx = c >> c_shift;
         count++;
@@ -119,6 +121,7 @@
 void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
                     MACROBLOCKD *xd) {
   const CdefInfo *const cdef_info = &cm->cdef_info;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   const int num_planes = av1_num_planes(cm);
   DECLARE_ALIGNED(16, uint16_t, src[CDEF_INBUF_SIZE]);
   uint16_t *linebuf[3];
@@ -133,8 +136,8 @@
   int xdec[3];
   int ydec[3];
   int coeff_shift = AOMMAX(cm->seq_params.bit_depth - 8, 0);
-  const int nvfb = (cm->mi_rows + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
-  const int nhfb = (cm->mi_cols + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
+  const int nvfb = (mi_params->mi_rows + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
+  const int nhfb = (mi_params->mi_cols + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
   av1_setup_dst_planes(xd->plane, cm->seq_params.sb_size, frame, 0, 0, 0,
                        num_planes);
   row_cdef = aom_malloc(sizeof(*row_cdef) * (nhfb + 2) * 2);
@@ -147,7 +150,7 @@
     mi_wide_l2[pli] = MI_SIZE_LOG2 - xd->plane[pli].subsampling_x;
     mi_high_l2[pli] = MI_SIZE_LOG2 - xd->plane[pli].subsampling_y;
   }
-  const int stride = (cm->mi_cols << MI_SIZE_LOG2) + 2 * CDEF_HBORDER;
+  const int stride = (mi_params->mi_cols << MI_SIZE_LOG2) + 2 * CDEF_HBORDER;
   for (int pli = 0; pli < num_planes; pli++) {
     linebuf[pli] = aom_malloc(sizeof(*linebuf) * CDEF_VBORDER * stride);
     colbuf[pli] =
@@ -169,17 +172,18 @@
       int nhb, nvb;
       int cstart = 0;
       curr_row_cdef[fbc] = 0;
-      if (cm->mi_grid_base[MI_SIZE_64X64 * fbr * cm->mi_stride +
-                           MI_SIZE_64X64 * fbc] == NULL ||
-          cm->mi_grid_base[MI_SIZE_64X64 * fbr * cm->mi_stride +
-                           MI_SIZE_64X64 * fbc]
+      if (mi_params->mi_grid_base[MI_SIZE_64X64 * fbr * mi_params->mi_stride +
+                                  MI_SIZE_64X64 * fbc] == NULL ||
+          mi_params
+                  ->mi_grid_base[MI_SIZE_64X64 * fbr * mi_params->mi_stride +
+                                 MI_SIZE_64X64 * fbc]
                   ->cdef_strength == -1) {
         cdef_left = 0;
         continue;
       }
       if (!cdef_left) cstart = -CDEF_HBORDER;
-      nhb = AOMMIN(MI_SIZE_64X64, cm->mi_cols - MI_SIZE_64X64 * fbc);
-      nvb = AOMMIN(MI_SIZE_64X64, cm->mi_rows - MI_SIZE_64X64 * fbr);
+      nhb = AOMMIN(MI_SIZE_64X64, mi_params->mi_cols - MI_SIZE_64X64 * fbc);
+      nvb = AOMMIN(MI_SIZE_64X64, mi_params->mi_rows - MI_SIZE_64X64 * fbr);
       int frame_top, frame_left, frame_bottom, frame_right;
 
       int mi_row = MI_SIZE_64X64 * fbr;
@@ -197,18 +201,19 @@
       frame_left = (mi_col == 0) ? 1 : 0;
 
       if (fbr != nvfb - 1)
-        frame_bottom = (mi_row + MI_SIZE_64X64 == cm->mi_rows) ? 1 : 0;
+        frame_bottom = (mi_row + MI_SIZE_64X64 == mi_params->mi_rows) ? 1 : 0;
       else
         frame_bottom = 1;
 
       if (fbc != nhfb - 1)
-        frame_right = (mi_col + MI_SIZE_64X64 == cm->mi_cols) ? 1 : 0;
+        frame_right = (mi_col + MI_SIZE_64X64 == mi_params->mi_cols) ? 1 : 0;
       else
         frame_right = 1;
 
       const int mbmi_cdef_strength =
-          cm->mi_grid_base[MI_SIZE_64X64 * fbr * cm->mi_stride +
-                           MI_SIZE_64X64 * fbc]
+          mi_params
+              ->mi_grid_base[MI_SIZE_64X64 * fbr * mi_params->mi_stride +
+                             MI_SIZE_64X64 * fbc]
               ->cdef_strength;
       level =
           cdef_info->cdef_strengths[mbmi_cdef_strength] / CDEF_SEC_STRENGTHS;
@@ -222,7 +227,7 @@
       uv_sec_strength += uv_sec_strength == 3;
       if ((level == 0 && sec_strength == 0 && uv_level == 0 &&
            uv_sec_strength == 0) ||
-          (cdef_count = av1_cdef_compute_sb_list(cm, fbr * MI_SIZE_64X64,
+          (cdef_count = av1_cdef_compute_sb_list(mi_params, fbr * MI_SIZE_64X64,
                                                  fbc * MI_SIZE_64X64, dlist,
                                                  BLOCK_64X64)) == 0) {
         cdef_left = 0;
diff --git a/av1/common/cdef.h b/av1/common/cdef.h
index 624c44c..5680baf 100644
--- a/av1/common/cdef.h
+++ b/av1/common/cdef.h
@@ -37,8 +37,8 @@
 extern "C" {
 #endif
 
-int av1_cdef_compute_sb_list(const AV1_COMMON *const cm, int mi_row, int mi_col,
-                             cdef_list *dlist, BLOCK_SIZE bsize);
+int av1_cdef_compute_sb_list(const CommonModeInfoParams *mi_params, int mi_row,
+                             int mi_col, cdef_list *dlist, BLOCK_SIZE bsize);
 void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm, MACROBLOCKD *xd);
 
 void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref,
diff --git a/av1/common/debugmodes.c b/av1/common/debugmodes.c
index acc71d9..7e1ab12 100644
--- a/av1/common/debugmodes.c
+++ b/av1/common/debugmodes.c
@@ -26,32 +26,31 @@
  */
 static void print_mi_data(AV1_COMMON *cm, FILE *file, const char *descriptor,
                           size_t member_offset) {
-  int mi_row, mi_col;
-  MB_MODE_INFO **mi = cm->mi_grid_base;
-  int rows = cm->mi_rows;
-  int cols = cm->mi_cols;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
+  MB_MODE_INFO **mi = mi_params->mi_grid_base;
+  int rows = mi_params->mi_rows;
+  int cols = mi_params->mi_cols;
   char prefix = descriptor[0];
 
   log_frame_info(cm, descriptor, file);
-  for (mi_row = 0; mi_row < rows; mi_row++) {
+  for (int mi_row = 0; mi_row < rows; mi_row++) {
     fprintf(file, "%c ", prefix);
-    for (mi_col = 0; mi_col < cols; mi_col++) {
+    for (int mi_col = 0; mi_col < cols; mi_col++) {
       fprintf(file, "%2d ", *((char *)((char *)(mi[0]) + member_offset)));
       mi++;
     }
     fprintf(file, "\n");
-    mi += cm->mi_stride - cols;
+    mi += mi_params->mi_stride - cols;
   }
   fprintf(file, "\n");
 }
 
 void av1_print_modes_and_motion_vectors(AV1_COMMON *cm, const char *file) {
-  int mi_row;
-  int mi_col;
+  CommonModeInfoParams *mi_params = &cm->mi_params;
   FILE *mvs = fopen(file, "a");
-  MB_MODE_INFO **mi = cm->mi_grid_base;
-  int rows = cm->mi_rows;
-  int cols = cm->mi_cols;
+  MB_MODE_INFO **mi = mi_params->mi_grid_base;
+  const int rows = mi_params->mi_rows;
+  const int cols = mi_params->mi_cols;
 
   print_mi_data(cm, mvs, "Partitions:", offsetof(MB_MODE_INFO, sb_type));
   print_mi_data(cm, mvs, "Modes:", offsetof(MB_MODE_INFO, mode));
@@ -61,28 +60,28 @@
 
   // output skip infomation.
   log_frame_info(cm, "Skips:", mvs);
-  for (mi_row = 0; mi_row < rows; mi_row++) {
+  for (int mi_row = 0; mi_row < rows; mi_row++) {
     fprintf(mvs, "S ");
-    for (mi_col = 0; mi_col < cols; mi_col++) {
+    for (int mi_col = 0; mi_col < cols; mi_col++) {
       fprintf(mvs, "%2d ", mi[0]->skip);
       mi++;
     }
     fprintf(mvs, "\n");
-    mi += cm->mi_stride - cols;
+    mi += mi_params->mi_stride - cols;
   }
   fprintf(mvs, "\n");
 
   // output motion vectors.
   log_frame_info(cm, "Vectors ", mvs);
-  mi = cm->mi_grid_base;
-  for (mi_row = 0; mi_row < rows; mi_row++) {
+  mi = mi_params->mi_grid_base;
+  for (int mi_row = 0; mi_row < rows; mi_row++) {
     fprintf(mvs, "V ");
-    for (mi_col = 0; mi_col < cols; mi_col++) {
+    for (int mi_col = 0; mi_col < cols; mi_col++) {
       fprintf(mvs, "%4d:%4d ", mi[0]->mv[0].as_mv.row, mi[0]->mv[0].as_mv.col);
       mi++;
     }
     fprintf(mvs, "\n");
-    mi += cm->mi_stride - cols;
+    mi += mi_params->mi_stride - cols;
   }
   fprintf(mvs, "\n");
 
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c
index 3c480ac..5f061be 100644
--- a/av1/common/entropymode.c
+++ b/av1/common/entropymode.c
@@ -1087,7 +1087,8 @@
   av1_clearall_segfeatures(&cm->seg);
 
   if (cm->cur_frame->seg_map)
-    memset(cm->cur_frame->seg_map, 0, (cm->mi_rows * cm->mi_cols));
+    memset(cm->cur_frame->seg_map, 0,
+           (cm->mi_params.mi_rows * cm->mi_params.mi_cols));
 
   // reset mode ref deltas
   av1_set_default_ref_deltas(cm->cur_frame->ref_deltas);
diff --git a/av1/common/loopfiltermask.c b/av1/common/loopfiltermask.c
index 7c31521..157310f 100644
--- a/av1/common/loopfiltermask.c
+++ b/av1/common/loopfiltermask.c
@@ -964,7 +964,7 @@
     const int shift = get_index_shift(col, row, &index);
     int index_next = 0;
     const int shift_next = get_index_shift(col, row_next, &index_next);
-    const int has_next_row = row_next < cm->mi_rows;
+    const int has_next_row = row_next < cm->mi_params.mi_rows;
     switch (pl) {
       case 0:
         mask_16x16 = lfm->left_y[TX_16X16].bits[index];
diff --git a/av1/common/mvref_common.c b/av1/common/mvref_common.c
index 020e881..92931d4 100644
--- a/av1/common/mvref_common.c
+++ b/av1/common/mvref_common.c
@@ -40,7 +40,7 @@
 void av1_copy_frame_mvs(const AV1_COMMON *const cm,
                         const MB_MODE_INFO *const mi, int mi_row, int mi_col,
                         int x_mis, int y_mis) {
-  const int frame_mvs_stride = ROUND_POWER_OF_TWO(cm->mi_cols, 1);
+  const int frame_mvs_stride = ROUND_POWER_OF_TWO(cm->mi_params.mi_cols, 1);
   MV_REF *frame_mvs =
       cm->cur_frame->mvs + (mi_row >> 1) * frame_mvs_stride + (mi_col >> 1);
   x_mis = ROUND_POWER_OF_TWO(x_mis, 1);
@@ -145,7 +145,7 @@
     uint16_t *ref_mv_weight, uint8_t *refmv_count, uint8_t *ref_match_count,
     uint8_t *newmv_count, int_mv *gm_mv_candidates, int max_row_offset,
     int *processed_rows) {
-  int end_mi = AOMMIN(xd->n4_w, cm->mi_cols - mi_col);
+  int end_mi = AOMMIN(xd->n4_w, cm->mi_params.mi_cols - mi_col);
   end_mi = AOMMIN(end_mi, mi_size_wide[BLOCK_64X64]);
   const int n8_w_8 = mi_size_wide[BLOCK_8X8];
   const int n8_w_16 = mi_size_wide[BLOCK_16X16];
@@ -193,7 +193,7 @@
     uint16_t *ref_mv_weight, uint8_t *refmv_count, uint8_t *ref_match_count,
     uint8_t *newmv_count, int_mv *gm_mv_candidates, int max_col_offset,
     int *processed_cols) {
-  int end_mi = AOMMIN(xd->n4_h, cm->mi_rows - mi_row);
+  int end_mi = AOMMIN(xd->n4_h, cm->mi_params.mi_rows - mi_row);
   end_mi = AOMMIN(end_mi, mi_size_high[BLOCK_64X64]);
   const int n8_h_8 = mi_size_high[BLOCK_8X8];
   const int n8_h_16 = mi_size_high[BLOCK_16X16];
@@ -334,7 +334,8 @@
   if (!is_inside(&xd->tile, mi_col, mi_row, &mi_pos)) return 0;
 
   const TPL_MV_REF *prev_frame_mvs =
-      cm->tpl_mvs + ((mi_row + mi_pos.row) >> 1) * (cm->mi_stride >> 1) +
+      cm->tpl_mvs +
+      ((mi_row + mi_pos.row) >> 1) * (cm->mi_params.mi_stride >> 1) +
       ((mi_col + mi_pos.col) >> 1);
   if (prev_frame_mvs->mfmv0.as_int == INVALID_MV) return 0;
 
@@ -671,9 +672,9 @@
   }
 
   int mi_width = AOMMIN(mi_size_wide[BLOCK_64X64], xd->n4_w);
-  mi_width = AOMMIN(mi_width, cm->mi_cols - mi_col);
+  mi_width = AOMMIN(mi_width, cm->mi_params.mi_cols - mi_col);
   int mi_height = AOMMIN(mi_size_high[BLOCK_64X64], xd->n4_h);
-  mi_height = AOMMIN(mi_height, cm->mi_rows - mi_row);
+  mi_height = AOMMIN(mi_height, cm->mi_params.mi_rows - mi_row);
   const int mi_size = AOMMIN(mi_width, mi_height);
   if (rf[1] > NONE_FRAME) {
     // TODO(jingning, yunqing): Refactor and consolidate the compound and
@@ -884,8 +885,8 @@
   const int col =
       (sign_bias == 1) ? blk_col - col_offset : blk_col + col_offset;
 
-  if (row < 0 || row >= (cm->mi_rows >> 1) || col < 0 ||
-      col >= (cm->mi_cols >> 1))
+  if (row < 0 || row >= (cm->mi_params.mi_rows >> 1) || col < 0 ||
+      col >= (cm->mi_params.mi_cols >> 1))
     return 0;
 
   if (row < base_blk_row - (MAX_OFFSET_HEIGHT >> 3) ||
@@ -919,8 +920,8 @@
       start_frame_buf->frame_type == INTRA_ONLY_FRAME)
     return 0;
 
-  if (start_frame_buf->mi_rows != cm->mi_rows ||
-      start_frame_buf->mi_cols != cm->mi_cols)
+  if (start_frame_buf->mi_rows != cm->mi_params.mi_rows ||
+      start_frame_buf->mi_cols != cm->mi_params.mi_cols)
     return 0;
 
   const int start_frame_order_hint = start_frame_buf->order_hint;
@@ -939,8 +940,8 @@
   if (dir == 2) start_to_current_frame_offset = -start_to_current_frame_offset;
 
   MV_REF *mv_ref_base = start_frame_buf->mvs;
-  const int mvs_rows = (cm->mi_rows + 1) >> 1;
-  const int mvs_cols = (cm->mi_cols + 1) >> 1;
+  const int mvs_rows = (cm->mi_params.mi_rows + 1) >> 1;
+  const int mvs_cols = (cm->mi_params.mi_cols + 1) >> 1;
 
   for (int blk_row = 0; blk_row < mvs_rows; ++blk_row) {
     for (int blk_col = 0; blk_col < mvs_cols; ++blk_col) {
@@ -965,7 +966,7 @@
         }
 
         if (pos_valid) {
-          const int mi_offset = mi_r * (cm->mi_stride >> 1) + mi_c;
+          const int mi_offset = mi_r * (cm->mi_params.mi_stride >> 1) + mi_c;
 
           tpl_mvs_base[mi_offset].mfmv0.as_mv.row = fwd_mv.row;
           tpl_mvs_base[mi_offset].mfmv0.as_mv.col = fwd_mv.col;
@@ -985,7 +986,8 @@
   if (!order_hint_info->enable_order_hint) return;
 
   TPL_MV_REF *tpl_mvs_base = cm->tpl_mvs;
-  int size = ((cm->mi_rows + MAX_MIB_SIZE) >> 1) * (cm->mi_stride >> 1);
+  int size = ((cm->mi_params.mi_rows + MAX_MIB_SIZE) >> 1) *
+             (cm->mi_params.mi_stride >> 1);
   for (int idx = 0; idx < size; ++idx) {
     tpl_mvs_base[idx].mfmv0.as_int = INVALID_MV;
     tpl_mvs_base[idx].ref_frame_offset = 0;
@@ -1145,7 +1147,8 @@
       }
     } else {
       // Handle "current block width > above block width" case.
-      for (i = 0; i < AOMMIN(xd->n4_w, cm->mi_cols - mi_col); i += mi_step) {
+      for (i = 0; i < AOMMIN(xd->n4_w, cm->mi_params.mi_cols - mi_col);
+           i += mi_step) {
         mbmi = xd->mi[i + mi_row_offset * mi_stride];
         n4_w = mi_size_wide[mbmi->sb_type];
         mi_step = AOMMIN(xd->n4_w, n4_w);
@@ -1184,7 +1187,8 @@
       }
     } else {
       // Handle "current block height > above block height" case.
-      for (i = 0; i < AOMMIN(xd->n4_h, cm->mi_rows - mi_row); i += mi_step) {
+      for (i = 0; i < AOMMIN(xd->n4_h, cm->mi_params.mi_rows - mi_row);
+           i += mi_step) {
         mbmi = xd->mi[mi_col_offset + i * mi_stride];
         n4_h = mi_size_high[mbmi->sb_type];
         mi_step = AOMMIN(xd->n4_h, n4_h);
diff --git a/av1/common/obmc.h b/av1/common/obmc.h
index 233e0d8..a001186 100644
--- a/av1/common/obmc.h
+++ b/av1/common/obmc.h
@@ -29,7 +29,7 @@
   // prev_row_mi points into the mi array, starting at the beginning of the
   // previous row.
   MB_MODE_INFO **prev_row_mi = xd->mi - mi_col - 1 * xd->mi_stride;
-  const int end_col = AOMMIN(mi_col + xd->n4_w, cm->mi_cols);
+  const int end_col = AOMMIN(mi_col + xd->n4_w, cm->mi_params.mi_cols);
   uint8_t mi_step;
   for (int above_mi_col = mi_col; above_mi_col < end_col && nb_count < nb_max;
        above_mi_col += mi_step) {
@@ -66,7 +66,7 @@
   // previous column
   const int mi_row = xd->mi_row;
   MB_MODE_INFO **prev_col_mi = xd->mi - 1 - mi_row * xd->mi_stride;
-  const int end_row = AOMMIN(mi_row + xd->n4_h, cm->mi_rows);
+  const int end_row = AOMMIN(mi_row + xd->n4_h, cm->mi_params.mi_rows);
   uint8_t mi_step;
   for (int left_mi_row = mi_row; left_mi_row < end_row && nb_count < nb_max;
        left_mi_row += mi_step) {
diff --git a/av1/common/pred_common.h b/av1/common/pred_common.h
index af2af6c..d1dab97 100644
--- a/av1/common/pred_common.h
+++ b/av1/common/pred_common.h
@@ -21,20 +21,22 @@
 extern "C" {
 #endif
 
-static INLINE int get_segment_id(const AV1_COMMON *const cm,
+static INLINE int get_segment_id(const CommonModeInfoParams *const mi_params,
                                  const uint8_t *segment_ids, BLOCK_SIZE bsize,
                                  int mi_row, int mi_col) {
-  const int mi_offset = mi_row * cm->mi_cols + mi_col;
+  const int mi_offset = mi_row * mi_params->mi_cols + mi_col;
   const int bw = mi_size_wide[bsize];
   const int bh = mi_size_high[bsize];
-  const int xmis = AOMMIN(cm->mi_cols - mi_col, bw);
-  const int ymis = AOMMIN(cm->mi_rows - mi_row, bh);
-  int x, y, segment_id = MAX_SEGMENTS;
+  const int xmis = AOMMIN(mi_params->mi_cols - mi_col, bw);
+  const int ymis = AOMMIN(mi_params->mi_rows - mi_row, bh);
+  int segment_id = MAX_SEGMENTS;
 
-  for (y = 0; y < ymis; ++y)
-    for (x = 0; x < xmis; ++x)
-      segment_id =
-          AOMMIN(segment_id, segment_ids[mi_offset + y * cm->mi_cols + x]);
+  for (int y = 0; y < ymis; ++y) {
+    for (int x = 0; x < xmis; ++x) {
+      segment_id = AOMMIN(segment_id,
+                          segment_ids[mi_offset + y * mi_params->mi_cols + x]);
+    }
+  }
 
   assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);
   return segment_id;
@@ -48,17 +50,19 @@
   int prev_u = -1;   // top segment_id
   const int mi_row = xd->mi_row;
   const int mi_col = xd->mi_col;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
+  const uint8_t *seg_map = cm->cur_frame->seg_map;
   if ((xd->up_available) && (xd->left_available)) {
-    prev_ul = get_segment_id(cm, cm->cur_frame->seg_map, BLOCK_4X4, mi_row - 1,
-                             mi_col - 1);
+    prev_ul =
+        get_segment_id(mi_params, seg_map, BLOCK_4X4, mi_row - 1, mi_col - 1);
   }
   if (xd->up_available) {
-    prev_u = get_segment_id(cm, cm->cur_frame->seg_map, BLOCK_4X4, mi_row - 1,
-                            mi_col - 0);
+    prev_u =
+        get_segment_id(mi_params, seg_map, BLOCK_4X4, mi_row - 1, mi_col - 0);
   }
   if (xd->left_available) {
-    prev_l = get_segment_id(cm, cm->cur_frame->seg_map, BLOCK_4X4, mi_row - 0,
-                            mi_col - 1);
+    prev_l =
+        get_segment_id(mi_params, seg_map, BLOCK_4X4, mi_row - 0, mi_col - 1);
   }
   // This property follows from the fact that get_segment_id() returns a
   // nonnegative value. This allows us to test for all edge cases with a simple
diff --git a/av1/common/thread_common.c b/av1/common/thread_common.c
index b656e68..f3c8795 100644
--- a/av1/common/thread_common.c
+++ b/av1/common/thread_common.c
@@ -268,7 +268,8 @@
     struct macroblockd_plane *planes, MACROBLOCKD *xd,
     AV1LfSync *const lf_sync) {
   const int sb_cols =
-      ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2) >> MAX_MIB_SIZE_LOG2;
+      ALIGN_POWER_OF_TWO(cm->mi_params.mi_cols, MAX_MIB_SIZE_LOG2) >>
+      MAX_MIB_SIZE_LOG2;
   int mi_row, mi_col, plane, dir;
   int r, c;
 
@@ -282,7 +283,8 @@
       r = mi_row >> MAX_MIB_SIZE_LOG2;
 
       if (dir == 0) {
-        for (mi_col = 0; mi_col < cm->mi_cols; mi_col += MAX_MIB_SIZE) {
+        for (mi_col = 0; mi_col < cm->mi_params.mi_cols;
+             mi_col += MAX_MIB_SIZE) {
           c = mi_col >> MAX_MIB_SIZE_LOG2;
 
           av1_setup_dst_planes(planes, cm->seq_params.sb_size, frame_buffer,
@@ -293,7 +295,8 @@
           sync_write(lf_sync, r, c, sb_cols, plane);
         }
       } else if (dir == 1) {
-        for (mi_col = 0; mi_col < cm->mi_cols; mi_col += MAX_MIB_SIZE) {
+        for (mi_col = 0; mi_col < cm->mi_params.mi_cols;
+             mi_col += MAX_MIB_SIZE) {
           c = mi_col >> MAX_MIB_SIZE_LOG2;
 
           // Wait for vertical edge filtering of the top-right block to be
@@ -331,7 +334,8 @@
     struct macroblockd_plane *planes, MACROBLOCKD *xd,
     AV1LfSync *const lf_sync) {
   const int sb_cols =
-      ALIGN_POWER_OF_TWO(cm->mi_cols, MIN_MIB_SIZE_LOG2) >> MIN_MIB_SIZE_LOG2;
+      ALIGN_POWER_OF_TWO(cm->mi_params.mi_cols, MIN_MIB_SIZE_LOG2) >>
+      MIN_MIB_SIZE_LOG2;
   int mi_row, mi_col, plane, dir;
   int r, c;
   (void)xd;
@@ -346,7 +350,8 @@
       r = mi_row >> MIN_MIB_SIZE_LOG2;
 
       if (dir == 0) {
-        for (mi_col = 0; mi_col < cm->mi_cols; mi_col += MI_SIZE_64X64) {
+        for (mi_col = 0; mi_col < cm->mi_params.mi_cols;
+             mi_col += MI_SIZE_64X64) {
           c = mi_col >> MIN_MIB_SIZE_LOG2;
 
           av1_setup_dst_planes(planes, BLOCK_64X64, frame_buffer, mi_row,
@@ -357,7 +362,8 @@
           sync_write(lf_sync, r, c, sb_cols, plane);
         }
       } else if (dir == 1) {
-        for (mi_col = 0; mi_col < cm->mi_cols; mi_col += MI_SIZE_64X64) {
+        for (mi_col = 0; mi_col < cm->mi_params.mi_cols;
+             mi_col += MI_SIZE_64X64) {
           c = mi_col >> MIN_MIB_SIZE_LOG2;
 
           // Wait for vertical edge filtering of the top-right block to be
@@ -402,16 +408,17 @@
 #if CONFIG_LPF_MASK
   int sb_rows;
   if (is_decoding) {
-    sb_rows =
-        ALIGN_POWER_OF_TWO(cm->mi_rows, MIN_MIB_SIZE_LOG2) >> MIN_MIB_SIZE_LOG2;
+    sb_rows = ALIGN_POWER_OF_TWO(cm->mi_params.mi_rows, MIN_MIB_SIZE_LOG2) >>
+              MIN_MIB_SIZE_LOG2;
   } else {
-    sb_rows =
-        ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2) >> MAX_MIB_SIZE_LOG2;
+    sb_rows = ALIGN_POWER_OF_TWO(cm->mi_params.mi_rows, MAX_MIB_SIZE_LOG2) >>
+              MAX_MIB_SIZE_LOG2;
   }
 #else
   // Number of superblock rows and cols
   const int sb_rows =
-      ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2) >> MAX_MIB_SIZE_LOG2;
+      ALIGN_POWER_OF_TWO(cm->mi_params.mi_rows, MAX_MIB_SIZE_LOG2) >>
+      MAX_MIB_SIZE_LOG2;
 #endif
   const int num_workers = nworkers;
   int i;
@@ -479,11 +486,11 @@
   int start_mi_row, end_mi_row, mi_rows_to_filter;
 
   start_mi_row = 0;
-  mi_rows_to_filter = cm->mi_rows;
-  if (partial_frame && cm->mi_rows > 8) {
-    start_mi_row = cm->mi_rows >> 1;
+  mi_rows_to_filter = cm->mi_params.mi_rows;
+  if (partial_frame && cm->mi_params.mi_rows > 8) {
+    start_mi_row = cm->mi_params.mi_rows >> 1;
     start_mi_row &= 0xfffffff8;
-    mi_rows_to_filter = AOMMAX(cm->mi_rows / 8, 8);
+    mi_rows_to_filter = AOMMAX(cm->mi_params.mi_rows / 8, 8);
   }
   end_mi_row = start_mi_row + mi_rows_to_filter;
   av1_loop_filter_frame_init(cm, plane_start, plane_end);
diff --git a/av1/common/tile_common.c b/av1/common/tile_common.c
index 4c044e6..1b11bd7 100644
--- a/av1/common/tile_common.c
+++ b/av1/common/tile_common.c
@@ -31,9 +31,9 @@
   const SequenceHeader *const seq_params = &cm->seq_params;
   CommonTileParams *const tiles = &cm->tiles;
   const int mi_cols =
-      ALIGN_POWER_OF_TWO(cm->mi_cols, seq_params->mib_size_log2);
+      ALIGN_POWER_OF_TWO(cm->mi_params.mi_cols, seq_params->mib_size_log2);
   const int mi_rows =
-      ALIGN_POWER_OF_TWO(cm->mi_rows, seq_params->mib_size_log2);
+      ALIGN_POWER_OF_TWO(cm->mi_params.mi_rows, seq_params->mib_size_log2);
   const int sb_cols = mi_cols >> seq_params->mib_size_log2;
   const int sb_rows = mi_rows >> seq_params->mib_size_log2;
 
@@ -135,7 +135,7 @@
                    << cm->seq_params.mib_size_log2;
   tile->tile_row = row;
   tile->mi_row_start = mi_row_start;
-  tile->mi_row_end = AOMMIN(mi_row_end, cm->mi_rows);
+  tile->mi_row_end = AOMMIN(mi_row_end, cm->mi_params.mi_rows);
   assert(tile->mi_row_end > tile->mi_row_start);
 }
 
@@ -147,7 +147,7 @@
                    << cm->seq_params.mib_size_log2;
   tile->tile_col = col;
   tile->mi_col_start = mi_col_start;
-  tile->mi_col_end = AOMMIN(mi_col_end, cm->mi_cols);
+  tile->mi_col_end = AOMMIN(mi_col_end, cm->mi_params.mi_cols);
   assert(tile->mi_col_end > tile->mi_col_start);
 }
 
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 4f79d72..ccad632 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -321,13 +321,14 @@
                                    BLOCK_SIZE bsize, int mi_row, int mi_col,
                                    int bw, int bh, int x_mis, int y_mis) {
   const int num_planes = av1_num_planes(cm);
-
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   const TileInfo *const tile = &xd->tile;
 
-  xd->mi = cm->mi_grid_base + get_mi_grid_idx(cm, mi_row, mi_col);
-  xd->mi[0] = &cm->mi[get_alloc_mi_idx(cm, mi_row, mi_col)];
-  xd->tx_type_map = &cm->tx_type_map[mi_row * cm->mi_stride + mi_col];
-  xd->tx_type_map_stride = cm->mi_stride;
+  xd->mi = mi_params->mi_grid_base + get_mi_grid_idx(mi_params, mi_row, mi_col);
+  xd->mi[0] = &mi_params->mi[get_alloc_mi_idx(mi_params, mi_row, mi_col)];
+  xd->tx_type_map =
+      &mi_params->tx_type_map[mi_row * mi_params->mi_stride + mi_col];
+  xd->tx_type_map_stride = mi_params->mi_stride;
   // TODO(slavarnway): Generate sb_type based on bwl and bhl, instead of
   // passing bsize from decode_partition().
   xd->mi[0]->sb_type = bsize;
@@ -338,10 +339,10 @@
 
   assert(x_mis && y_mis);
   for (int x = 1; x < x_mis; ++x) xd->mi[x] = xd->mi[0];
-  int idx = cm->mi_stride;
+  int idx = mi_params->mi_stride;
   for (int y = 1; y < y_mis; ++y) {
     memcpy(&xd->mi[idx], &xd->mi[0], x_mis * sizeof(xd->mi[0]));
-    idx += cm->mi_stride;
+    idx += mi_params->mi_stride;
   }
 
   set_plane_n4(xd, bw, bh, num_planes);
@@ -349,7 +350,8 @@
 
   // Distance of Mb to the various image edges. These are specified to 8th pel
   // as they are always compared to values that are in 1/8th pel units
-  set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols);
+  set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, mi_params->mi_rows,
+                 mi_params->mi_cols);
 
   av1_setup_dst_planes(xd->plane, bsize, &cm->cur_frame->buf, mi_row, mi_col, 0,
                        num_planes);
@@ -364,8 +366,8 @@
   const SequenceHeader *const seq_params = &cm->seq_params;
   const int bw = mi_size_wide[bsize];
   const int bh = mi_size_high[bsize];
-  const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
-  const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
+  const int x_mis = AOMMIN(bw, cm->mi_params.mi_cols - mi_col);
+  const int y_mis = AOMMIN(bh, cm->mi_params.mi_rows - mi_row);
 
 #if CONFIG_ACCOUNTING
   aom_accounting_set_context(&pbi->accounting, mi_col, mi_row);
@@ -1474,23 +1476,26 @@
                                                       int mi_row, int mi_col,
                                                       BLOCK_SIZE bsize) {
   AV1_COMMON *const cm = &pbi->common;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   MACROBLOCKD *const xd = &td->xd;
   const int bw = mi_size_wide[bsize];
   const int bh = mi_size_high[bsize];
   const int num_planes = av1_num_planes(cm);
 
-  const int offset = mi_row * cm->mi_stride + mi_col;
+  const int offset = mi_row * mi_params->mi_stride + mi_col;
   const TileInfo *const tile = &xd->tile;
 
-  xd->mi = cm->mi_grid_base + offset;
-  xd->tx_type_map = &cm->tx_type_map[mi_row * cm->mi_stride + mi_col];
-  xd->tx_type_map_stride = cm->mi_stride;
+  xd->mi = mi_params->mi_grid_base + offset;
+  xd->tx_type_map =
+      &mi_params->tx_type_map[mi_row * mi_params->mi_stride + mi_col];
+  xd->tx_type_map_stride = mi_params->mi_stride;
 
   set_plane_n4(xd, bw, bh, num_planes);
 
   // Distance of Mb to the various image edges. These are specified to 8th pel
   // as they are always compared to values that are in 1/8th pel units
-  set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols);
+  set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, mi_params->mi_rows,
+                 mi_params->mi_cols);
 
   av1_setup_dst_planes(xd->plane, bsize, &cm->cur_frame->buf, mi_row, mi_col, 0,
                        num_planes);
@@ -1549,10 +1554,11 @@
   BLOCK_SIZE subsize;
   const int quarter_step = bw / 4;
   BLOCK_SIZE bsize2 = get_partition_subsize(bsize, PARTITION_SPLIT);
-  const int has_rows = (mi_row + hbs) < cm->mi_rows;
-  const int has_cols = (mi_col + hbs) < cm->mi_cols;
+  const int has_rows = (mi_row + hbs) < cm->mi_params.mi_rows;
+  const int has_cols = (mi_col + hbs) < cm->mi_params.mi_cols;
 
-  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
+  if (mi_row >= cm->mi_params.mi_rows || mi_col >= cm->mi_params.mi_cols)
+    return;
 
   // parse_decode_flag takes the following values :
   // 01 - do parse only
@@ -1648,14 +1654,14 @@
     case PARTITION_HORZ_4:
       for (int i = 0; i < 4; ++i) {
         int this_mi_row = mi_row + i * quarter_step;
-        if (i > 0 && this_mi_row >= cm->mi_rows) break;
+        if (i > 0 && this_mi_row >= cm->mi_params.mi_rows) break;
         DEC_BLOCK(this_mi_row, mi_col, subsize);
       }
       break;
     case PARTITION_VERT_4:
       for (int i = 0; i < 4; ++i) {
         int this_mi_col = mi_col + i * quarter_step;
-        if (i > 0 && this_mi_col >= cm->mi_cols) break;
+        if (i > 0 && this_mi_col >= cm->mi_params.mi_cols) break;
         DEC_BLOCK(mi_row, this_mi_col, subsize);
       }
       break;
@@ -1700,15 +1706,16 @@
   seg->enabled = aom_rb_read_bit(rb);
   if (!seg->enabled) {
     if (cm->cur_frame->seg_map)
-      memset(cm->cur_frame->seg_map, 0, (cm->mi_rows * cm->mi_cols));
+      memset(cm->cur_frame->seg_map, 0,
+             (cm->mi_params.mi_rows * cm->mi_params.mi_cols));
 
     memset(seg, 0, sizeof(*seg));
     segfeatures_copy(&cm->cur_frame->seg, seg);
     return;
   }
   if (cm->seg.enabled && cm->prev_frame &&
-      (cm->mi_rows == cm->prev_frame->mi_rows) &&
-      (cm->mi_cols == cm->prev_frame->mi_cols)) {
+      (cm->mi_params.mi_rows == cm->prev_frame->mi_rows) &&
+      (cm->mi_params.mi_cols == cm->prev_frame->mi_cols)) {
     cm->last_frame_seg_map = cm->prev_frame->seg_map;
   } else {
     cm->last_frame_seg_map = NULL;
@@ -2162,7 +2169,8 @@
 
     // Allocations in av1_alloc_context_buffers() depend on individual
     // dimensions as well as the overall size.
-    if (new_mi_cols > cm->mi_cols || new_mi_rows > cm->mi_rows) {
+    if (new_mi_cols > cm->mi_params.mi_cols ||
+        new_mi_rows > cm->mi_params.mi_rows) {
       if (av1_alloc_context_buffers(cm, width, height)) {
         // The cm->mi_* values have been cleared and any existing context
         // buffers have been freed. Clear cm->width and cm->height to be
@@ -2173,9 +2181,9 @@
                            "Failed to allocate context buffers");
       }
     } else {
-      cm->set_mb_mi(cm, width, height);
+      cm->mi_params.set_mb_mi(&cm->mi_params, width, height);
     }
-    av1_init_context_buffers(cm);
+    av1_init_mi_buffers(&cm->mi_params);
     cm->width = width;
     cm->height = height;
   }
@@ -2337,8 +2345,10 @@
     AV1_COMMON *const cm, struct aom_read_bit_buffer *const rb) {
   const SequenceHeader *const seq_params = &cm->seq_params;
   CommonTileParams *const tiles = &cm->tiles;
-  int width_mi = ALIGN_POWER_OF_TWO(cm->mi_cols, seq_params->mib_size_log2);
-  int height_mi = ALIGN_POWER_OF_TWO(cm->mi_rows, seq_params->mib_size_log2);
+  int width_mi =
+      ALIGN_POWER_OF_TWO(cm->mi_params.mi_cols, seq_params->mib_size_log2);
+  int height_mi =
+      ALIGN_POWER_OF_TWO(cm->mi_params.mi_rows, seq_params->mib_size_log2);
   int width_sb = width_mi >> seq_params->mib_size_log2;
   int height_sb = height_mi >> seq_params->mib_size_log2;
 
@@ -2367,7 +2377,8 @@
     tiles->cols = i;
     tiles->col_start_sb[i] = start_sb + width_sb;
   }
-  av1_calculate_tile_cols(seq_params, cm->mi_rows, cm->mi_cols, tiles);
+  av1_calculate_tile_cols(seq_params, cm->mi_params.mi_rows,
+                          cm->mi_params.mi_cols, tiles);
 
   // Read tile rows
   if (tiles->uniform_spacing) {
@@ -2391,7 +2402,7 @@
     tiles->rows = i;
     tiles->row_start_sb[i] = start_sb + height_sb;
   }
-  av1_calculate_tile_rows(seq_params, cm->mi_rows, tiles);
+  av1_calculate_tile_rows(seq_params, cm->mi_params.mi_rows, tiles);
 }
 
 void av1_set_single_tile_decoding_mode(AV1_COMMON *const cm) {
@@ -2676,7 +2687,7 @@
                                      int mi_col) {
   AV1_COMMON *const cm = &pbi->common;
   int mib_size_log2 = cm->seq_params.mib_size_log2;
-  int stride = (cm->mi_cols >> mib_size_log2) + 1;
+  int stride = (cm->mi_params.mi_cols >> mib_size_log2) + 1;
   int offset = (mi_row >> mib_size_log2) * stride + (mi_col >> mib_size_log2);
   CB_BUFFER *cb_buffer = cb_buffer_base + offset;
 
@@ -3822,8 +3833,8 @@
 
 static AOM_INLINE void dec_alloc_cb_buf(AV1Decoder *pbi) {
   AV1_COMMON *const cm = &pbi->common;
-  int size = ((cm->mi_rows >> cm->seq_params.mib_size_log2) + 1) *
-             ((cm->mi_cols >> cm->seq_params.mib_size_log2) + 1);
+  int size = ((cm->mi_params.mi_rows >> cm->seq_params.mib_size_log2) + 1) *
+             ((cm->mi_params.mi_cols >> cm->seq_params.mib_size_log2) + 1);
 
   if (pbi->cb_buffer_alloc_size < size) {
     av1_dec_free_cb_buf(pbi);
@@ -5169,7 +5180,7 @@
   xd->bd = (int)seq_params->bit_depth;
 
   if (cm->num_allocated_above_context_planes < av1_num_planes(cm) ||
-      cm->num_allocated_above_context_mi_col < cm->mi_cols ||
+      cm->num_allocated_above_context_mi_col < cm->mi_params.mi_cols ||
       cm->num_allocated_above_contexts < cm->tiles.rows) {
     av1_free_above_context_buffers(cm, cm->num_allocated_above_contexts);
     if (av1_alloc_above_context_buffers(cm, cm->tiles.rows))
@@ -5360,7 +5371,7 @@
     return uncomp_hdr_size;
   }
 
-  cm->setup_mi(cm);
+  cm->mi_params.setup_mi(&cm->mi_params);
 
   av1_setup_motion_field(cm);
 
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index fd122e3..d8af601 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -57,11 +57,12 @@
   const int index = cm->seq_params.sb_size == BLOCK_128X128
                         ? !!(mi_col & mask) + 2 * !!(mi_row & mask)
                         : 0;
-  cm->mi_grid_base[(mi_row & m) * cm->mi_stride + (mi_col & m)]->cdef_strength =
-      xd->cdef_preset[index] =
-          xd->cdef_preset[index] == -1 && !mbmi->skip
-              ? aom_read_literal(r, cm->cdef_info.cdef_bits, ACCT_STR)
-              : xd->cdef_preset[index];
+  cm->mi_params
+      .mi_grid_base[(mi_row & m) * cm->mi_params.mi_stride + (mi_col & m)]
+      ->cdef_strength = xd->cdef_preset[index] =
+      xd->cdef_preset[index] == -1 && !mbmi->skip
+          ? aom_read_literal(r, cm->cdef_info.cdef_bits, ACCT_STR)
+          : xd->cdef_preset[index];
 }
 
 static int read_delta_qindex(AV1_COMMON *cm, const MACROBLOCKD *xd,
@@ -286,8 +287,8 @@
 
   for (int y = 0; y < y_mis; y++)
     for (int x = 0; x < x_mis; x++)
-      segment_id =
-          AOMMIN(segment_id, segment_ids[mi_offset + y * cm->mi_cols + x]);
+      segment_id = AOMMIN(
+          segment_id, segment_ids[mi_offset + y * cm->mi_params.mi_cols + x]);
 
   assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);
   return segment_id;
@@ -299,7 +300,8 @@
 
   for (int y = 0; y < y_mis; y++)
     for (int x = 0; x < x_mis; x++)
-      cm->cur_frame->seg_map[mi_offset + y * cm->mi_cols + x] = segment_id;
+      cm->cur_frame->seg_map[mi_offset + y * cm->mi_params.mi_cols + x] =
+          segment_id;
 }
 
 static int read_intra_segment_id(AV1_COMMON *const cm,
@@ -307,30 +309,31 @@
                                  aom_reader *r, int skip) {
   struct segmentation *const seg = &cm->seg;
   if (!seg->enabled) return 0;  // Default for disabled segmentation
-
   assert(seg->update_map && !seg->temporal_update);
 
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   const int mi_row = xd->mi_row;
   const int mi_col = xd->mi_col;
-  const int mi_offset = mi_row * cm->mi_cols + mi_col;
+  const int mi_offset = mi_row * mi_params->mi_cols + mi_col;
   const int bw = mi_size_wide[bsize];
   const int bh = mi_size_high[bsize];
-  const int x_mis = AOMMIN(cm->mi_cols - mi_col, bw);
-  const int y_mis = AOMMIN(cm->mi_rows - mi_row, bh);
+  const int x_mis = AOMMIN(mi_params->mi_cols - mi_col, bw);
+  const int y_mis = AOMMIN(mi_params->mi_rows - mi_row, bh);
   const int segment_id = read_segment_id(cm, xd, r, skip);
   set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
   return segment_id;
 }
 
-static void copy_segment_id(const AV1_COMMON *cm,
+static void copy_segment_id(const CommonModeInfoParams *const mi_params,
                             const uint8_t *last_segment_ids,
                             uint8_t *current_segment_ids, int mi_offset,
                             int x_mis, int y_mis) {
   for (int y = 0; y < y_mis; y++)
     for (int x = 0; x < x_mis; x++)
-      current_segment_ids[mi_offset + y * cm->mi_cols + x] =
-          last_segment_ids ? last_segment_ids[mi_offset + y * cm->mi_cols + x]
-                           : 0;
+      current_segment_ids[mi_offset + y * mi_params->mi_cols + x] =
+          last_segment_ids
+              ? last_segment_ids[mi_offset + y * mi_params->mi_cols + x]
+              : 0;
 }
 
 static int get_predicted_segment_id(AV1_COMMON *const cm, int mi_offset,
@@ -343,21 +346,22 @@
 static int read_inter_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                                  int preskip, aom_reader *r) {
   struct segmentation *const seg = &cm->seg;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   MB_MODE_INFO *const mbmi = xd->mi[0];
   const int mi_row = xd->mi_row;
   const int mi_col = xd->mi_col;
-  const int mi_offset = mi_row * cm->mi_cols + mi_col;
+  const int mi_offset = mi_row * mi_params->mi_cols + mi_col;
   const int bw = mi_size_wide[mbmi->sb_type];
   const int bh = mi_size_high[mbmi->sb_type];
 
   // TODO(slavarnway): move x_mis, y_mis into xd ?????
-  const int x_mis = AOMMIN(cm->mi_cols - mi_col, bw);
-  const int y_mis = AOMMIN(cm->mi_rows - mi_row, bh);
+  const int x_mis = AOMMIN(mi_params->mi_cols - mi_col, bw);
+  const int y_mis = AOMMIN(mi_params->mi_rows - mi_row, bh);
 
   if (!seg->enabled) return 0;  // Default for disabled segmentation
 
   if (!seg->update_map) {
-    copy_segment_id(cm, cm->last_frame_seg_map, cm->cur_frame->seg_map,
+    copy_segment_id(mi_params, cm->last_frame_seg_map, cm->cur_frame->seg_map,
                     mi_offset, x_mis, y_mis);
     return get_predicted_segment_id(cm, mi_offset, x_mis, y_mis);
   }
@@ -1519,7 +1523,7 @@
 
 static void intra_copy_frame_mvs(AV1_COMMON *const cm, int mi_row, int mi_col,
                                  int x_mis, int y_mis) {
-  const int frame_mvs_stride = ROUND_POWER_OF_TWO(cm->mi_cols, 1);
+  const int frame_mvs_stride = ROUND_POWER_OF_TWO(cm->mi_params.mi_cols, 1);
   MV_REF *frame_mvs =
       cm->cur_frame->mvs + (mi_row >> 1) * frame_mvs_stride + (mi_col >> 1);
   x_mis = ROUND_POWER_OF_TWO(x_mis, 1);
diff --git a/av1/decoder/decoder.c b/av1/decoder/decoder.c
index 1b989e5..041776b 100644
--- a/av1/decoder/decoder.c
+++ b/av1/decoder/decoder.c
@@ -45,7 +45,8 @@
   av1_init_wedge_masks();
 }
 
-static void dec_set_mb_mi(AV1_COMMON *cm, int width, int height) {
+static void dec_set_mb_mi(CommonModeInfoParams *mi_params, int width,
+                          int height) {
   // Ensure that the decoded width and height are both multiples of
   // 8 luma pixels (note: this may only be a multiple of 4 chroma pixels if
   // subsampling is used).
@@ -54,62 +55,68 @@
   const int aligned_width = ALIGN_POWER_OF_TWO(width, 3);
   const int aligned_height = ALIGN_POWER_OF_TWO(height, 3);
 
-  cm->mi_cols = aligned_width >> MI_SIZE_LOG2;
-  cm->mi_rows = aligned_height >> MI_SIZE_LOG2;
-  cm->mi_stride = calc_mi_size(cm->mi_cols);
+  mi_params->mi_cols = aligned_width >> MI_SIZE_LOG2;
+  mi_params->mi_rows = aligned_height >> MI_SIZE_LOG2;
+  mi_params->mi_stride = calc_mi_size(mi_params->mi_cols);
 
-  cm->mb_cols = (cm->mi_cols + 2) >> 2;
-  cm->mb_rows = (cm->mi_rows + 2) >> 2;
-  cm->MBs = cm->mb_rows * cm->mb_cols;
+  mi_params->mb_cols = (mi_params->mi_cols + 2) >> 2;
+  mi_params->mb_rows = (mi_params->mi_rows + 2) >> 2;
+  mi_params->MBs = mi_params->mb_rows * mi_params->mb_cols;
 
-  cm->mi_alloc_bsize = BLOCK_4X4;
-  cm->mi_alloc_rows = cm->mi_rows;
-  cm->mi_alloc_cols = cm->mi_cols;
-  cm->mi_alloc_stride = cm->mi_stride;
+  mi_params->mi_alloc_bsize = BLOCK_4X4;
+  mi_params->mi_alloc_rows = mi_params->mi_rows;
+  mi_params->mi_alloc_cols = mi_params->mi_cols;
+  mi_params->mi_alloc_stride = mi_params->mi_stride;
 
-  assert(mi_size_wide[cm->mi_alloc_bsize] == mi_size_high[cm->mi_alloc_bsize]);
+  assert(mi_size_wide[mi_params->mi_alloc_bsize] ==
+         mi_size_high[mi_params->mi_alloc_bsize]);
 
 #if CONFIG_LPF_MASK
-  av1_alloc_loop_filter_mask(cm);
+  av1_alloc_loop_filter_mask(mi_params);
 #endif
 }
 
-static void dec_setup_mi(AV1_COMMON *cm) {
-  const int mi_grid_size = cm->mi_stride * calc_mi_size(cm->mi_rows);
-  memset(cm->mi_grid_base, 0, mi_grid_size * sizeof(*cm->mi_grid_base));
+static void dec_setup_mi(CommonModeInfoParams *mi_params) {
+  const int mi_grid_size =
+      mi_params->mi_stride * calc_mi_size(mi_params->mi_rows);
+  memset(mi_params->mi_grid_base, 0,
+         mi_grid_size * sizeof(*mi_params->mi_grid_base));
 }
 
-static int dec_alloc_mi(AV1_COMMON *cm) {
-  const int mi_grid_size = cm->mi_stride * calc_mi_size(cm->mi_rows);
+static int dec_alloc_mi(CommonModeInfoParams *mi_params) {
+  const int mi_grid_size =
+      mi_params->mi_stride * calc_mi_size(mi_params->mi_rows);
 
-  if (cm->mi_alloc_size < mi_grid_size || cm->mi_grid_size < mi_grid_size) {
-    cm->free_mi(cm);
+  if (mi_params->mi_alloc_size < mi_grid_size ||
+      mi_params->mi_grid_size < mi_grid_size) {
+    mi_params->free_mi(mi_params);
 
-    cm->mi = aom_calloc(mi_grid_size, sizeof(*cm->mi));
-    if (!cm->mi) return 1;
-    cm->mi_alloc_size = mi_grid_size;
+    mi_params->mi = aom_calloc(mi_grid_size, sizeof(*mi_params->mi));
+    if (!mi_params->mi) return 1;
+    mi_params->mi_alloc_size = mi_grid_size;
 
-    cm->mi_grid_base =
+    mi_params->mi_grid_base =
         (MB_MODE_INFO **)aom_calloc(mi_grid_size, sizeof(MB_MODE_INFO *));
-    if (!cm->mi_grid_base) return 1;
-    cm->mi_grid_size = mi_grid_size;
+    if (!mi_params->mi_grid_base) return 1;
+    mi_params->mi_grid_size = mi_grid_size;
 
-    cm->tx_type_map = aom_calloc(calc_mi_size(cm->mi_rows) * cm->mi_stride,
-                                 sizeof(*cm->tx_type_map));
-    if (!cm->tx_type_map) return 1;
+    mi_params->tx_type_map =
+        aom_calloc(calc_mi_size(mi_params->mi_rows) * mi_params->mi_stride,
+                   sizeof(*mi_params->tx_type_map));
+    if (!mi_params->tx_type_map) return 1;
   }
 
   return 0;
 }
 
-static void dec_free_mi(AV1_COMMON *cm) {
-  aom_free(cm->mi);
-  cm->mi = NULL;
-  aom_free(cm->mi_grid_base);
-  cm->mi_grid_base = NULL;
-  cm->mi_alloc_size = 0;
-  aom_free(cm->tx_type_map);
-  cm->tx_type_map = NULL;
+static void dec_free_mi(CommonModeInfoParams *mi_params) {
+  aom_free(mi_params->mi);
+  mi_params->mi = NULL;
+  aom_free(mi_params->mi_grid_base);
+  mi_params->mi_grid_base = NULL;
+  mi_params->mi_alloc_size = 0;
+  aom_free(mi_params->tx_type_map);
+  mi_params->tx_type_map = NULL;
 }
 
 AV1Decoder *av1_decoder_create(BufferPool *const pool) {
@@ -152,10 +159,10 @@
 
   cm->seq_params.bit_depth = AOM_BITS_8;
 
-  cm->alloc_mi = dec_alloc_mi;
-  cm->free_mi = dec_free_mi;
-  cm->setup_mi = dec_setup_mi;
-  cm->set_mb_mi = dec_set_mb_mi;
+  cm->mi_params.alloc_mi = dec_alloc_mi;
+  cm->mi_params.free_mi = dec_free_mi;
+  cm->mi_params.setup_mi = dec_setup_mi;
+  cm->mi_params.set_mb_mi = dec_set_mb_mi;
 
   av1_loop_filter_init(cm);
 
@@ -525,8 +532,9 @@
 
   if (!cm->show_existing_frame) {
     if (cm->seg.enabled) {
-      if (cm->prev_frame && (cm->mi_rows == cm->prev_frame->mi_rows) &&
-          (cm->mi_cols == cm->prev_frame->mi_cols)) {
+      if (cm->prev_frame &&
+          (cm->mi_params.mi_rows == cm->prev_frame->mi_rows) &&
+          (cm->mi_params.mi_cols == cm->prev_frame->mi_cols)) {
         cm->last_frame_seg_map = cm->prev_frame->seg_map;
       } else {
         cm->last_frame_seg_map = NULL;
diff --git a/av1/decoder/inspection.c b/av1/decoder/inspection.c
index 26041e3..72ced47 100644
--- a/av1/decoder/inspection.c
+++ b/av1/decoder/inspection.c
@@ -36,10 +36,11 @@
 int ifd_inspect(insp_frame_data *fd, void *decoder, int skip_not_transform) {
   struct AV1Decoder *pbi = (struct AV1Decoder *)decoder;
   AV1_COMMON *const cm = &pbi->common;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
 
-  if (fd->mi_rows != cm->mi_rows || fd->mi_cols != cm->mi_cols) {
+  if (fd->mi_rows != mi_params->mi_rows || fd->mi_cols != mi_params->mi_cols) {
     ifd_clear(fd);
-    ifd_init_mi_rc(fd, cm->mi_rows, cm->mi_cols);
+    ifd_init_mi_rc(fd, mi_params->mi_rows, mi_params->mi_cols);
   }
   fd->show_existing_frame = cm->show_existing_frame;
   fd->frame_number = cm->current_frame.frame_number;
@@ -66,10 +67,11 @@
       fd->v_dequant[i][j] = cm->v_dequant_QTX[i][j];
     }
   }
-  for (j = 0; j < cm->mi_rows; j++) {
-    for (i = 0; i < cm->mi_cols; i++) {
-      const MB_MODE_INFO *mbmi = cm->mi_grid_base[j * cm->mi_stride + i];
-      insp_mi_data *mi = &fd->mi_grid[j * cm->mi_cols + i];
+  for (j = 0; j < mi_params->mi_rows; j++) {
+    for (i = 0; i < mi_params->mi_cols; i++) {
+      const MB_MODE_INFO *mbmi =
+          mi_params->mi_grid_base[j * mi_params->mi_stride + i];
+      insp_mi_data *mi = &fd->mi_grid[j * mi_params->mi_cols + i];
       // Segment
       mi->segment_id = mbmi->segment_id;
       // Motion Vectors
@@ -119,8 +121,9 @@
       if (mi->skip) {
         const int tx_type_row = j - j % tx_size_high_unit[mi->tx_size];
         const int tx_type_col = i - i % tx_size_wide_unit[mi->tx_size];
-        const int tx_type_map_idx = tx_type_row * cm->mi_stride + tx_type_col;
-        mi->tx_type = cm->tx_type_map[tx_type_map_idx];
+        const int tx_type_map_idx =
+            tx_type_row * mi_params->mi_stride + tx_type_col;
+        mi->tx_type = mi_params->tx_type_map[tx_type_map_idx];
       } else {
         mi->tx_type = 0;
       }
diff --git a/av1/encoder/aq_complexity.c b/av1/encoder/aq_complexity.c
index 70740c7..936eddc 100644
--- a/av1/encoder/aq_complexity.c
+++ b/av1/encoder/aq_complexity.c
@@ -70,7 +70,8 @@
   aom_clear_system_state();
 
   if (resolution_change) {
-    memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
+    memset(cpi->segmentation_map, 0,
+           cm->mi_params.mi_rows * cm->mi_params.mi_cols);
     av1_clearall_segfeatures(seg);
     av1_disable_segmentation(seg);
     return;
@@ -82,7 +83,8 @@
         get_aq_c_strength(cm->base_qindex, cm->seq_params.bit_depth);
 
     // Clear down the segment map.
-    memset(cpi->segmentation_map, DEFAULT_AQ2_SEG, cm->mi_rows * cm->mi_cols);
+    memset(cpi->segmentation_map, DEFAULT_AQ2_SEG,
+           cm->mi_params.mi_rows * cm->mi_params.mi_cols);
 
     av1_clearall_segfeatures(seg);
 
@@ -132,9 +134,9 @@
   const AV1_COMMON *const cm = &cpi->common;
   const int num_planes = av1_num_planes(cm);
 
-  const int mi_offset = mi_row * cm->mi_cols + mi_col;
-  const int xmis = AOMMIN(cm->mi_cols - mi_col, mi_size_wide[bs]);
-  const int ymis = AOMMIN(cm->mi_rows - mi_row, mi_size_high[bs]);
+  const int mi_offset = mi_row * cm->mi_params.mi_cols + mi_col;
+  const int xmis = AOMMIN(cm->mi_params.mi_cols - mi_col, mi_size_wide[bs]);
+  const int ymis = AOMMIN(cm->mi_params.mi_rows - mi_row, mi_size_high[bs]);
   int x, y;
   int i;
   unsigned char segment;
@@ -177,7 +179,8 @@
   // Fill in the entires in the segment map corresponding to this SB64.
   for (y = 0; y < ymis; y++) {
     for (x = 0; x < xmis; x++) {
-      cpi->segmentation_map[mi_offset + y * cm->mi_cols + x] = segment;
+      cpi->segmentation_map[mi_offset + y * cm->mi_params.mi_cols + x] =
+          segment;
     }
   }
 }
diff --git a/av1/encoder/aq_cyclicrefresh.c b/av1/encoder/aq_cyclicrefresh.c
index c3b266a..3866411 100644
--- a/av1/encoder/aq_cyclicrefresh.c
+++ b/av1/encoder/aq_cyclicrefresh.c
@@ -98,7 +98,7 @@
   const AV1_COMMON *const cm = &cpi->common;
   const CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
   int estimated_bits;
-  int mbs = cm->MBs;
+  int mbs = cm->mi_params.MBs;
   int num4x4bl = mbs << 4;
   // Weight for non-base segments: use actual number of blocks refreshed in
   // previous/just encoded frame. Note number of blocks here is in 4x4 units.
@@ -131,7 +131,7 @@
   const AV1_COMMON *const cm = &cpi->common;
   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
   int bits_per_mb;
-  int num4x4bl = cm->MBs << 4;
+  int num4x4bl = cm->mi_params.MBs << 4;
   // Weight for segment prior to encoding: take the average of the target
   // number for the frame to be encoded and the actual from the previous frame.
   double weight_segment =
@@ -164,9 +164,9 @@
   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
   const int bw = mi_size_wide[bsize];
   const int bh = mi_size_high[bsize];
-  const int xmis = AOMMIN(cm->mi_cols - mi_col, bw);
-  const int ymis = AOMMIN(cm->mi_rows - mi_row, bh);
-  const int block_index = mi_row * cm->mi_cols + mi_col;
+  const int xmis = AOMMIN(cm->mi_params.mi_cols - mi_col, bw);
+  const int ymis = AOMMIN(cm->mi_params.mi_rows - mi_row, bh);
+  const int block_index = mi_row * cm->mi_params.mi_cols + mi_col;
   const int refresh_this_block =
       candidate_refresh_aq(cr, mbmi, rate, dist, bsize);
   // Default is to not update the refresh map.
@@ -200,7 +200,7 @@
   // copy mbmi->segment_id into global segmentation map.
   for (int y = 0; y < ymis; y++)
     for (int x = 0; x < xmis; x++) {
-      int map_offset = block_index + y * cm->mi_cols + x;
+      int map_offset = block_index + y * cm->mi_params.mi_cols + x;
       cr->map[map_offset] = new_map_value;
       cpi->segmentation_map[map_offset] = mbmi->segment_id;
     }
@@ -209,17 +209,19 @@
 // Update the some stats after encode frame is done.
 void av1_cyclic_refresh_postencode(AV1_COMP *const cpi) {
   AV1_COMMON *const cm = &cpi->common;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
   unsigned char *const seg_map = cpi->segmentation_map;
   cr->cnt_zeromv = 0;
   cr->actual_num_seg1_blocks = 0;
   cr->actual_num_seg2_blocks = 0;
-  for (int mi_row = 0; mi_row < cm->mi_rows; mi_row++) {
-    for (int mi_col = 0; mi_col < cm->mi_cols; mi_col++) {
-      MB_MODE_INFO **mi = cm->mi_grid_base + mi_row * cm->mi_stride + mi_col;
+  for (int mi_row = 0; mi_row < mi_params->mi_rows; mi_row++) {
+    for (int mi_col = 0; mi_col < mi_params->mi_cols; mi_col++) {
+      MB_MODE_INFO **mi =
+          mi_params->mi_grid_base + mi_row * mi_params->mi_stride + mi_col;
       MV mv = mi[0]->mv[0].as_mv;
       if (cm->seg.enabled) {
-        int map_index = mi_row * cm->mi_cols + mi_col;
+        int map_index = mi_row * mi_params->mi_cols + mi_col;
         if (cyclic_refresh_segment_id(seg_map[map_index]) ==
             CR_SEGMENT_ID_BOOST1)
           cr->actual_num_seg1_blocks++;
@@ -232,7 +234,8 @@
         cr->cnt_zeromv++;
     }
   }
-  cr->cnt_zeromv = 100 * cr->cnt_zeromv / (cm->mi_rows * cm->mi_cols);
+  cr->cnt_zeromv =
+      100 * cr->cnt_zeromv / (mi_params->mi_rows * mi_params->mi_cols);
   cr->avg_frame_low_motion =
       (3 * cr->avg_frame_low_motion + (double)cr->cnt_zeromv) / 4;
 }
@@ -259,18 +262,20 @@
 // encoding of the superblock).
 static void cyclic_refresh_update_map(AV1_COMP *const cpi) {
   AV1_COMMON *const cm = &cpi->common;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
   unsigned char *const seg_map = cpi->segmentation_map;
   int i, block_count, bl_index, sb_rows, sb_cols, sbs_in_frame;
   int xmis, ymis, x, y;
-  memset(seg_map, CR_SEGMENT_ID_BASE, cm->mi_rows * cm->mi_cols);
-  sb_cols =
-      (cm->mi_cols + cm->seq_params.mib_size - 1) / cm->seq_params.mib_size;
-  sb_rows =
-      (cm->mi_rows + cm->seq_params.mib_size - 1) / cm->seq_params.mib_size;
+  memset(seg_map, CR_SEGMENT_ID_BASE, mi_params->mi_rows * mi_params->mi_cols);
+  sb_cols = (mi_params->mi_cols + cm->seq_params.mib_size - 1) /
+            cm->seq_params.mib_size;
+  sb_rows = (mi_params->mi_rows + cm->seq_params.mib_size - 1) /
+            cm->seq_params.mib_size;
   sbs_in_frame = sb_cols * sb_rows;
   // Number of target blocks to get the q delta (segment 1).
-  block_count = cr->percent_refresh * cm->mi_rows * cm->mi_cols / 100;
+  block_count =
+      cr->percent_refresh * mi_params->mi_rows * mi_params->mi_cols / 100;
   // Set the segmentation map: cycle through the superblocks, starting at
   // cr->mb_index, and stopping when either block_count blocks have been found
   // to be refreshed, or we have passed through whole frame.
@@ -292,15 +297,15 @@
         cpi->oxcf.content == AOM_CONTENT_SCREEN
             ? av1_get_qindex(&cm->seg, CR_SEGMENT_ID_BOOST2, cm->base_qindex)
             : 0;
-    assert(mi_row >= 0 && mi_row < cm->mi_rows);
-    assert(mi_col >= 0 && mi_col < cm->mi_cols);
-    bl_index = mi_row * cm->mi_cols + mi_col;
+    assert(mi_row >= 0 && mi_row < mi_params->mi_rows);
+    assert(mi_col >= 0 && mi_col < mi_params->mi_cols);
+    bl_index = mi_row * mi_params->mi_cols + mi_col;
     // Loop through all MI blocks in superblock and update map.
-    xmis = AOMMIN(cm->mi_cols - mi_col, cm->seq_params.mib_size);
-    ymis = AOMMIN(cm->mi_rows - mi_row, cm->seq_params.mib_size);
+    xmis = AOMMIN(mi_params->mi_cols - mi_col, cm->seq_params.mib_size);
+    ymis = AOMMIN(mi_params->mi_rows - mi_row, cm->seq_params.mib_size);
     for (y = 0; y < ymis; y++) {
       for (x = 0; x < xmis; x++) {
-        const int bl_index2 = bl_index + y * cm->mi_cols + x;
+        const int bl_index2 = bl_index + y * mi_params->mi_cols + x;
         // If the block is as a candidate for clean up then mark it
         // for possible boost/refresh (segment 1). The segment id may get
         // reset to 0 later if block gets coded anything other than GLOBALMV.
@@ -316,7 +321,7 @@
     if (sum_map >= xmis * ymis / 2) {
       for (y = 0; y < ymis; y++)
         for (x = 0; x < xmis; x++) {
-          seg_map[bl_index + y * cm->mi_cols + x] = CR_SEGMENT_ID_BOOST1;
+          seg_map[bl_index + y * mi_params->mi_cols + x] = CR_SEGMENT_ID_BOOST1;
         }
       cr->target_num_seg_blocks += xmis * ymis;
     }
@@ -334,7 +339,7 @@
   const RATE_CONTROL *const rc = &cpi->rc;
   const AV1_COMMON *const cm = &cpi->common;
   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
-  int num4x4bl = cm->MBs << 4;
+  int num4x4bl = cm->mi_params.MBs << 4;
   int target_refresh = 0;
   double weight_segment_target = 0;
   double weight_segment = 0;
@@ -390,7 +395,8 @@
   // number for the frame to be encoded and the actual from the previous frame.
   // Use the target if its less. To be used for setting the base qp for the
   // frame in av1_rc_regulate_q.
-  target_refresh = cr->percent_refresh * cm->mi_rows * cm->mi_cols / 100;
+  target_refresh =
+      cr->percent_refresh * cm->mi_params.mi_rows * cm->mi_params.mi_cols / 100;
   weight_segment_target = (double)(target_refresh) / num4x4bl;
   weight_segment = (double)((target_refresh + cr->actual_num_seg1_blocks +
                              cr->actual_num_seg2_blocks) >>
@@ -415,11 +421,12 @@
   if (!cr->apply_cyclic_refresh) {
     // Set segmentation map to 0 and disable.
     unsigned char *const seg_map = cpi->segmentation_map;
-    memset(seg_map, 0, cm->mi_rows * cm->mi_cols);
+    memset(seg_map, 0, cm->mi_params.mi_rows * cm->mi_params.mi_cols);
     av1_disable_segmentation(&cm->seg);
     if (cm->current_frame.frame_type == KEY_FRAME) {
       memset(cr->last_coded_q_map, MAXQ,
-             cm->mi_rows * cm->mi_cols * sizeof(*cr->last_coded_q_map));
+             cm->mi_params.mi_rows * cm->mi_params.mi_cols *
+                 sizeof(*cr->last_coded_q_map));
       cr->sb_index = 0;
     }
     return;
@@ -487,7 +494,7 @@
 void av1_cyclic_refresh_reset_resize(AV1_COMP *const cpi) {
   const AV1_COMMON *const cm = &cpi->common;
   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
-  memset(cr->map, 0, cm->mi_rows * cm->mi_cols);
+  memset(cr->map, 0, cm->mi_params.mi_rows * cm->mi_params.mi_cols);
   cr->sb_index = 0;
   cpi->refresh_golden_frame = 1;
 }
diff --git a/av1/encoder/aq_variance.c b/av1/encoder/aq_variance.c
index 07b1dac..6e3cc3c 100644
--- a/av1/encoder/aq_variance.c
+++ b/av1/encoder/aq_variance.c
@@ -57,7 +57,8 @@
   avg_ratio = rate_ratio[avg_energy];
 
   if (resolution_change) {
-    memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
+    memset(cpi->segmentation_map, 0,
+           cm->mi_params.mi_rows * cm->mi_params.mi_cols);
     av1_clearall_segfeatures(seg);
     aom_clear_system_state();
     av1_disable_segmentation(seg);
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 7c35623..2756c14 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -399,20 +399,20 @@
   }
 }
 
-static INLINE void set_spatial_segment_id(const AV1_COMMON *const cm,
-                                          uint8_t *segment_ids,
-                                          BLOCK_SIZE bsize, int mi_row,
-                                          int mi_col, int segment_id) {
-  const int mi_offset = mi_row * cm->mi_cols + mi_col;
+static INLINE void set_spatial_segment_id(
+    const CommonModeInfoParams *const mi_params, uint8_t *segment_ids,
+    BLOCK_SIZE bsize, int mi_row, int mi_col, int segment_id) {
+  const int mi_offset = mi_row * mi_params->mi_cols + mi_col;
   const int bw = mi_size_wide[bsize];
   const int bh = mi_size_high[bsize];
-  const int xmis = AOMMIN(cm->mi_cols - mi_col, bw);
-  const int ymis = AOMMIN(cm->mi_rows - mi_row, bh);
-  int x, y;
+  const int xmis = AOMMIN(mi_params->mi_cols - mi_col, bw);
+  const int ymis = AOMMIN(mi_params->mi_rows - mi_row, bh);
 
-  for (y = 0; y < ymis; ++y)
-    for (x = 0; x < xmis; ++x)
-      segment_ids[mi_offset + y * cm->mi_cols + x] = segment_id;
+  for (int y = 0; y < ymis; ++y) {
+    for (int x = 0; x < xmis; ++x) {
+      segment_ids[mi_offset + y * mi_params->mi_cols + x] = segment_id;
+    }
+  }
 }
 
 int av1_neg_interleave(int x, int ref, int max) {
@@ -457,10 +457,10 @@
     // changing from lossless to lossy.
     assert(is_inter_block(mbmi) || !cpi->has_lossless_segment);
 
-    set_spatial_segment_id(cm, cm->cur_frame->seg_map, mbmi->sb_type, mi_row,
-                           mi_col, pred);
-    set_spatial_segment_id(cm, cpi->segmentation_map, mbmi->sb_type, mi_row,
-                           mi_col, pred);
+    set_spatial_segment_id(&cm->mi_params, cm->cur_frame->seg_map,
+                           mbmi->sb_type, mi_row, mi_col, pred);
+    set_spatial_segment_id(&cm->mi_params, cpi->segmentation_map, mbmi->sb_type,
+                           mi_row, mi_col, pred);
     /* mbmi is read only but we need to update segment_id */
     ((MB_MODE_INFO *)mbmi)->segment_id = pred;
     return;
@@ -470,8 +470,8 @@
       av1_neg_interleave(mbmi->segment_id, pred, seg->last_active_segid + 1);
   aom_cdf_prob *pred_cdf = segp->spatial_pred_seg_cdf[cdf_num];
   aom_write_symbol(w, coded_id, pred_cdf, MAX_SEGMENTS);
-  set_spatial_segment_id(cm, cm->cur_frame->seg_map, mbmi->sb_type, mi_row,
-                         mi_col, mbmi->segment_id);
+  set_spatial_segment_id(&cm->mi_params, cm->cur_frame->seg_map, mbmi->sb_type,
+                         mi_row, mi_col, mbmi->segment_id);
 }
 
 #define WRITE_REF_BIT(bname, pname) \
@@ -868,7 +868,8 @@
   const int mi_row = xd->mi_row;
   const int mi_col = xd->mi_col;
   const MB_MODE_INFO *mbmi =
-      cm->mi_grid_base[(mi_row & m) * cm->mi_stride + (mi_col & m)];
+      cm->mi_params
+          .mi_grid_base[(mi_row & m) * cm->mi_params.mi_stride + (mi_col & m)];
   // Initialise when at top left part of the superblock
   if (!(mi_row & (cm->seq_params.mib_size - 1)) &&
       !(mi_col & (cm->seq_params.mib_size - 1))) {  // Top left?
@@ -915,8 +916,8 @@
         write_segment_id(cpi, mbmi, w, seg, segp, 0);
       }
       if (pred_flag) {
-        set_spatial_segment_id(cm, cm->cur_frame->seg_map, mbmi->sb_type,
-                               mi_row, mi_col, mbmi->segment_id);
+        set_spatial_segment_id(&cm->mi_params, cm->cur_frame->seg_map,
+                               mbmi->sb_type, mi_row, mi_col, mbmi->segment_id);
       }
     } else {
       write_segment_id(cpi, mbmi, w, seg, segp, 0);
@@ -1301,10 +1302,10 @@
 #if ENC_MISMATCH_DEBUG
 static AOM_INLINE void enc_dump_logs(AV1_COMP *cpi, int mi_row, int mi_col) {
   AV1_COMMON *const cm = &cpi->common;
-  const MB_MODE_INFO *const mbmi =
-      *(cm->mi_grid_base + (mi_row * cm->mi_stride + mi_col));
+  const MB_MODE_INFO *const mbmi = *(
+      cm->mi_params.mi_grid_base + (mi_row * cm->mi_params.mi_stride + mi_col));
   const MB_MODE_INFO_EXT_FRAME *const mbmi_ext_frame_base =
-      cpi->mbmi_ext_frame_base + get_mi_ext_idx(cm, mi_row, mi_col);
+      cpi->mbmi_ext_frame_base + get_mi_ext_idx(&cm->mi_params, mi_row, mi_col);
   if (is_inter_block(mbmi)) {
 #define FRAME_TO_CHECK 11
     if (cm->current_frame.frame_number == FRAME_TO_CHECK &&
@@ -1468,13 +1469,14 @@
                                      const TOKENEXTRA *const tok_end,
                                      int mi_row, int mi_col) {
   const AV1_COMMON *cm = &cpi->common;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   MACROBLOCKD *xd = &cpi->td.mb.e_mbd;
-  const int grid_idx = mi_row * cm->mi_stride + mi_col;
-  xd->mi = cm->mi_grid_base + grid_idx;
+  const int grid_idx = mi_row * mi_params->mi_stride + mi_col;
+  xd->mi = mi_params->mi_grid_base + grid_idx;
   cpi->td.mb.mbmi_ext_frame =
-      cpi->mbmi_ext_frame_base + get_mi_ext_idx(cm, mi_row, mi_col);
-  xd->tx_type_map = cm->tx_type_map + grid_idx;
-  xd->tx_type_map_stride = cm->mi_stride;
+      cpi->mbmi_ext_frame_base + get_mi_ext_idx(mi_params, mi_row, mi_col);
+  xd->tx_type_map = mi_params->tx_type_map + grid_idx;
+  xd->tx_type_map_stride = mi_params->mi_stride;
 
   const MB_MODE_INFO *mbmi = xd->mi[0];
   const BLOCK_SIZE bsize = mbmi->sb_type;
@@ -1483,7 +1485,8 @@
 
   const int bh = mi_size_high[bsize];
   const int bw = mi_size_wide[bsize];
-  set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols);
+  set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, mi_params->mi_rows,
+                 mi_params->mi_cols);
 
   xd->above_txfm_context = cm->above_txfm_context[tile->tile_row] + mi_col;
   xd->left_txfm_context =
@@ -1545,8 +1548,8 @@
 
   if (!is_partition_point) return;
 
-  const int has_rows = (mi_row + hbs) < cm->mi_rows;
-  const int has_cols = (mi_col + hbs) < cm->mi_cols;
+  const int has_rows = (mi_row + hbs) < cm->mi_params.mi_rows;
+  const int has_cols = (mi_col + hbs) < cm->mi_params.mi_cols;
   const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
   FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
 
@@ -1579,6 +1582,7 @@
     const TOKENEXTRA **tok, const TOKENEXTRA *const tok_end, int mi_row,
     int mi_col, BLOCK_SIZE bsize) {
   const AV1_COMMON *const cm = &cpi->common;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
   assert(bsize < BLOCK_SIZES_ALL);
   const int hbs = mi_size_wide[bsize] / 2;
@@ -1587,7 +1591,7 @@
   const PARTITION_TYPE partition = get_partition(cm, mi_row, mi_col, bsize);
   const BLOCK_SIZE subsize = get_partition_subsize(bsize, partition);
 
-  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
+  if (mi_row >= mi_params->mi_rows || mi_col >= mi_params->mi_cols) return;
 
   const int num_planes = av1_num_planes(cm);
   for (int plane = 0; plane < num_planes; ++plane) {
@@ -1614,12 +1618,12 @@
       break;
     case PARTITION_HORZ:
       write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col);
-      if (mi_row + hbs < cm->mi_rows)
+      if (mi_row + hbs < mi_params->mi_rows)
         write_modes_b(cpi, tile, w, tok, tok_end, mi_row + hbs, mi_col);
       break;
     case PARTITION_VERT:
       write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col);
-      if (mi_col + hbs < cm->mi_cols)
+      if (mi_col + hbs < mi_params->mi_cols)
         write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col + hbs);
       break;
     case PARTITION_SPLIT:
@@ -1652,7 +1656,7 @@
     case PARTITION_HORZ_4:
       for (i = 0; i < 4; ++i) {
         int this_mi_row = mi_row + i * quarter_step;
-        if (i > 0 && this_mi_row >= cm->mi_rows) break;
+        if (i > 0 && this_mi_row >= mi_params->mi_rows) break;
 
         write_modes_b(cpi, tile, w, tok, tok_end, this_mi_row, mi_col);
       }
@@ -1660,7 +1664,7 @@
     case PARTITION_VERT_4:
       for (i = 0; i < 4; ++i) {
         int this_mi_col = mi_col + i * quarter_step;
-        if (i > 0 && this_mi_col >= cm->mi_cols) break;
+        if (i > 0 && this_mi_col >= mi_params->mi_cols) break;
 
         write_modes_b(cpi, tile, w, tok, tok_end, mi_row, this_mi_col);
       }
@@ -2120,8 +2124,10 @@
 
 static AOM_INLINE void write_tile_info_max_tile(
     const AV1_COMMON *const cm, struct aom_write_bit_buffer *wb) {
-  int width_mi = ALIGN_POWER_OF_TWO(cm->mi_cols, cm->seq_params.mib_size_log2);
-  int height_mi = ALIGN_POWER_OF_TWO(cm->mi_rows, cm->seq_params.mib_size_log2);
+  int width_mi =
+      ALIGN_POWER_OF_TWO(cm->mi_params.mi_cols, cm->seq_params.mib_size_log2);
+  int height_mi =
+      ALIGN_POWER_OF_TWO(cm->mi_params.mi_rows, cm->seq_params.mib_size_log2);
   int width_sb = width_mi >> cm->seq_params.mib_size_log2;
   int height_sb = height_mi >> cm->seq_params.mib_size_log2;
   int size_sb, i;
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index 5b0b014..3b7f842 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -875,10 +875,11 @@
   av1_setup_block_planes(xd, cm->seq_params.subsampling_x,
                          cm->seq_params.subsampling_y, num_planes);
 
-  xd->mi = cm->mi_grid_base;
-  xd->mi[0] = cm->mi;
-  xd->tx_type_map = cm->tx_type_map;
-  xd->tx_type_map_stride = cm->mi_stride;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
+  xd->mi = mi_params->mi_grid_base;
+  xd->mi[0] = mi_params->mi;
+  xd->tx_type_map = mi_params->tx_type_map;
+  xd->tx_type_map_stride = mi_params->mi_stride;
 }
 
 // Apply temporal filtering to key frames and encode the filtered frame.
@@ -917,10 +918,11 @@
   if (apply_filtering) {
     // Initialization for frame motion estimation.
     MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
-    av1_init_context_buffers(cm);
+    av1_init_mi_buffers(&cm->mi_params);
     setup_mi(cpi, frame_input->source);
     av1_init_macroblockd(cm, xd, NULL);
-    const int ext_mi_size = cm->mi_alloc_rows * cm->mi_alloc_cols;
+    const int ext_mi_size =
+        cm->mi_params.mi_alloc_rows * cm->mi_params.mi_alloc_cols;
     memset(cpi->mbmi_ext_frame_base, 0,
            ext_mi_size * sizeof(*cpi->mbmi_ext_frame_base));
 
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 5cf1e41..ee132e6 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -254,8 +254,8 @@
   const int bsize_base = BLOCK_16X16;
   const int num_mi_w = mi_size_wide[bsize_base];
   const int num_mi_h = mi_size_high[bsize_base];
-  const int num_cols = (cm->mi_cols + num_mi_w - 1) / num_mi_w;
-  const int num_rows = (cm->mi_rows + num_mi_h - 1) / num_mi_h;
+  const int num_cols = (cm->mi_params.mi_cols + num_mi_w - 1) / num_mi_w;
+  const int num_rows = (cm->mi_params.mi_rows + num_mi_h - 1) / num_mi_h;
   const int num_bcols = (mi_size_wide[bsize] + num_mi_w - 1) / num_mi_w;
   const int num_brows = (mi_size_high[bsize] + num_mi_h - 1) / num_mi_h;
   int row, col;
@@ -301,8 +301,8 @@
   const int bsize_base = BLOCK_16X16;
   const int num_mi_w = mi_size_wide[bsize_base];
   const int num_mi_h = mi_size_high[bsize_base];
-  const int num_cols = (cm->mi_cols + num_mi_w - 1) / num_mi_w;
-  const int num_rows = (cm->mi_rows + num_mi_h - 1) / num_mi_h;
+  const int num_cols = (cm->mi_params.mi_cols + num_mi_w - 1) / num_mi_w;
+  const int num_rows = (cm->mi_params.mi_rows + num_mi_h - 1) / num_mi_h;
   const int num_bcols = (mi_size_wide[bsize] + num_mi_w - 1) / num_mi_w;
   const int num_brows = (mi_size_high[bsize] + num_mi_h - 1) / num_mi_h;
   int row, col;
@@ -405,15 +405,15 @@
 
   // Set up limit values for MV components.
   // Mv beyond the range do not produce new/different prediction block.
-  av1_set_mv_limits(cm, &x->mv_limits, mi_row, mi_col, mi_height, mi_width,
-                    cpi->oxcf.border_in_pixels);
+  av1_set_mv_limits(&cm->mi_params, &x->mv_limits, mi_row, mi_col, mi_height,
+                    mi_width, cpi->oxcf.border_in_pixels);
 
   set_plane_n4(xd, mi_width, mi_height, num_planes);
 
   // Set up distance of MB to edge of frame in 1/8th pel units.
   assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
-  set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
-                 cm->mi_cols);
+  set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width,
+                 cm->mi_params.mi_rows, cm->mi_params.mi_cols);
 
   // Set up source buffers.
   av1_setup_src_planes(x, cpi->source, mi_row, mi_col, num_planes, bsize);
@@ -441,7 +441,7 @@
       const uint8_t *const map =
           seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
       mbmi->segment_id =
-          map ? get_segment_id(cm, map, bsize, mi_row, mi_col) : 0;
+          map ? get_segment_id(&cm->mi_params, map, bsize, mi_row, mi_col) : 0;
     }
     av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
   }
@@ -513,6 +513,7 @@
                                     RUN_TYPE dry_run) {
   int i, x_idx, y;
   const AV1_COMMON *const cm = &cpi->common;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   const int num_planes = av1_num_planes(cm);
   RD_COUNTS *const rdc = &td->rd_counts;
   MACROBLOCK *const x = &td->mb;
@@ -524,7 +525,7 @@
   const struct segmentation *const seg = &cm->seg;
   const int bw = mi_size_wide[mi->sb_type];
   const int bh = mi_size_high[mi->sb_type];
-  const int mis = cm->mi_stride;
+  const int mis = mi_params->mi_stride;
   const int mi_width = mi_size_wide[bsize];
   const int mi_height = mi_size_high[bsize];
 
@@ -542,9 +543,9 @@
   // If not dry_run, copy the transform type data into the frame level buffer.
   // Encoder will fetch tx types when writing bitstream.
   if (!dry_run) {
-    const int grid_idx = get_mi_grid_idx(cm, mi_row, mi_col);
-    uint8_t *const tx_type_map = cm->tx_type_map + grid_idx;
-    const int mi_stride = cm->mi_stride;
+    const int grid_idx = get_mi_grid_idx(mi_params, mi_row, mi_col);
+    uint8_t *const tx_type_map = mi_params->tx_type_map + grid_idx;
+    const int mi_stride = mi_params->mi_stride;
     for (int blk_row = 0; blk_row < bh; ++blk_row) {
       av1_copy_array(tx_type_map + blk_row * mi_stride,
                      xd->tx_type_map + blk_row * xd->tx_type_map_stride, bw);
@@ -560,7 +561,7 @@
       const uint8_t *const map =
           seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
       mi_addr->segment_id =
-          map ? get_segment_id(cm, map, bsize, mi_row, mi_col) : 0;
+          map ? get_segment_id(mi_params, map, bsize, mi_row, mi_col) : 0;
       reset_tx_size(x, mi_addr, x->tx_mode_search_type);
     }
     // Else for cyclic refresh mode update the segment map, set the segment id
@@ -642,8 +643,8 @@
     rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
   }
 
-  const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
-  const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
+  const int x_mis = AOMMIN(bw, mi_params->mi_cols - mi_col);
+  const int y_mis = AOMMIN(bh, mi_params->mi_rows - mi_row);
   if (cm->seq_params.order_hint_info.enable_ref_frame_mvs)
     av1_copy_frame_mvs(cm, mi, mi_row, mi_col, x_mis, y_mis);
 }
@@ -1687,6 +1688,7 @@
                                  int *rate) {
   assert(bsize < BLOCK_SIZES_ALL);
   const AV1_COMMON *const cm = &cpi->common;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   MACROBLOCK *const x = &td->mb;
   MACROBLOCKD *const xd = &x->e_mbd;
   assert(bsize < BLOCK_SIZES_ALL);
@@ -1701,11 +1703,11 @@
   int i;
   BLOCK_SIZE bsize2 = get_partition_subsize(bsize, PARTITION_SPLIT);
 
-  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
+  if (mi_row >= mi_params->mi_rows || mi_col >= mi_params->mi_cols) return;
 
   if (!dry_run && ctx >= 0) {
-    const int has_rows = (mi_row + hbs) < cm->mi_rows;
-    const int has_cols = (mi_col + hbs) < cm->mi_cols;
+    const int has_rows = (mi_row + hbs) < mi_params->mi_rows;
+    const int has_cols = (mi_col + hbs) < mi_params->mi_cols;
 
     if (has_rows && has_cols) {
 #if CONFIG_ENTROPY_STATS
@@ -1728,7 +1730,7 @@
     case PARTITION_VERT:
       encode_b(cpi, tile_data, td, tp, mi_row, mi_col, dry_run, subsize,
                partition, &pc_tree->vertical[0], rate);
-      if (mi_col + hbs < cm->mi_cols) {
+      if (mi_col + hbs < mi_params->mi_cols) {
         encode_b(cpi, tile_data, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
                  partition, &pc_tree->vertical[1], rate);
       }
@@ -1736,7 +1738,7 @@
     case PARTITION_HORZ:
       encode_b(cpi, tile_data, td, tp, mi_row, mi_col, dry_run, subsize,
                partition, &pc_tree->horizontal[0], rate);
-      if (mi_row + hbs < cm->mi_rows) {
+      if (mi_row + hbs < mi_params->mi_rows) {
         encode_b(cpi, tile_data, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
                  partition, &pc_tree->horizontal[1], rate);
       }
@@ -1788,7 +1790,7 @@
     case PARTITION_HORZ_4:
       for (i = 0; i < 4; ++i) {
         int this_mi_row = mi_row + i * quarter_step;
-        if (i > 0 && this_mi_row >= cm->mi_rows) break;
+        if (i > 0 && this_mi_row >= mi_params->mi_rows) break;
 
         encode_b(cpi, tile_data, td, tp, this_mi_row, mi_col, dry_run, subsize,
                  partition, &pc_tree->horizontal4[i], rate);
@@ -1797,7 +1799,7 @@
     case PARTITION_VERT_4:
       for (i = 0; i < 4; ++i) {
         int this_mi_col = mi_col + i * quarter_step;
-        if (i > 0 && this_mi_col >= cm->mi_cols) break;
+        if (i > 0 && this_mi_col >= mi_params->mi_cols) break;
         encode_b(cpi, tile_data, td, tp, mi_row, this_mi_col, dry_run, subsize,
                  partition, &pc_tree->vertical4[i], rate);
       }
@@ -1817,8 +1819,8 @@
   for (r = 0; r < cm->seq_params.mib_size; r += bh) {
     int bw = bw_in;
     for (c = 0; c < cm->seq_params.mib_size; c += bw) {
-      const int grid_index = get_mi_grid_idx(cm, r, c);
-      const int mi_index = get_alloc_mi_idx(cm, r, c);
+      const int grid_index = get_mi_grid_idx(&cm->mi_params, r, c);
+      const int mi_index = get_alloc_mi_idx(&cm->mi_params, r, c);
       mib[grid_index] = mi + mi_index;
       mib[grid_index]->sb_type = find_partition_size(
           bsize, mi_rows_remaining - r, mi_cols_remaining - c, &bh, &bw);
@@ -1836,26 +1838,27 @@
                                               MB_MODE_INFO **mib, int mi_row,
                                               int mi_col, BLOCK_SIZE bsize) {
   AV1_COMMON *const cm = &cpi->common;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   const int mi_rows_remaining = tile->mi_row_end - mi_row;
   const int mi_cols_remaining = tile->mi_col_end - mi_col;
-  int block_row, block_col;
   MB_MODE_INFO *const mi_upper_left =
-      cm->mi + get_alloc_mi_idx(cm, mi_row, mi_col);
+      mi_params->mi + get_alloc_mi_idx(mi_params, mi_row, mi_col);
   int bh = mi_size_high[bsize];
   int bw = mi_size_wide[bsize];
 
-  assert(bsize >= cm->mi_alloc_bsize &&
-         "Attempted to use bsize < cm->mi_alloc_bsize");
+  assert(bsize >= mi_params->mi_alloc_bsize &&
+         "Attempted to use bsize < mi_params->mi_alloc_bsize");
   assert((mi_rows_remaining > 0) && (mi_cols_remaining > 0));
 
   // Apply the requested partition size to the SB if it is all "in image"
   if ((mi_cols_remaining >= cm->seq_params.mib_size) &&
       (mi_rows_remaining >= cm->seq_params.mib_size)) {
-    for (block_row = 0; block_row < cm->seq_params.mib_size; block_row += bh) {
-      for (block_col = 0; block_col < cm->seq_params.mib_size;
+    for (int block_row = 0; block_row < cm->seq_params.mib_size;
+         block_row += bh) {
+      for (int block_col = 0; block_col < cm->seq_params.mib_size;
            block_col += bw) {
-        const int grid_index = get_mi_grid_idx(cm, block_row, block_col);
-        const int mi_index = get_alloc_mi_idx(cm, block_row, block_col);
+        const int grid_index = get_mi_grid_idx(mi_params, block_row, block_col);
+        const int mi_index = get_alloc_mi_idx(mi_params, block_row, block_col);
         mib[grid_index] = mi_upper_left + mi_index;
         mib[grid_index]->sb_type = bsize;
       }
@@ -1872,6 +1875,7 @@
     TOKENEXTRA **tp, int mi_row, int mi_col, BLOCK_SIZE bsize, int *rate,
     int64_t *dist, int do_recon, PC_TREE *pc_tree) {
   AV1_COMMON *const cm = &cpi->common;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   const int num_planes = av1_num_planes(cm);
   TileInfo *const tile_info = &tile_data->tile_info;
   MACROBLOCK *const x = &td->mb;
@@ -1894,7 +1898,7 @@
   int do_partition_search = 1;
   PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
 
-  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
+  if (mi_row >= mi_params->mi_rows || mi_col >= mi_params->mi_cols) return;
 
   assert(mi_size_wide[bsize] == mi_size_high[bsize]);
 
@@ -1928,7 +1932,7 @@
       splits_below = 1;
       for (i = 0; i < 4; i++) {
         int jj = i >> 1, ii = i & 0x01;
-        MB_MODE_INFO *this_mi = mib[jj * hbs * cm->mi_stride + ii * hbs];
+        MB_MODE_INFO *this_mi = mib[jj * hbs * mi_params->mi_stride + ii * hbs];
         if (this_mi && this_mi->sb_type >= sub_subsize) {
           splits_below = 0;
         }
@@ -1938,7 +1942,8 @@
     // If partition is not none try none unless each of the 4 splits are split
     // even further..
     if (partition != PARTITION_NONE && !splits_below &&
-        mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
+        mi_row + hbs < mi_params->mi_rows &&
+        mi_col + hbs < mi_params->mi_cols) {
       pc_tree->partitioning = PARTITION_NONE;
       pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &none_rdc,
                     PARTITION_NONE, bsize, ctx_none, invalid_rdc, PICK_MODE_RD);
@@ -1964,7 +1969,7 @@
                     PARTITION_HORZ, subsize, &pc_tree->horizontal[0],
                     invalid_rdc, PICK_MODE_RD);
       if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
-          mi_row + hbs < cm->mi_rows) {
+          mi_row + hbs < mi_params->mi_rows) {
         RD_STATS tmp_rdc;
         const PICK_MODE_CONTEXT *const ctx_h = &pc_tree->horizontal[0];
         av1_init_rd_stats(&tmp_rdc);
@@ -1988,7 +1993,7 @@
                     PARTITION_VERT, subsize, &pc_tree->vertical[0], invalid_rdc,
                     PICK_MODE_RD);
       if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
-          mi_col + hbs < cm->mi_cols) {
+          mi_col + hbs < mi_params->mi_cols) {
         RD_STATS tmp_rdc;
         const PICK_MODE_CONTEXT *const ctx_v = &pc_tree->vertical[0];
         av1_init_rd_stats(&tmp_rdc);
@@ -2017,12 +2022,13 @@
         int y_idx = (i >> 1) * hbs;
         int jj = i >> 1, ii = i & 0x01;
         RD_STATS tmp_rdc;
-        if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
+        if ((mi_row + y_idx >= mi_params->mi_rows) ||
+            (mi_col + x_idx >= mi_params->mi_cols))
           continue;
 
         av1_init_rd_stats(&tmp_rdc);
         rd_use_partition(cpi, td, tile_data,
-                         mib + jj * hbs * cm->mi_stride + ii * hbs, tp,
+                         mib + jj * hbs * mi_params->mi_stride + ii * hbs, tp,
                          mi_row + y_idx, mi_col + x_idx, subsize, &tmp_rdc.rate,
                          &tmp_rdc.dist, i != 3, pc_tree->split[i]);
         if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
@@ -2053,8 +2059,10 @@
       cpi->sf.part_sf.adjust_partitioning_from_last_frame &&
       cpi->sf.part_sf.partition_search_type == SEARCH_PARTITION &&
       partition != PARTITION_SPLIT && bsize > BLOCK_8X8 &&
-      (mi_row + bs < cm->mi_rows || mi_row + hbs == cm->mi_rows) &&
-      (mi_col + bs < cm->mi_cols || mi_col + hbs == cm->mi_cols)) {
+      (mi_row + bs < mi_params->mi_rows ||
+       mi_row + hbs == mi_params->mi_rows) &&
+      (mi_col + bs < mi_params->mi_cols ||
+       mi_col + hbs == mi_params->mi_cols)) {
     BLOCK_SIZE split_subsize = get_partition_subsize(bsize, PARTITION_SPLIT);
     chosen_rdc.rate = 0;
     chosen_rdc.dist = 0;
@@ -2068,7 +2076,8 @@
       int y_idx = (i >> 1) * hbs;
       RD_STATS tmp_rdc;
 
-      if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
+      if ((mi_row + y_idx >= mi_params->mi_rows) ||
+          (mi_col + x_idx >= mi_params->mi_cols))
         continue;
 
       save_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes);
@@ -2147,7 +2156,8 @@
   for (int i = 0; i < 4; i++) {
     int x_idx = (i & 1) * hbs;
     int y_idx = (i >> 1) * hbs;
-    if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
+    if ((mi_row + y_idx >= cm->mi_params.mi_rows) ||
+        (mi_col + x_idx >= cm->mi_params.mi_cols))
       return 0;
     if (get_partition(cm, mi_row + y_idx, mi_col + x_idx, subsize) !=
             PARTITION_NONE &&
@@ -2167,6 +2177,7 @@
                                            int mi_row, int mi_col,
                                            BLOCK_SIZE bsize, PC_TREE *pc_tree) {
   AV1_COMMON *const cm = &cpi->common;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   TileInfo *const tile_info = &tile_data->tile_info;
   MACROBLOCK *const x = &td->mb;
   MACROBLOCKD *const xd = &x->e_mbd;
@@ -2188,7 +2199,7 @@
   RD_STATS invalid_rd;
   av1_invalid_rd_stats(&invalid_rd);
 
-  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
+  if (mi_row >= mi_params->mi_rows || mi_col >= mi_params->mi_cols) return;
 
   assert(mi_size_wide[bsize] == mi_size_high[bsize]);
 
@@ -2221,7 +2232,8 @@
           av1_invalid_rd_stats(&block_rdc);
           const int x_idx = (i & 1) * hbs;
           const int y_idx = (i >> 1) * hbs;
-          if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
+          if (mi_row + y_idx >= mi_params->mi_rows ||
+              mi_col + x_idx >= mi_params->mi_cols)
             continue;
           xd->above_txfm_context =
               cm->above_txfm_context[tile_info->tile_row] + mi_col + x_idx;
@@ -2252,7 +2264,8 @@
           for (int i = 0; i < 4; i++) {
             const int x_idx = (i & 1) * hbs;
             const int y_idx = (i >> 1) * hbs;
-            if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
+            if (mi_row + y_idx >= mi_params->mi_rows ||
+                mi_col + x_idx >= mi_params->mi_cols)
               continue;
 
             encode_b(cpi, tile_data, td, tp, mi_row + y_idx, mi_col + x_idx, 0,
@@ -2274,7 +2287,7 @@
                     PICK_MODE_NONRD);
       encode_b(cpi, tile_data, td, tp, mi_row, mi_col, 0, subsize,
                PARTITION_VERT, &pc_tree->vertical[0], NULL);
-      if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
+      if (mi_col + hbs < mi_params->mi_cols && bsize > BLOCK_8X8) {
         pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + hbs, &dummy_cost,
                       PARTITION_VERT, subsize, &pc_tree->vertical[1],
                       invalid_rd, PICK_MODE_NONRD);
@@ -2289,7 +2302,7 @@
       encode_b(cpi, tile_data, td, tp, mi_row, mi_col, 0, subsize,
                PARTITION_HORZ, &pc_tree->horizontal[0], NULL);
 
-      if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
+      if (mi_row + hbs < mi_params->mi_rows && bsize > BLOCK_8X8) {
         pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col, &dummy_cost,
                       PARTITION_HORZ, subsize, &pc_tree->horizontal[1],
                       invalid_rd, PICK_MODE_NONRD);
@@ -2325,8 +2338,8 @@
             av1_invalid_rd_stats(&block_rdc);
             int x_idx = (i & 1) * hbs;
             int y_idx = (i >> 1) * hbs;
-            if ((mi_row + y_idx >= cm->mi_rows) ||
-                (mi_col + x_idx >= cm->mi_cols))
+            if ((mi_row + y_idx >= mi_params->mi_rows) ||
+                (mi_col + x_idx >= mi_params->mi_cols))
               continue;
             xd->above_txfm_context =
                 cm->above_txfm_context[tile_info->tile_row] + mi_col + x_idx;
@@ -2358,8 +2371,8 @@
           for (int i = 0; i < 4; i++) {
             int x_idx = (i & 1) * hbs;
             int y_idx = (i >> 1) * hbs;
-            if ((mi_row + y_idx >= cm->mi_rows) ||
-                (mi_col + x_idx >= cm->mi_cols))
+            if ((mi_row + y_idx >= mi_params->mi_rows) ||
+                (mi_col + x_idx >= mi_params->mi_cols))
               continue;
 
             encode_b(cpi, tile_data, td, tp, mi_row + y_idx, mi_col + x_idx, 0,
@@ -2371,12 +2384,13 @@
           int x_idx = (i & 1) * hbs;
           int y_idx = (i >> 1) * hbs;
           int jj = i >> 1, ii = i & 0x01;
-          if ((mi_row + y_idx >= cm->mi_rows) ||
-              (mi_col + x_idx >= cm->mi_cols))
+          if ((mi_row + y_idx >= mi_params->mi_rows) ||
+              (mi_col + x_idx >= mi_params->mi_cols))
             continue;
-          nonrd_use_partition(
-              cpi, td, tile_data, mib + jj * hbs * cm->mi_stride + ii * hbs, tp,
-              mi_row + y_idx, mi_col + x_idx, subsize, pc_tree->split[i]);
+          nonrd_use_partition(cpi, td, tile_data,
+                              mib + jj * hbs * mi_params->mi_stride + ii * hbs,
+                              tp, mi_row + y_idx, mi_col + x_idx, subsize,
+                              pc_tree->split[i]);
         }
       }
       break;
@@ -2406,7 +2420,7 @@
 // bars embedded in the stream.
 static int active_h_edge(const AV1_COMP *cpi, int mi_row, int mi_step) {
   int top_edge = 0;
-  int bottom_edge = cpi->common.mi_rows;
+  int bottom_edge = cpi->common.mi_params.mi_rows;
   int is_active_h_edge = 0;
 
   // For two pass account for any formatting bars detected.
@@ -2436,7 +2450,7 @@
 // bars embedded in the stream.
 static int active_v_edge(const AV1_COMP *cpi, int mi_col, int mi_step) {
   int left_edge = 0;
-  int right_edge = cpi->common.mi_cols;
+  int right_edge = cpi->common.mi_params.mi_cols;
   int is_active_v_edge = 0;
 
   // For two pass account for any formatting bars detected.
@@ -2652,6 +2666,7 @@
                               SB_MULTI_PASS_MODE multi_pass_mode,
                               RD_RECT_PART_WIN_INFO *rect_part_win_info) {
   const AV1_COMMON *const cm = &cpi->common;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   const int num_planes = av1_num_planes(cm);
   TileInfo *const tile_info = &tile_data->tile_info;
   MACROBLOCK *const x = &td->mb;
@@ -2702,8 +2717,8 @@
   if (bsize == cm->seq_params.sb_size) x->must_find_valid_partition = 0;
 
   // Override skipping rectangular partition operations for edge blocks
-  const int has_rows = (mi_row + mi_step < cm->mi_rows);
-  const int has_cols = (mi_col + mi_step < cm->mi_cols);
+  const int has_rows = (mi_row + mi_step < mi_params->mi_rows);
+  const int has_cols = (mi_col + mi_step < mi_params->mi_cols);
   const int xss = x->e_mbd.plane[1].subsampling_x;
   const int yss = x->e_mbd.plane[1].subsampling_y;
 
@@ -2796,8 +2811,9 @@
       !cpi->is_screen_content_type && frame_is_intra_only(cm) &&
       cpi->sf.part_sf.intra_cnn_split &&
       cm->seq_params.sb_size >= BLOCK_64X64 && bsize <= BLOCK_64X64 &&
-      bsize >= BLOCK_8X8 && mi_row + mi_size_high[bsize] <= cm->mi_rows &&
-      mi_col + mi_size_wide[bsize] <= cm->mi_cols;
+      bsize >= BLOCK_8X8 &&
+      mi_row + mi_size_high[bsize] <= mi_params->mi_rows &&
+      mi_col + mi_size_wide[bsize] <= mi_params->mi_cols;
 
   if (try_intra_cnn_split) {
     av1_intra_mode_cnn_partition(
@@ -2811,9 +2827,10 @@
   const int try_split_only =
       !cpi->is_screen_content_type &&
       cpi->sf.part_sf.simple_motion_search_split && do_square_split &&
-      bsize >= BLOCK_8X8 && mi_row + mi_size_high[bsize] <= cm->mi_rows &&
-      mi_col + mi_size_wide[bsize] <= cm->mi_cols && !frame_is_intra_only(cm) &&
-      !av1_superres_scaled(cm);
+      bsize >= BLOCK_8X8 &&
+      mi_row + mi_size_high[bsize] <= mi_params->mi_rows &&
+      mi_col + mi_size_wide[bsize] <= mi_params->mi_cols &&
+      !frame_is_intra_only(cm) && !av1_superres_scaled(cm);
 
   if (try_split_only) {
     av1_simple_motion_search_based_split(
@@ -2989,10 +3006,11 @@
 
         if (cpi->sf.part_sf.simple_motion_search_early_term_none &&
             cm->show_frame && !frame_is_intra_only(cm) &&
-            bsize >= BLOCK_16X16 && mi_row + mi_step < cm->mi_rows &&
-            mi_col + mi_step < cm->mi_cols && this_rdc.rdcost < INT64_MAX &&
-            this_rdc.rdcost >= 0 && this_rdc.rate < INT_MAX &&
-            this_rdc.rate >= 0 && (do_square_split || do_rectangular_split)) {
+            bsize >= BLOCK_16X16 && mi_row + mi_step < mi_params->mi_rows &&
+            mi_col + mi_step < mi_params->mi_cols &&
+            this_rdc.rdcost < INT64_MAX && this_rdc.rdcost >= 0 &&
+            this_rdc.rate < INT_MAX && this_rdc.rate >= 0 &&
+            (do_square_split || do_rectangular_split)) {
           av1_simple_motion_search_early_term_none(cpi, x, pc_tree, mi_row,
                                                    mi_col, bsize, &this_rdc,
                                                    &terminate_partition_search);
@@ -3026,7 +3044,8 @@
       const int x_idx = (idx & 1) * mi_step;
       const int y_idx = (idx >> 1) * mi_step;
 
-      if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
+      if (mi_row + y_idx >= mi_params->mi_rows ||
+          mi_col + x_idx >= mi_params->mi_cols)
         continue;
 
       if (cpi->sf.mv_sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
@@ -3689,7 +3708,7 @@
     for (int i = 0; i < 4; ++i) {
       const int this_mi_row = mi_row + i * quarter_step;
 
-      if (i > 0 && this_mi_row >= cm->mi_rows) break;
+      if (i > 0 && this_mi_row >= mi_params->mi_rows) break;
 
       PICK_MODE_CONTEXT *ctx_this = &pc_tree->horizontal4[i];
 
@@ -3745,7 +3764,7 @@
     for (int i = 0; i < 4; ++i) {
       const int this_mi_col = mi_col + i * quarter_step;
 
-      if (i > 0 && this_mi_col >= cm->mi_cols) break;
+      if (i > 0 && this_mi_col >= mi_params->mi_cols) break;
 
       PICK_MODE_CONTEXT *ctx_this = &pc_tree->vertical4[i];
 
@@ -3888,7 +3907,7 @@
   const int step = 1 << cpi->tpl_stats_block_mis_log2;
   for (int row = mi_row; row < mi_row + mi_high; row += step) {
     for (int col = mi_col_sr; col < mi_col_end_sr; col += step) {
-      if (row >= cm->mi_rows || col >= mi_cols_sr) continue;
+      if (row >= cm->mi_params.mi_rows || col >= mi_cols_sr) continue;
       TplDepStats *this_stats =
           &tpl_stats[av1_tpl_ptr_pos(cpi, row, col, tpl_stride)];
       int64_t mc_dep_delta =
@@ -3978,7 +3997,7 @@
 
   for (int row = mi_row; row < mi_row + mi_high; row += step) {
     for (int col = mi_col_sr; col < mi_col_end_sr; col += step) {
-      if (row >= cm->mi_rows || col >= mi_cols_sr) continue;
+      if (row >= cm->mi_params.mi_rows || col >= mi_cols_sr) continue;
       TplDepStats *this_stats =
           &tpl_stats[av1_tpl_ptr_pos(cpi, row, col, tpl_stride)];
       inter_cost_b[mi_count] = this_stats->inter_cost;
@@ -4026,7 +4045,7 @@
   const int step = 1 << cpi->tpl_stats_block_mis_log2;
   for (int row = mi_row; row < mi_row + mi_high; row += step) {
     for (int col = mi_col_sr; col < mi_col_end_sr; col += step) {
-      if (row >= cm->mi_rows || col >= mi_cols_sr) continue;
+      if (row >= cm->mi_params.mi_rows || col >= mi_cols_sr) continue;
       TplDepStats *this_stats =
           &tpl_stats[av1_tpl_ptr_pos(cpi, row, col, tpl_stride)];
       int64_t mc_dep_delta =
@@ -4070,6 +4089,7 @@
                                      const TileInfo *const tile_info,
                                      int mi_row, int mi_col, int num_planes) {
   AV1_COMMON *const cm = &cpi->common;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   const DeltaQInfo *const delta_q_info = &cm->delta_q_info;
   assert(delta_q_info->delta_q_present_flag);
 
@@ -4139,12 +4159,12 @@
 
     // pre-set the delta lf for loop filter. Note that this value is set
     // before mi is assigned for each block in current superblock
-    for (int j = 0; j < AOMMIN(mib_size, cm->mi_rows - mi_row); j++) {
-      for (int k = 0; k < AOMMIN(mib_size, cm->mi_cols - mi_col); k++) {
-        const int mi_idx = get_alloc_mi_idx(cm, mi_row + j, mi_col + k);
-        cm->mi[mi_idx].delta_lf_from_base = delta_lf;
+    for (int j = 0; j < AOMMIN(mib_size, mi_params->mi_rows - mi_row); j++) {
+      for (int k = 0; k < AOMMIN(mib_size, mi_params->mi_cols - mi_col); k++) {
+        const int mi_idx = get_alloc_mi_idx(mi_params, mi_row + j, mi_col + k);
+        mi_params->mi[mi_idx].delta_lf_from_base = delta_lf;
         for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id) {
-          cm->mi[mi_idx].delta_lf[lf_id] = delta_lf;
+          mi_params->mi[mi_idx].delta_lf[lf_id] = delta_lf;
         }
       }
     }
@@ -4387,7 +4407,8 @@
   MACROBLOCK *const x = &td->mb;
   const SPEED_FEATURES *const sf = &cpi->sf;
   const TileInfo *const tile_info = &tile_data->tile_info;
-  MB_MODE_INFO **mi = cm->mi_grid_base + get_mi_grid_idx(cm, mi_row, mi_col);
+  MB_MODE_INFO **mi = cm->mi_params.mi_grid_base +
+                      get_mi_grid_idx(&cm->mi_params, mi_row, mi_col);
   const BLOCK_SIZE sb_size = cm->seq_params.sb_size;
   if (sf->rt_sf.source_metrics_sb_nonrd && sb_size == BLOCK_64X64 &&
       cm->current_frame.frame_type != KEY_FRAME) {
@@ -4417,29 +4438,33 @@
 }
 
 // Memset the mbmis at the current superblock to 0
-static INLINE void reset_mbmi(AV1_COMMON *cm, int mi_row, int mi_col) {
-  const BLOCK_SIZE sb_size = cm->seq_params.sb_size;
+static INLINE void reset_mbmi(CommonModeInfoParams *const mi_params,
+                              BLOCK_SIZE sb_size, int mi_row, int mi_col) {
   // size of sb in unit of mi_grid (BLOCK_4X4)
   const int sb_size_mi = mi_size_wide[sb_size];
-  const int mi_alloc_size_1d = mi_size_wide[cm->mi_alloc_bsize];
+  const int mi_alloc_size_1d = mi_size_wide[mi_params->mi_alloc_bsize];
   // size of sb in unit of allocated mi size
   const int sb_size_alloc_mi = mi_size_wide[sb_size] / mi_alloc_size_1d;
-  assert(cm->mi_alloc_stride % sb_size_alloc_mi == 0 &&
+  assert(mi_params->mi_alloc_stride % sb_size_alloc_mi == 0 &&
          "mi is not allocated as a multiple of sb!");
-  assert(cm->mi_stride % sb_size_mi == 0 &&
+  assert(mi_params->mi_stride % sb_size_mi == 0 &&
          "mi_grid is not allocated as a multiple of sb!");
 
   const int mi_rows = mi_size_high[sb_size];
   for (int cur_mi_row = 0; cur_mi_row < mi_rows; cur_mi_row++) {
-    assert(get_mi_grid_idx(cm, 0, mi_col + mi_alloc_size_1d) < cm->mi_stride);
-    const int mi_grid_idx = get_mi_grid_idx(cm, mi_row + cur_mi_row, mi_col);
-    const int alloc_mi_idx = get_alloc_mi_idx(cm, mi_row + cur_mi_row, mi_col);
-    memset(&cm->mi_grid_base[mi_grid_idx], 0,
-           sb_size_mi * sizeof(*cm->mi_grid_base));
-    memset(&cm->tx_type_map[mi_grid_idx], 0,
-           sb_size_mi * sizeof(*cm->tx_type_map));
+    assert(get_mi_grid_idx(mi_params, 0, mi_col + mi_alloc_size_1d) <
+           mi_params->mi_stride);
+    const int mi_grid_idx =
+        get_mi_grid_idx(mi_params, mi_row + cur_mi_row, mi_col);
+    const int alloc_mi_idx =
+        get_alloc_mi_idx(mi_params, mi_row + cur_mi_row, mi_col);
+    memset(&mi_params->mi_grid_base[mi_grid_idx], 0,
+           sb_size_mi * sizeof(*mi_params->mi_grid_base));
+    memset(&mi_params->tx_type_map[mi_grid_idx], 0,
+           sb_size_mi * sizeof(*mi_params->tx_type_map));
     if (cur_mi_row % mi_alloc_size_1d == 0) {
-      memset(&cm->mi[alloc_mi_idx], 0, sb_size_alloc_mi * sizeof(*cm->mi));
+      memset(&mi_params->mi[alloc_mi_idx], 0,
+             sb_size_alloc_mi * sizeof(*mi_params->mi));
     }
   }
 }
@@ -4472,8 +4497,8 @@
   memcpy(sb_fp_stats->thresh_freq_fact, x->thresh_freq_fact,
          sizeof(sb_fp_stats->thresh_freq_fact));
 
-  const int alloc_mi_idx = get_alloc_mi_idx(cm, mi_row, mi_col);
-  sb_fp_stats->current_qindex = cm->mi[alloc_mi_idx].current_qindex;
+  const int alloc_mi_idx = get_alloc_mi_idx(&cm->mi_params, mi_row, mi_col);
+  sb_fp_stats->current_qindex = cm->mi_params.mi[alloc_mi_idx].current_qindex;
 
 #if CONFIG_INTERNAL_STATS
   memcpy(sb_fp_stats->mode_chosen_counts, cpi->mode_chosen_counts,
@@ -4503,8 +4528,8 @@
   memcpy(x->thresh_freq_fact, sb_fp_stats->thresh_freq_fact,
          sizeof(sb_fp_stats->thresh_freq_fact));
 
-  const int alloc_mi_idx = get_alloc_mi_idx(cm, mi_row, mi_col);
-  cm->mi[alloc_mi_idx].current_qindex = sb_fp_stats->current_qindex;
+  const int alloc_mi_idx = get_alloc_mi_idx(&cm->mi_params, mi_row, mi_col);
+  cm->mi_params.mi[alloc_mi_idx].current_qindex = sb_fp_stats->current_qindex;
 
 #if CONFIG_INTERNAL_STATS
   memcpy(cpi->mode_chosen_counts, sb_fp_stats->mode_chosen_counts,
@@ -4516,6 +4541,7 @@
 static void init_ref_frame_space(AV1_COMP *cpi, ThreadData *td, int mi_row,
                                  int mi_col) {
   const AV1_COMMON *cm = &cpi->common;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   MACROBLOCK *x = &td->mb;
   const int frame_idx = cpi->gf_group.index;
   TplDepFrame *tpl_frame = &cpi->tpl_frame[frame_idx];
@@ -4539,8 +4565,10 @@
   int64_t inter_cost[INTER_REFS_PER_FRAME] = { 0 };
   const int step = 1 << cpi->tpl_stats_block_mis_log2;
   const BLOCK_SIZE sb_size = cm->seq_params.sb_size;
-  const int mi_row_end = AOMMIN(mi_size_high[sb_size] + mi_row, cm->mi_rows);
-  const int mi_col_end = AOMMIN(mi_size_wide[sb_size] + mi_col, cm->mi_cols);
+  const int mi_row_end =
+      AOMMIN(mi_size_high[sb_size] + mi_row, mi_params->mi_rows);
+  const int mi_col_end =
+      AOMMIN(mi_size_wide[sb_size] + mi_col, mi_params->mi_cols);
 
   for (int row = mi_row; row < mi_row_end; row += step) {
     for (int col = mi_col; col < mi_col_end; col += step) {
@@ -4661,7 +4689,8 @@
   MACROBLOCK *const x = &td->mb;
   const SPEED_FEATURES *const sf = &cpi->sf;
   const TileInfo *const tile_info = &tile_data->tile_info;
-  MB_MODE_INFO **mi = cm->mi_grid_base + get_mi_grid_idx(cm, mi_row, mi_col);
+  MB_MODE_INFO **mi = cm->mi_params.mi_grid_base +
+                      get_mi_grid_idx(&cm->mi_params, mi_row, mi_col);
   const BLOCK_SIZE sb_size = cm->seq_params.sb_size;
   int dummy_rate;
   int64_t dummy_dist;
@@ -4734,7 +4763,7 @@
       // Second pass
       init_encode_rd_sb(cpi, td, tile_data, pc_root, &dummy_rdc, mi_row, mi_col,
                         0);
-      reset_mbmi(&cpi->common, mi_row, mi_col);
+      reset_mbmi(&cm->mi_params, sb_size, mi_row, mi_col);
       reset_partition(pc_root, sb_size);
 
       restore_sb_state(&sb_fp_stats, cpi, td, tile_data, mi_row, mi_col);
@@ -4885,7 +4914,8 @@
       const uint8_t *const map =
           seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
       const int segment_id =
-          map ? get_segment_id(cm, map, sb_size, mi_row, mi_col) : 0;
+          map ? get_segment_id(&cm->mi_params, map, sb_size, mi_row, mi_col)
+              : 0;
       seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
     }
 
@@ -5549,23 +5579,26 @@
   }
 }
 
+#define CHECK_PRECOMPUTED_REF_FRAME_MAP 0
+
 static AOM_INLINE void encode_frame_internal(AV1_COMP *cpi) {
   ThreadData *const td = &cpi->td;
   MACROBLOCK *const x = &td->mb;
   AV1_COMMON *const cm = &cpi->common;
+  CommonModeInfoParams *const mi_params = &cm->mi_params;
   FeatureFlags *const features = &cm->features;
   MACROBLOCKD *const xd = &x->e_mbd;
   RD_COUNTS *const rdc = &cpi->td.rd_counts;
   int i;
 
   if (!cpi->sf.rt_sf.use_nonrd_pick_mode) {
-    cm->setup_mi(cm);
+    mi_params->setup_mi(mi_params);
   }
 
-  xd->mi = cm->mi_grid_base;
-  xd->mi[0] = cm->mi;
-  xd->tx_type_map = cm->tx_type_map;
-  xd->tx_type_map_stride = cm->mi_stride;
+  xd->mi = mi_params->mi_grid_base;
+  xd->mi[0] = mi_params->mi;
+  xd->tx_type_map = mi_params->tx_type_map;
+  xd->tx_type_map_stride = mi_params->mi_stride;
 
 #if CONFIG_AV1_HIGHBITDEPTH
   x->fwd_txfm4x4 = aom_fdct4x4;
@@ -5622,7 +5655,7 @@
                                       is_block_same[0], &cpi->td.mb);
     // Hash data generated for screen contents is used for intraBC ME
     // TODO(any): Adjust max_size based on superblock size for intra frames
-    const int min_alloc_size = block_size_wide[cm->mi_alloc_bsize];
+    const int min_alloc_size = block_size_wide[mi_params->mi_alloc_bsize];
     int src_idx = 0;
     for (int size = 4; size <= 128; size *= 2, src_idx = !src_idx) {
       const int dst_idx = !src_idx;
@@ -5940,8 +5973,6 @@
   }
 }
 
-#define CHECK_PRECOMPUTED_REF_FRAME_MAP 0
-
 void av1_encode_frame(AV1_COMP *cpi) {
   AV1_COMMON *const cm = &cpi->common;
   CurrentFrame *const current_frame = &cm->current_frame;
@@ -5952,8 +5983,8 @@
 
   // Make sure segment_id is no larger than last_active_segid.
   if (cm->seg.enabled && cm->seg.update_map) {
-    const int mi_rows = cm->mi_rows;
-    const int mi_cols = cm->mi_cols;
+    const int mi_rows = cm->mi_params.mi_rows;
+    const int mi_cols = cm->mi_params.mi_cols;
     const int last_active_segid = cm->seg.last_active_segid;
     uint8_t *map = cpi->segmentation_map;
     for (int mi_row = 0; mi_row < mi_rows; ++mi_row) {
@@ -6221,7 +6252,7 @@
   MB_MODE_INFO *mbmi = mi_4x4[0];
   const int seg_skip =
       segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP);
-  const int mis = cm->mi_stride;
+  const int mis = cm->mi_params.mi_stride;
   const int mi_width = mi_size_wide[bsize];
   const int mi_height = mi_size_high[bsize];
   const int is_inter = is_inter_block(mbmi);
@@ -6352,7 +6383,8 @@
 
       for (j = 0; j < mi_height; j++)
         for (i = 0; i < mi_width; i++)
-          if (mi_col + i < cm->mi_cols && mi_row + j < cm->mi_rows)
+          if (mi_col + i < cm->mi_params.mi_cols &&
+              mi_row + j < cm->mi_params.mi_rows)
             mi_4x4[mis * j + i]->tx_size = intra_tx_size;
 
       if (intra_tx_size != max_txsize_rect_lookup[bsize]) ++x->txb_split_count;
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 5dc3427..2aa9a3e 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -402,7 +402,8 @@
   unsigned char *const seg_map = cpi->segmentation_map;
   int i;
   if (cpi->active_map.enabled || cpi->active_map.update)
-    for (i = 0; i < cpi->common.mi_rows * cpi->common.mi_cols; ++i)
+    for (i = 0;
+         i < cpi->common.mi_params.mi_rows * cpi->common.mi_params.mi_cols; ++i)
       if (seg_map[i] == AM_SEGMENT_ID_INACTIVE)
         seg_map[i] = AM_SEGMENT_ID_ACTIVE;
 }
@@ -422,7 +423,9 @@
 
   if (cpi->active_map.update) {
     if (cpi->active_map.enabled) {
-      for (i = 0; i < cpi->common.mi_rows * cpi->common.mi_cols; ++i)
+      for (i = 0;
+           i < cpi->common.mi_params.mi_rows * cpi->common.mi_params.mi_cols;
+           ++i)
         if (seg_map[i] == AM_SEGMENT_ID_ACTIVE) seg_map[i] = active_map[i];
       av1_enable_segmentation(seg);
       av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
@@ -456,10 +459,11 @@
 
 int av1_set_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
                        int cols) {
-  if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols) {
+  const CommonModeInfoParams *const mi_params = &cpi->common.mi_params;
+  if (rows == mi_params->mb_rows && cols == mi_params->mb_cols) {
     unsigned char *const active_map_8x8 = cpi->active_map.map;
-    const int mi_rows = cpi->common.mi_rows;
-    const int mi_cols = cpi->common.mi_cols;
+    const int mi_rows = mi_params->mi_rows;
+    const int mi_cols = mi_params->mi_cols;
     const int row_scale = mi_size_high[BLOCK_16X16] == 2 ? 1 : 2;
     const int col_scale = mi_size_wide[BLOCK_16X16] == 2 ? 1 : 2;
     cpi->active_map.update = 1;
@@ -485,11 +489,12 @@
 
 int av1_get_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
                        int cols) {
-  if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols &&
+  const CommonModeInfoParams *const mi_params = &cpi->common.mi_params;
+  if (rows == mi_params->mb_rows && cols == mi_params->mb_cols &&
       new_map_16x16) {
     unsigned char *const seg_map_8x8 = cpi->segmentation_map;
-    const int mi_rows = cpi->common.mi_rows;
-    const int mi_cols = cpi->common.mi_cols;
+    const int mi_rows = mi_params->mi_rows;
+    const int mi_cols = mi_params->mi_cols;
     const int row_scale = mi_size_high[BLOCK_16X16] == 2 ? 1 : 2;
     const int col_scale = mi_size_wide[BLOCK_16X16] == 2 ? 1 : 2;
 
@@ -629,7 +634,8 @@
   cpi->vaq_refresh = 0;
 }
 
-static void enc_set_mb_mi(AV1_COMMON *cm, int width, int height) {
+static void enc_set_mb_mi(CommonModeInfoParams *mi_params, int width,
+                          int height) {
   // Ensure that the decoded width and height are both multiples of
   // 8 luma pixels (note: this may only be a multiple of 4 chroma pixels if
   // subsampling is used).
@@ -638,71 +644,80 @@
   const int aligned_width = ALIGN_POWER_OF_TWO(width, 3);
   const int aligned_height = ALIGN_POWER_OF_TWO(height, 3);
 
-  cm->mi_cols = aligned_width >> MI_SIZE_LOG2;
-  cm->mi_rows = aligned_height >> MI_SIZE_LOG2;
-  cm->mi_stride = calc_mi_size(cm->mi_cols);
+  mi_params->mi_cols = aligned_width >> MI_SIZE_LOG2;
+  mi_params->mi_rows = aligned_height >> MI_SIZE_LOG2;
+  mi_params->mi_stride = calc_mi_size(mi_params->mi_cols);
 
-  cm->mb_cols = (cm->mi_cols + 2) >> 2;
-  cm->mb_rows = (cm->mi_rows + 2) >> 2;
-  cm->MBs = cm->mb_rows * cm->mb_cols;
+  mi_params->mb_cols = (mi_params->mi_cols + 2) >> 2;
+  mi_params->mb_rows = (mi_params->mi_rows + 2) >> 2;
+  mi_params->MBs = mi_params->mb_rows * mi_params->mb_cols;
 
   const int is_4k_or_larger = AOMMIN(width, height) >= 2160;
 
-  cm->mi_alloc_bsize = is_4k_or_larger ? BLOCK_8X8 : BLOCK_4X4;
-  const int mi_alloc_size_1d = mi_size_wide[cm->mi_alloc_bsize];
-  cm->mi_alloc_rows = (cm->mi_rows + mi_alloc_size_1d - 1) / mi_alloc_size_1d;
-  cm->mi_alloc_cols = (cm->mi_cols + mi_alloc_size_1d - 1) / mi_alloc_size_1d;
-  cm->mi_alloc_stride =
-      (cm->mi_stride + mi_alloc_size_1d - 1) / mi_alloc_size_1d;
+  mi_params->mi_alloc_bsize = is_4k_or_larger ? BLOCK_8X8 : BLOCK_4X4;
+  const int mi_alloc_size_1d = mi_size_wide[mi_params->mi_alloc_bsize];
+  mi_params->mi_alloc_rows =
+      (mi_params->mi_rows + mi_alloc_size_1d - 1) / mi_alloc_size_1d;
+  mi_params->mi_alloc_cols =
+      (mi_params->mi_cols + mi_alloc_size_1d - 1) / mi_alloc_size_1d;
+  mi_params->mi_alloc_stride =
+      (mi_params->mi_stride + mi_alloc_size_1d - 1) / mi_alloc_size_1d;
 
-  assert(mi_size_wide[cm->mi_alloc_bsize] == mi_size_high[cm->mi_alloc_bsize]);
+  assert(mi_size_wide[mi_params->mi_alloc_bsize] ==
+         mi_size_high[mi_params->mi_alloc_bsize]);
 
 #if CONFIG_LPF_MASK
-  av1_alloc_loop_filter_mask(cm);
+  av1_alloc_loop_filter_mask(mi_params);
 #endif
 }
 
-static void enc_setup_mi(AV1_COMMON *cm) {
-  const int mi_grid_size = cm->mi_stride * calc_mi_size(cm->mi_rows);
-  memset(cm->mi, 0, cm->mi_alloc_size * sizeof(*cm->mi));
-  memset(cm->mi_grid_base, 0, mi_grid_size * sizeof(*cm->mi_grid_base));
-  memset(cm->tx_type_map, 0, mi_grid_size * sizeof(*cm->tx_type_map));
+static void enc_setup_mi(CommonModeInfoParams *mi_params) {
+  const int mi_grid_size =
+      mi_params->mi_stride * calc_mi_size(mi_params->mi_rows);
+  memset(mi_params->mi, 0, mi_params->mi_alloc_size * sizeof(*mi_params->mi));
+  memset(mi_params->mi_grid_base, 0,
+         mi_grid_size * sizeof(*mi_params->mi_grid_base));
+  memset(mi_params->tx_type_map, 0,
+         mi_grid_size * sizeof(*mi_params->tx_type_map));
 }
 
-static int enc_alloc_mi(AV1_COMMON *cm) {
-  const int mi_grid_size = cm->mi_stride * calc_mi_size(cm->mi_rows);
-  const int alloc_size_1d = mi_size_wide[cm->mi_alloc_bsize];
-  const int alloc_mi_size =
-      cm->mi_alloc_stride * (calc_mi_size(cm->mi_rows) / alloc_size_1d);
+static int enc_alloc_mi(CommonModeInfoParams *mi_params) {
+  const int mi_grid_size =
+      mi_params->mi_stride * calc_mi_size(mi_params->mi_rows);
+  const int alloc_size_1d = mi_size_wide[mi_params->mi_alloc_bsize];
+  const int alloc_mi_size = mi_params->mi_alloc_stride *
+                            (calc_mi_size(mi_params->mi_rows) / alloc_size_1d);
 
-  if (cm->mi_alloc_size < alloc_mi_size || cm->mi_grid_size < mi_grid_size) {
-    cm->free_mi(cm);
+  if (mi_params->mi_alloc_size < alloc_mi_size ||
+      mi_params->mi_grid_size < mi_grid_size) {
+    mi_params->free_mi(mi_params);
 
-    cm->mi = aom_calloc(alloc_mi_size, sizeof(*cm->mi));
-    if (!cm->mi) return 1;
-    cm->mi_alloc_size = alloc_mi_size;
+    mi_params->mi = aom_calloc(alloc_mi_size, sizeof(*mi_params->mi));
+    if (!mi_params->mi) return 1;
+    mi_params->mi_alloc_size = alloc_mi_size;
 
-    cm->mi_grid_base =
+    mi_params->mi_grid_base =
         (MB_MODE_INFO **)aom_calloc(mi_grid_size, sizeof(MB_MODE_INFO *));
-    if (!cm->mi_grid_base) return 1;
-    cm->mi_grid_size = mi_grid_size;
+    if (!mi_params->mi_grid_base) return 1;
+    mi_params->mi_grid_size = mi_grid_size;
 
-    cm->tx_type_map = aom_calloc(calc_mi_size(cm->mi_rows) * cm->mi_stride,
-                                 sizeof(*cm->tx_type_map));
-    if (!cm->tx_type_map) return 1;
+    mi_params->tx_type_map =
+        aom_calloc(calc_mi_size(mi_params->mi_rows) * mi_params->mi_stride,
+                   sizeof(*mi_params->tx_type_map));
+    if (!mi_params->tx_type_map) return 1;
   }
 
   return 0;
 }
 
-static void enc_free_mi(AV1_COMMON *cm) {
-  aom_free(cm->mi);
-  cm->mi = NULL;
-  aom_free(cm->mi_grid_base);
-  cm->mi_grid_base = NULL;
-  cm->mi_alloc_size = 0;
-  aom_free(cm->tx_type_map);
-  cm->tx_type_map = NULL;
+static void enc_free_mi(CommonModeInfoParams *mi_params) {
+  aom_free(mi_params->mi);
+  mi_params->mi = NULL;
+  aom_free(mi_params->mi_grid_base);
+  mi_params->mi_grid_base = NULL;
+  mi_params->mi_alloc_size = 0;
+  aom_free(mi_params->tx_type_map);
+  mi_params->tx_type_map = NULL;
 }
 
 void av1_initialize_enc(void) {
@@ -724,7 +739,8 @@
 
 static void alloc_context_buffers_ext(AV1_COMP *cpi) {
   AV1_COMMON *cm = &cpi->common;
-  const int new_ext_mi_size = cm->mi_alloc_rows * cm->mi_alloc_cols;
+  const int new_ext_mi_size =
+      cm->mi_params.mi_alloc_rows * cm->mi_params.mi_alloc_cols;
 
   if (new_ext_mi_size > cpi->mi_ext_alloc_size) {
     dealloc_context_buffers_ext(cpi);
@@ -906,7 +922,8 @@
   // Disable and clear down for KF
   if (cm->current_frame.frame_type == KEY_FRAME) {
     // Clear down the global segmentation map
-    memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
+    memset(cpi->segmentation_map, 0,
+           cm->mi_params.mi_rows * cm->mi_params.mi_cols);
     seg->update_map = 0;
     seg->update_data = 0;
     cpi->static_mb_pct = 0;
@@ -919,7 +936,8 @@
   } else if (cpi->refresh_alt_ref_frame) {
     // If this is an alt ref frame
     // Clear down the global segmentation map
-    memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
+    memset(cpi->segmentation_map, 0,
+           cm->mi_params.mi_rows * cm->mi_params.mi_cols);
     seg->update_map = 0;
     seg->update_data = 0;
     cpi->static_mb_pct = 0;
@@ -986,7 +1004,8 @@
 
         av1_disable_segmentation(seg);
 
-        memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
+        memset(cpi->segmentation_map, 0,
+               cm->mi_params.mi_rows * cm->mi_params.mi_cols);
 
         seg->update_map = 0;
         seg->update_data = 0;
@@ -1027,17 +1046,17 @@
 
 static void update_reference_segmentation_map(AV1_COMP *cpi) {
   AV1_COMMON *const cm = &cpi->common;
-  MB_MODE_INFO **mi_4x4_ptr = cm->mi_grid_base;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
+  MB_MODE_INFO **mi_4x4_ptr = mi_params->mi_grid_base;
   uint8_t *cache_ptr = cm->cur_frame->seg_map;
-  int row, col;
 
-  for (row = 0; row < cm->mi_rows; row++) {
+  for (int row = 0; row < mi_params->mi_rows; row++) {
     MB_MODE_INFO **mi_4x4 = mi_4x4_ptr;
     uint8_t *cache = cache_ptr;
-    for (col = 0; col < cm->mi_cols; col++, mi_4x4++, cache++)
+    for (int col = 0; col < mi_params->mi_cols; col++, mi_4x4++, cache++)
       cache[0] = mi_4x4[0]->segment_id;
-    mi_4x4_ptr += cm->mi_stride;
-    cache_ptr += cm->mi_cols;
+    mi_4x4_ptr += mi_params->mi_stride;
+    cache_ptr += mi_params->mi_cols;
   }
 }
 
@@ -1100,7 +1119,7 @@
   }
 
   int mi_rows_aligned_to_sb =
-      ALIGN_POWER_OF_TWO(cm->mi_rows, cm->seq_params.mib_size_log2);
+      ALIGN_POWER_OF_TWO(cm->mi_params.mi_rows, cm->seq_params.mib_size_log2);
   int sb_rows = mi_rows_aligned_to_sb >> cm->seq_params.mib_size_log2;
 
   av1_alloc_txb_buf(cpi);
@@ -1111,7 +1130,8 @@
 
   {
     unsigned int tokens =
-        get_token_alloc(cm->mb_rows, cm->mb_cols, MAX_SB_SIZE_LOG2, num_planes);
+        get_token_alloc(cm->mi_params.mb_rows, cm->mi_params.mb_cols,
+                        MAX_SB_SIZE_LOG2, num_planes);
     CHECK_MEM_ERROR(cm, cpi->tile_tok[0][0],
                     aom_calloc(tokens, sizeof(*cpi->tile_tok[0][0])));
   }
@@ -1147,6 +1167,7 @@
 
 static void set_tile_info(AV1_COMP *cpi) {
   AV1_COMMON *const cm = &cpi->common;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   const SequenceHeader *const seq_params = &cm->seq_params;
   CommonTileParams *const tiles = &cm->tiles;
   int i, start_sb;
@@ -1159,7 +1180,8 @@
     tiles->log2_cols = AOMMAX(cpi->oxcf.tile_columns, tiles->min_log2_cols);
     tiles->log2_cols = AOMMIN(tiles->log2_cols, tiles->max_log2_cols);
   } else {
-    int mi_cols = ALIGN_POWER_OF_TWO(cm->mi_cols, seq_params->mib_size_log2);
+    int mi_cols =
+        ALIGN_POWER_OF_TWO(mi_params->mi_cols, seq_params->mib_size_log2);
     int sb_cols = mi_cols >> seq_params->mib_size_log2;
     int size_sb, j = 0;
     tiles->uniform_spacing = 0;
@@ -1172,14 +1194,16 @@
     tiles->cols = i;
     tiles->col_start_sb[i] = sb_cols;
   }
-  av1_calculate_tile_cols(seq_params, cm->mi_rows, cm->mi_cols, tiles);
+  av1_calculate_tile_cols(seq_params, mi_params->mi_rows, mi_params->mi_cols,
+                          tiles);
 
   // configure tile rows
   if (tiles->uniform_spacing) {
     tiles->log2_rows = AOMMAX(cpi->oxcf.tile_rows, tiles->min_log2_rows);
     tiles->log2_rows = AOMMIN(tiles->log2_rows, tiles->max_log2_rows);
   } else {
-    int mi_rows = ALIGN_POWER_OF_TWO(cm->mi_rows, seq_params->mib_size_log2);
+    int mi_rows =
+        ALIGN_POWER_OF_TWO(mi_params->mi_rows, seq_params->mib_size_log2);
     int sb_rows = mi_rows >> seq_params->mib_size_log2;
     int size_sb, j = 0;
     for (i = 0, start_sb = 0; start_sb < sb_rows && i < MAX_TILE_ROWS; i++) {
@@ -1191,7 +1215,7 @@
     tiles->rows = i;
     tiles->row_start_sb[i] = sb_rows;
   }
-  av1_calculate_tile_rows(seq_params, cm->mi_rows, tiles);
+  av1_calculate_tile_rows(seq_params, mi_params->mi_rows, tiles);
 }
 
 static void update_frame_size(AV1_COMP *cpi) {
@@ -1203,11 +1227,12 @@
     aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
                        "Failed to allocate context buffers");
   }
-  av1_init_context_buffers(cm);
+  av1_init_mi_buffers(&cm->mi_params);
 
   av1_init_macroblockd(cm, xd, NULL);
 
-  const int ext_mi_size = cm->mi_alloc_rows * cm->mi_alloc_cols;
+  const int ext_mi_size =
+      cm->mi_params.mi_alloc_rows * cm->mi_params.mi_alloc_cols;
   alloc_context_buffers_ext(cpi);
   memset(cpi->mbmi_ext_frame_base, 0,
          ext_mi_size * sizeof(*cpi->mbmi_ext_frame_base));
@@ -2652,21 +2677,23 @@
 
 static void realloc_segmentation_maps(AV1_COMP *cpi) {
   AV1_COMMON *const cm = &cpi->common;
+  CommonModeInfoParams *const mi_params = &cm->mi_params;
 
   // Create the encoder segmentation map and set all entries to 0
   aom_free(cpi->segmentation_map);
   CHECK_MEM_ERROR(cm, cpi->segmentation_map,
-                  aom_calloc(cm->mi_rows * cm->mi_cols, 1));
+                  aom_calloc(mi_params->mi_rows * mi_params->mi_cols, 1));
 
   // Create a map used for cyclic background refresh.
   if (cpi->cyclic_refresh) av1_cyclic_refresh_free(cpi->cyclic_refresh);
-  CHECK_MEM_ERROR(cm, cpi->cyclic_refresh,
-                  av1_cyclic_refresh_alloc(cm->mi_rows, cm->mi_cols));
+  CHECK_MEM_ERROR(
+      cm, cpi->cyclic_refresh,
+      av1_cyclic_refresh_alloc(mi_params->mi_rows, mi_params->mi_cols));
 
   // Create a map used to mark inactive areas.
   aom_free(cpi->active_map.map);
   CHECK_MEM_ERROR(cm, cpi->active_map.map,
-                  aom_calloc(cm->mi_rows * cm->mi_cols, 1));
+                  aom_calloc(mi_params->mi_rows * mi_params->mi_cols, 1));
 }
 
 static void set_tpl_stats_block_size(AV1_COMP *cpi) {
@@ -2965,12 +2992,14 @@
   }
 
   cm->error.setjmp = 1;
-  cm->alloc_mi = enc_alloc_mi;
-  cm->free_mi = enc_free_mi;
-  cm->setup_mi = enc_setup_mi;
-  cm->set_mb_mi = enc_set_mb_mi;
 
-  cm->mi_alloc_bsize = BLOCK_4X4;
+  CommonModeInfoParams *const mi_params = &cm->mi_params;
+  mi_params->alloc_mi = enc_alloc_mi;
+  mi_params->free_mi = enc_free_mi;
+  mi_params->setup_mi = enc_setup_mi;
+  mi_params->set_mb_mi = enc_set_mb_mi;
+
+  mi_params->mi_alloc_bsize = BLOCK_4X4;
 
   CHECK_MEM_ERROR(cm, cm->fc,
                   (FRAME_CONTEXT *)aom_memalign(32, sizeof(*cm->fc)));
@@ -3042,9 +3071,10 @@
   }
 
   if (cpi->b_calculate_consistency) {
-    CHECK_MEM_ERROR(cm, cpi->ssim_vars,
-                    aom_malloc(sizeof(*cpi->ssim_vars) * 4 *
-                               cpi->common.mi_rows * cpi->common.mi_cols));
+    CHECK_MEM_ERROR(
+        cm, cpi->ssim_vars,
+        aom_malloc(sizeof(*cpi->ssim_vars) * 4 * cpi->common.mi_params.mi_rows *
+                   cpi->common.mi_params.mi_cols));
     cpi->worst_consistency = 100.0;
   }
 #endif
@@ -3133,8 +3163,8 @@
     const int bsize = BLOCK_16X16;
     const int w = mi_size_wide[bsize];
     const int h = mi_size_high[bsize];
-    const int num_cols = (cm->mi_cols + w - 1) / w;
-    const int num_rows = (cm->mi_rows + h - 1) / h;
+    const int num_cols = (mi_params->mi_cols + w - 1) / w;
+    const int num_rows = (mi_params->mi_rows + h - 1) / h;
     CHECK_MEM_ERROR(cm, cpi->tpl_rdmult_scaling_factors,
                     aom_calloc(num_rows * num_cols,
                                sizeof(*cpi->tpl_rdmult_scaling_factors)));
@@ -3147,8 +3177,8 @@
     const int bsize = BLOCK_16X16;
     const int w = mi_size_wide[bsize];
     const int h = mi_size_high[bsize];
-    const int num_cols = (cm->mi_cols + w - 1) / w;
-    const int num_rows = (cm->mi_rows + h - 1) / h;
+    const int num_cols = (mi_params->mi_cols + w - 1) / w;
+    const int num_rows = (mi_params->mi_rows + h - 1) / h;
     CHECK_MEM_ERROR(cm, cpi->ssim_rdmult_scaling_factors,
                     aom_calloc(num_rows * num_cols,
                                sizeof(*cpi->ssim_rdmult_scaling_factors)));
@@ -3159,8 +3189,8 @@
     const int bsize = BLOCK_64X64;
     const int w = mi_size_wide[bsize];
     const int h = mi_size_high[bsize];
-    const int num_cols = (cm->mi_cols + w - 1) / w;
-    const int num_rows = (cm->mi_rows + h - 1) / h;
+    const int num_cols = (mi_params->mi_cols + w - 1) / w;
+    const int num_rows = (mi_params->mi_rows + h - 1) / h;
     CHECK_MEM_ERROR(cm, cpi->vmaf_rdmult_scaling_factors,
                     aom_calloc(num_rows * num_cols,
                                sizeof(*cpi->vmaf_rdmult_scaling_factors)));
@@ -3170,8 +3200,10 @@
   set_tpl_stats_block_size(cpi);
 
   for (int frame = 0; frame < MAX_LENGTH_TPL_FRAME_STATS; ++frame) {
-    const int mi_cols = ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2);
-    const int mi_rows = ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2);
+    const int mi_cols =
+        ALIGN_POWER_OF_TWO(mi_params->mi_cols, MAX_MIB_SIZE_LOG2);
+    const int mi_rows =
+        ALIGN_POWER_OF_TWO(mi_params->mi_rows, MAX_MIB_SIZE_LOG2);
 
     cpi->tpl_stats_buffer[frame].is_valid = 0;
     cpi->tpl_stats_buffer[frame].width =
@@ -3179,8 +3211,8 @@
     cpi->tpl_stats_buffer[frame].height =
         mi_rows >> cpi->tpl_stats_block_mis_log2;
     cpi->tpl_stats_buffer[frame].stride = cpi->tpl_stats_buffer[frame].width;
-    cpi->tpl_stats_buffer[frame].mi_rows = cm->mi_rows;
-    cpi->tpl_stats_buffer[frame].mi_cols = cm->mi_cols;
+    cpi->tpl_stats_buffer[frame].mi_rows = mi_params->mi_rows;
+    cpi->tpl_stats_buffer[frame].mi_cols = mi_params->mi_cols;
   }
 
   for (int frame = 0; frame < MAX_LAG_BUFFERS; ++frame) {
@@ -4089,7 +4121,7 @@
     const int step = 1 << cpi->tpl_stats_block_mis_log2;
     const int mi_cols_sr = av1_pixels_to_mi(cm->superres_upscaled_width);
 
-    for (int row = 0; row < cm->mi_rows; row += step) {
+    for (int row = 0; row < cm->mi_params.mi_rows; row += step) {
       for (int col = 0; col < mi_cols_sr; col += step) {
         TplDepStats *this_stats =
             &tpl_stats[av1_tpl_ptr_pos(cpi, row, col, tpl_stride)];
@@ -4149,10 +4181,10 @@
         }
       }
 #if !USE_TPL_CLASSIC_MODEL
-      cpi->rd.mc_count_base =
-          (double)mc_count_base / (cm->mi_rows * cm->mi_cols);
-      cpi->rd.mc_saved_base =
-          (double)mc_saved_base / (cm->mi_rows * cm->mi_cols);
+      cpi->rd.mc_count_base = (double)mc_count_base /
+                              (cm->mi_params.mi_rows * cm->mi_params.mi_cols);
+      cpi->rd.mc_saved_base = (double)mc_saved_base /
+                              (cm->mi_params.mi_rows * cm->mi_params.mi_cols);
 #endif  // !USE_TPL_CLASSIC_MODEL
       aom_clear_system_state();
     }
@@ -4277,7 +4309,7 @@
 
     cpi->initial_width = cm->width;
     cpi->initial_height = cm->height;
-    cpi->initial_mbs = cm->MBs;
+    cpi->initial_mbs = cm->mi_params.MBs;
   }
 }
 
@@ -4331,7 +4363,7 @@
 
   // Allocate above context buffers
   if (cm->num_allocated_above_context_planes < av1_num_planes(cm) ||
-      cm->num_allocated_above_context_mi_col < cm->mi_cols ||
+      cm->num_allocated_above_context_mi_col < cm->mi_params.mi_cols ||
       cm->num_allocated_above_contexts < cm->tiles.rows) {
     av1_free_above_context_buffers(cm, cm->num_allocated_above_contexts);
     if (av1_alloc_above_context_buffers(cm, cm->tiles.rows))
@@ -6093,7 +6125,7 @@
 }
 
 static void set_mb_ssim_rdmult_scaling(AV1_COMP *cpi) {
-  AV1_COMMON *cm = &cpi->common;
+  const CommonModeInfoParams *const mi_params = &cpi->common.mi_params;
   ThreadData *td = &cpi->td;
   MACROBLOCK *x = &td->mb;
   MACROBLOCKD *xd = &x->e_mbd;
@@ -6103,24 +6135,23 @@
 
   const int num_mi_w = mi_size_wide[block_size];
   const int num_mi_h = mi_size_high[block_size];
-  const int num_cols = (cm->mi_cols + num_mi_w - 1) / num_mi_w;
-  const int num_rows = (cm->mi_rows + num_mi_h - 1) / num_mi_h;
+  const int num_cols = (mi_params->mi_cols + num_mi_w - 1) / num_mi_w;
+  const int num_rows = (mi_params->mi_rows + num_mi_h - 1) / num_mi_h;
   double log_sum = 0.0;
-  int row, col;
   const int use_hbd = cpi->source->flags & YV12_FLAG_HIGHBITDEPTH;
 
   // Loop through each 16x16 block.
-  for (row = 0; row < num_rows; ++row) {
-    for (col = 0; col < num_cols; ++col) {
-      int mi_row, mi_col;
+  for (int row = 0; row < num_rows; ++row) {
+    for (int col = 0; col < num_cols; ++col) {
       double var = 0.0, num_of_var = 0.0;
       const int index = row * num_cols + col;
 
       // Loop through each 8x8 block.
-      for (mi_row = row * num_mi_h;
-           mi_row < cm->mi_rows && mi_row < (row + 1) * num_mi_h; mi_row += 2) {
-        for (mi_col = col * num_mi_w;
-             mi_col < cm->mi_cols && mi_col < (col + 1) * num_mi_w;
+      for (int mi_row = row * num_mi_h;
+           mi_row < mi_params->mi_rows && mi_row < (row + 1) * num_mi_h;
+           mi_row += 2) {
+        for (int mi_col = col * num_mi_w;
+             mi_col < mi_params->mi_cols && mi_col < (col + 1) * num_mi_w;
              mi_col += 2) {
           struct buf_2d buf;
           const int row_offset_y = mi_row << 2;
@@ -6150,14 +6181,12 @@
   }
   log_sum = exp(log_sum / (double)(num_rows * num_cols));
 
-  for (row = 0; row < num_rows; ++row) {
-    for (col = 0; col < num_cols; ++col) {
+  for (int row = 0; row < num_rows; ++row) {
+    for (int col = 0; col < num_cols; ++col) {
       const int index = row * num_cols + col;
       cpi->ssim_rdmult_scaling_factors[index] /= log_sum;
     }
   }
-
-  (void)xd;
 }
 
 #if CONFIG_DEBUG
@@ -6410,7 +6439,7 @@
       update_reference_segmentation_map(cpi);
     } else if (cm->last_frame_seg_map) {
       memcpy(cm->cur_frame->seg_map, cm->last_frame_seg_map,
-             cm->mi_cols * cm->mi_rows * sizeof(uint8_t));
+             cm->mi_params.mi_cols * cm->mi_params.mi_rows * sizeof(uint8_t));
     }
   }
 
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 79bbe43..29e8f68 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -1496,15 +1496,15 @@
                                          MACROBLOCK *const x,
                                          MACROBLOCKD *const xd, int mi_row,
                                          int mi_col) {
-  const AV1_COMMON *const cm = &cpi->common;
-  const int grid_idx = get_mi_grid_idx(cm, mi_row, mi_col);
-  const int mi_idx = get_alloc_mi_idx(cm, mi_row, mi_col);
-  const int ext_idx = get_mi_ext_idx(cm, mi_row, mi_col);
+  const CommonModeInfoParams *const mi_params = &cpi->common.mi_params;
+  const int grid_idx = get_mi_grid_idx(mi_params, mi_row, mi_col);
+  const int mi_idx = get_alloc_mi_idx(mi_params, mi_row, mi_col);
+  const int ext_idx = get_mi_ext_idx(mi_params, mi_row, mi_col);
 
-  xd->mi = cm->mi_grid_base + grid_idx;
-  xd->mi[0] = cm->mi + mi_idx;
-  xd->tx_type_map = cm->tx_type_map + grid_idx;
-  xd->tx_type_map_stride = cm->mi_stride;
+  xd->mi = mi_params->mi_grid_base + grid_idx;
+  xd->mi[0] = mi_params->mi + mi_idx;
+  xd->tx_type_map = mi_params->tx_type_map + grid_idx;
+  xd->tx_type_map_stride = mi_params->mi_stride;
   x->mbmi_ext_frame = cpi->mbmi_ext_frame_base + ext_idx;
 }
 
diff --git a/av1/encoder/encodetxb.c b/av1/encoder/encodetxb.c
index 0b539b0..c2941a5 100644
--- a/av1/encoder/encodetxb.c
+++ b/av1/encoder/encodetxb.c
@@ -73,8 +73,8 @@
 
 void av1_alloc_txb_buf(AV1_COMP *cpi) {
   AV1_COMMON *cm = &cpi->common;
-  int size = ((cm->mi_rows >> cm->seq_params.mib_size_log2) + 1) *
-             ((cm->mi_cols >> cm->seq_params.mib_size_log2) + 1);
+  int size = ((cm->mi_params.mi_rows >> cm->seq_params.mib_size_log2) + 1) *
+             ((cm->mi_params.mi_cols >> cm->seq_params.mib_size_log2) + 1);
 
   av1_free_txb_buf(cpi);
   // TODO(jingning): This should be further reduced.
@@ -2259,7 +2259,7 @@
                                          int mi_col) {
   const AV1_COMMON *const cm = &cpi->common;
   const int mib_size_log2 = cm->seq_params.mib_size_log2;
-  const int stride = (cm->mi_cols >> mib_size_log2) + 1;
+  const int stride = (cm->mi_params.mi_cols >> mib_size_log2) + 1;
   const int offset =
       (mi_row >> mib_size_log2) * stride + (mi_col >> mib_size_log2);
   return cpi->coeff_buffer_base + offset;
diff --git a/av1/encoder/ethread.c b/av1/encoder/ethread.c
index 0ba8d63..3682b68 100644
--- a/av1/encoder/ethread.c
+++ b/av1/encoder/ethread.c
@@ -60,8 +60,8 @@
           av1_reset_loop_filter_delta(xd, av1_num_planes(cm));
         for (int mi_col = tile_info->mi_col_start;
              mi_col < tile_info->mi_col_end; mi_col += mib_size) {
-          const int idx_str = cm->mi_stride * mi_row + mi_col;
-          MB_MODE_INFO **mi = cm->mi_grid_base + idx_str;
+          const int idx_str = cm->mi_params.mi_stride * mi_row + mi_col;
+          MB_MODE_INFO **mi = cm->mi_params.mi_grid_base + idx_str;
           MB_MODE_INFO *mbmi = mi[0];
           if (mbmi->skip == 1 && (mbmi->sb_type == cm->seq_params.sb_size)) {
             for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id)
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c
index 1a32356..9abd0c6 100644
--- a/av1/encoder/firstpass.c
+++ b/av1/encoder/firstpass.c
@@ -252,16 +252,17 @@
   }
 }
 
-static BLOCK_SIZE get_bsize(const AV1_COMMON *cm, int mb_row, int mb_col) {
+static BLOCK_SIZE get_bsize(const CommonModeInfoParams *const mi_params,
+                            int mb_row, int mb_col) {
   if (mi_size_wide[BLOCK_16X16] * mb_col + mi_size_wide[BLOCK_8X8] <
-      cm->mi_cols) {
+      mi_params->mi_cols) {
     return mi_size_wide[BLOCK_16X16] * mb_row + mi_size_wide[BLOCK_8X8] <
-                   cm->mi_rows
+                   mi_params->mi_rows
                ? BLOCK_16X16
                : BLOCK_16X8;
   } else {
     return mi_size_wide[BLOCK_16X16] * mb_row + mi_size_wide[BLOCK_8X8] <
-                   cm->mi_rows
+                   mi_params->mi_rows
                ? BLOCK_8X16
                : BLOCK_8X8;
   }
@@ -300,6 +301,7 @@
   int mb_row, mb_col;
   MACROBLOCK *const x = &cpi->td.mb;
   AV1_COMMON *const cm = &cpi->common;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   CurrentFrame *const current_frame = &cm->current_frame;
   const SequenceHeader *const seq_params = &cm->seq_params;
   const int num_planes = av1_num_planes(cm);
@@ -355,9 +357,9 @@
 
   int *raw_motion_err_list;
   int raw_motion_err_counts = 0;
-  CHECK_MEM_ERROR(
-      cm, raw_motion_err_list,
-      aom_calloc(cm->mb_rows * cm->mb_cols, sizeof(*raw_motion_err_list)));
+  CHECK_MEM_ERROR(cm, raw_motion_err_list,
+                  aom_calloc(mi_params->mb_rows * mi_params->mb_cols,
+                             sizeof(*raw_motion_err_list)));
   // First pass code requires valid last and new frame buffers.
   assert(new_yv12 != NULL);
   assert(frame_is_intra_only(cm) || (lst_yv12 != NULL));
@@ -365,8 +367,8 @@
   av1_setup_frame_size(cpi);
   aom_clear_system_state();
 
-  xd->mi = cm->mi_grid_base;
-  xd->mi[0] = cm->mi;
+  xd->mi = mi_params->mi_grid_base;
+  xd->mi[0] = mi_params->mi;
   x->e_mbd.mi[0]->sb_type = BLOCK_16X16;
 
   intra_factor = 0.0;
@@ -390,8 +392,8 @@
     av1_setup_pre_planes(xd, 0, lst_yv12, 0, 0, NULL, num_planes);
   }
 
-  xd->mi = cm->mi_grid_base;
-  xd->mi[0] = cm->mi;
+  xd->mi = mi_params->mi_grid_base;
+  xd->mi[0] = mi_params->mi;
 
   // Don't store luma on the fist pass since chroma is not computed
   xd->cfl.store_y = 0;
@@ -415,7 +417,7 @@
   recon_uv_stride = new_yv12->uv_stride;
   uv_mb_height = 16 >> (new_yv12->y_height > new_yv12->uv_height);
 
-  for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) {
+  for (mb_row = 0; mb_row < mi_params->mb_rows; ++mb_row) {
     MV best_ref_mv = kZeroMv;
 
     // Reset above block coeffs.
@@ -428,26 +430,26 @@
 
     // Set up limit values for motion vectors to prevent them extending
     // outside the UMV borders.
-    av1_set_mv_row_limits(cm, &x->mv_limits, (mb_row << 2),
+    av1_set_mv_row_limits(mi_params, &x->mv_limits, (mb_row << 2),
                           (16 >> MI_SIZE_LOG2), cpi->oxcf.border_in_pixels);
 
-    for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) {
+    for (mb_col = 0; mb_col < mi_params->mb_cols; ++mb_col) {
       int this_intra_error;
       const int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
-      const BLOCK_SIZE bsize = get_bsize(cm, mb_row, mb_col);
+      const BLOCK_SIZE bsize = get_bsize(mi_params, mb_row, mb_col);
       double log_intra;
       int level_sample;
 
       aom_clear_system_state();
 
       const int grid_idx =
-          get_mi_grid_idx(cm, mb_row * mb_scale, mb_col * mb_scale);
+          get_mi_grid_idx(mi_params, mb_row * mb_scale, mb_col * mb_scale);
       const int mi_idx =
-          get_alloc_mi_idx(cm, mb_row * mb_scale, mb_col * mb_scale);
-      xd->mi = cm->mi_grid_base + grid_idx;
-      xd->mi[0] = cm->mi + mi_idx;
-      xd->tx_type_map = cm->tx_type_map + grid_idx;
-      xd->tx_type_map_stride = cm->mi_stride;
+          get_alloc_mi_idx(mi_params, mb_row * mb_scale, mb_col * mb_scale);
+      xd->mi = mi_params->mi_grid_base + grid_idx;
+      xd->mi[0] = mi_params->mi + mi_idx;
+      xd->tx_type_map = mi_params->tx_type_map + grid_idx;
+      xd->tx_type_map_stride = mi_params->mi_stride;
       xd->plane[0].dst.buf = new_yv12->y_buffer + recon_yoffset;
       xd->plane[1].dst.buf = new_yv12->u_buffer + recon_uvoffset;
       xd->plane[2].dst.buf = new_yv12->v_buffer + recon_uvoffset;
@@ -455,8 +457,8 @@
       xd->mi[0]->sb_type = bsize;
       xd->mi[0]->ref_frame[0] = INTRA_FRAME;
       set_mi_row_col(xd, &tile, mb_row * mb_scale, mi_size_high[bsize],
-                     mb_col * mb_scale, mi_size_wide[bsize], cm->mi_rows,
-                     cm->mi_cols);
+                     mb_col * mb_scale, mi_size_wide[bsize], mi_params->mi_rows,
+                     mi_params->mi_cols);
 
       set_plane_n4(xd, mi_size_wide[bsize], mi_size_high[bsize], num_planes);
 
@@ -528,7 +530,7 @@
 
       // Set up limit values for motion vectors to prevent them extending
       // outside the UMV borders.
-      av1_set_mv_col_limits(cm, &x->mv_limits, (mb_col << 2),
+      av1_set_mv_col_limits(mi_params, &x->mv_limits, (mb_col << 2),
                             (16 >> MI_SIZE_LOG2), cpi->oxcf.border_in_pixels);
 
       if (!frame_is_intra_only(cm)) {  // Do a motion search
@@ -723,12 +725,12 @@
             lastmv = best_mv;
 
             // Does the row vector point inwards or outwards?
-            if (mb_row < cm->mb_rows / 2) {
+            if (mb_row < mi_params->mb_rows / 2) {
               if (mv.row > 0)
                 --sum_in_vectors;
               else if (mv.row < 0)
                 ++sum_in_vectors;
-            } else if (mb_row > cm->mb_rows / 2) {
+            } else if (mb_row > mi_params->mb_rows / 2) {
               if (mv.row > 0)
                 ++sum_in_vectors;
               else if (mv.row < 0)
@@ -736,12 +738,12 @@
             }
 
             // Does the col vector point inwards or outwards?
-            if (mb_col < cm->mb_cols / 2) {
+            if (mb_col < mi_params->mb_cols / 2) {
               if (mv.col > 0)
                 --sum_in_vectors;
               else if (mv.col < 0)
                 ++sum_in_vectors;
-            } else if (mb_col > cm->mb_cols / 2) {
+            } else if (mb_col > mi_params->mb_cols / 2) {
               if (mv.col > 0)
                 ++sum_in_vectors;
               else if (mv.col < 0)
@@ -767,11 +769,12 @@
       alt_yv12_yoffset += 16;
     }
     // Adjust to the next row of MBs.
-    x->plane[0].src.buf += 16 * x->plane[0].src.stride - 16 * cm->mb_cols;
-    x->plane[1].src.buf +=
-        uv_mb_height * x->plane[1].src.stride - uv_mb_height * cm->mb_cols;
-    x->plane[2].src.buf +=
-        uv_mb_height * x->plane[1].src.stride - uv_mb_height * cm->mb_cols;
+    x->plane[0].src.buf +=
+        16 * x->plane[0].src.stride - 16 * mi_params->mb_cols;
+    x->plane[1].src.buf += uv_mb_height * x->plane[1].src.stride -
+                           uv_mb_height * mi_params->mb_cols;
+    x->plane[2].src.buf += uv_mb_height * x->plane[1].src.stride -
+                           uv_mb_height * mi_params->mb_cols;
 
     aom_clear_system_state();
   }
@@ -781,14 +784,14 @@
 
   // Clamp the image start to rows/2. This number of rows is discarded top
   // and bottom as dead data so rows / 2 means the frame is blank.
-  if ((image_data_start_row > cm->mb_rows / 2) ||
+  if ((image_data_start_row > mi_params->mb_rows / 2) ||
       (image_data_start_row == INVALID_ROW)) {
-    image_data_start_row = cm->mb_rows / 2;
+    image_data_start_row = mi_params->mb_rows / 2;
   }
   // Exclude any image dead zone
   if (image_data_start_row > 0) {
-    intra_skip_count =
-        AOMMAX(0, intra_skip_count - (image_data_start_row * cm->mb_cols * 2));
+    intra_skip_count = AOMMAX(
+        0, intra_skip_count - (image_data_start_row * mi_params->mb_cols * 2));
   }
 
   FIRSTPASS_STATS *this_frame_stats = twopass->stats_buf_ctx->stats_in_end;
@@ -801,7 +804,7 @@
     // number of mbs is proportional to the image area.
     const int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE)
                             ? cpi->initial_mbs
-                            : cpi->common.MBs;
+                            : mi_params->MBs;
     const double min_err = 200 * sqrt(num_mbs);
 
     intra_factor = intra_factor / (double)num_mbs;
diff --git a/av1/encoder/level.c b/av1/encoder/level.c
index 1d570a3..94d4f55 100644
--- a/av1/encoder/level.c
+++ b/av1/encoder/level.c
@@ -944,7 +944,8 @@
       *min_cropped_tile_height =
           AOMMIN(*min_cropped_tile_height, cropped_tile_height);
 
-      const int is_right_most_tile = tile_info->mi_col_end == cm->mi_cols;
+      const int is_right_most_tile =
+          tile_info->mi_col_end == cm->mi_params.mi_cols;
       if (!is_right_most_tile) {
         if (av1_superres_scaled(cm))
           *tile_width_valid &= tile_width >= 128;
diff --git a/av1/encoder/mcomp.h b/av1/encoder/mcomp.h
index 679435f..f385c38 100644
--- a/av1/encoder/mcomp.h
+++ b/av1/encoder/mcomp.h
@@ -163,36 +163,37 @@
 
 // Set up limit values for MV components.
 // Mv beyond the range do not produce new/different prediction block.
-static INLINE void av1_set_mv_row_limits(const AV1_COMMON *const cm,
-                                         FullMvLimits *mv_limits, int mi_row,
-                                         int mi_height, int border) {
+static INLINE void av1_set_mv_row_limits(
+    const CommonModeInfoParams *const mi_params, FullMvLimits *mv_limits,
+    int mi_row, int mi_height, int border) {
   const int min1 = -(mi_row * MI_SIZE + border - 2 * AOM_INTERP_EXTEND);
   const int min2 = -(((mi_row + mi_height) * MI_SIZE) + 2 * AOM_INTERP_EXTEND);
   mv_limits->row_min = AOMMAX(min1, min2);
-  const int max1 = (cm->mi_rows - mi_row - mi_height) * MI_SIZE + border -
-                   2 * AOM_INTERP_EXTEND;
-  const int max2 = (cm->mi_rows - mi_row) * MI_SIZE + 2 * AOM_INTERP_EXTEND;
+  const int max1 = (mi_params->mi_rows - mi_row - mi_height) * MI_SIZE +
+                   border - 2 * AOM_INTERP_EXTEND;
+  const int max2 =
+      (mi_params->mi_rows - mi_row) * MI_SIZE + 2 * AOM_INTERP_EXTEND;
   mv_limits->row_max = AOMMIN(max1, max2);
 }
 
-static INLINE void av1_set_mv_col_limits(const AV1_COMMON *const cm,
-                                         FullMvLimits *mv_limits, int mi_col,
-                                         int mi_width, int border) {
+static INLINE void av1_set_mv_col_limits(
+    const CommonModeInfoParams *const mi_params, FullMvLimits *mv_limits,
+    int mi_col, int mi_width, int border) {
   const int min1 = -(mi_col * MI_SIZE + border - 2 * AOM_INTERP_EXTEND);
   const int min2 = -(((mi_col + mi_width) * MI_SIZE) + 2 * AOM_INTERP_EXTEND);
   mv_limits->col_min = AOMMAX(min1, min2);
-  const int max1 = (cm->mi_cols - mi_col - mi_width) * MI_SIZE + border -
+  const int max1 = (mi_params->mi_cols - mi_col - mi_width) * MI_SIZE + border -
                    2 * AOM_INTERP_EXTEND;
-  const int max2 = (cm->mi_cols - mi_col) * MI_SIZE + 2 * AOM_INTERP_EXTEND;
+  const int max2 =
+      (mi_params->mi_cols - mi_col) * MI_SIZE + 2 * AOM_INTERP_EXTEND;
   mv_limits->col_max = AOMMIN(max1, max2);
 }
 
-static INLINE void av1_set_mv_limits(const AV1_COMMON *const cm,
-                                     FullMvLimits *mv_limits, int mi_row,
-                                     int mi_col, int mi_height, int mi_width,
-                                     int border) {
-  av1_set_mv_row_limits(cm, mv_limits, mi_row, mi_height, border);
-  av1_set_mv_col_limits(cm, mv_limits, mi_col, mi_width, border);
+static INLINE void av1_set_mv_limits(
+    const CommonModeInfoParams *const mi_params, FullMvLimits *mv_limits,
+    int mi_row, int mi_col, int mi_height, int mi_width, int border) {
+  av1_set_mv_row_limits(mi_params, mv_limits, mi_row, mi_height, border);
+  av1_set_mv_col_limits(mi_params, mv_limits, mi_col, mi_width, border);
 }
 
 void av1_set_mv_search_range(FullMvLimits *mv_limits, const MV *mv);
diff --git a/av1/encoder/mv_prec.c b/av1/encoder/mv_prec.c
index 384554d..1b28285 100644
--- a/av1/encoder/mv_prec.c
+++ b/av1/encoder/mv_prec.c
@@ -177,14 +177,16 @@
                                           const AV1_COMP *cpi, int mi_row,
                                           int mi_col) {
   const AV1_COMMON *cm = &cpi->common;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
 
-  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) {
+  if (mi_row >= mi_params->mi_rows || mi_col >= mi_params->mi_cols) {
     return;
   }
 
-  const MB_MODE_INFO *mbmi = cm->mi_grid_base[mi_row * cm->mi_stride + mi_col];
+  const MB_MODE_INFO *mbmi =
+      mi_params->mi_grid_base[mi_row * mi_params->mi_stride + mi_col];
   const MB_MODE_INFO_EXT_FRAME *mbmi_ext_frame =
-      cpi->mbmi_ext_frame_base + get_mi_ext_idx(cm, mi_row, mi_col);
+      cpi->mbmi_ext_frame_base + get_mi_ext_idx(mi_params, mi_row, mi_col);
 
   if (!is_inter_block(mbmi)) {
     mv_stats->intra_count++;
@@ -265,7 +267,8 @@
   assert(bsize < BLOCK_SIZES_ALL);
   const AV1_COMMON *cm = &cpi->common;
 
-  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
+  if (mi_row >= cm->mi_params.mi_rows || mi_col >= cm->mi_params.mi_cols)
+    return;
 
   const PARTITION_TYPE partition = get_partition(cm, mi_row, mi_col, bsize);
   const BLOCK_SIZE subsize = get_partition_subsize(bsize, partition);
diff --git a/av1/encoder/nonrd_pickmode.c b/av1/encoder/nonrd_pickmode.c
index 007291d..4e81806 100644
--- a/av1/encoder/nonrd_pickmode.c
+++ b/av1/encoder/nonrd_pickmode.c
@@ -2160,8 +2160,8 @@
   aom_usec_timer_mark(&ms_stat.timer2);
   ms_stat.avg_block_times[bsize] += aom_usec_timer_elapsed(&ms_stat.timer2);
   //
-  if ((mi_row + mi_size_high[bsize] >= (cpi->common.mi_rows)) &&
-      (mi_col + mi_size_wide[bsize] >= (cpi->common.mi_cols))) {
+  if ((mi_row + mi_size_high[bsize] >= (cpi->common.mi_params.mi_rows)) &&
+      (mi_col + mi_size_wide[bsize] >= (cpi->common.mi_params.mi_cols))) {
     int i, j;
     PREDICTION_MODE used_modes[3] = { NEARESTMV, NEARMV, NEWMV };
     BLOCK_SIZE bss[5] = { BLOCK_8X8, BLOCK_16X16, BLOCK_32X32, BLOCK_64X64,
diff --git a/av1/encoder/partition_strategy.c b/av1/encoder/partition_strategy.c
index 883208b..ff5a89c 100644
--- a/av1/encoder/partition_strategy.c
+++ b/av1/encoder/partition_strategy.c
@@ -316,7 +316,7 @@
   const AV1_COMMON *const cm = &cpi->common;
   int best_ref = -1;
 
-  if (mi_col >= cm->mi_cols || mi_row >= cm->mi_rows) {
+  if (mi_col >= cm->mi_params.mi_cols || mi_row >= cm->mi_params.mi_rows) {
     // If the whole block is outside of the image, set the var and sse to 0.
     *best_var = 0;
     *best_sse = 0;
diff --git a/av1/encoder/partition_strategy.h b/av1/encoder/partition_strategy.h
index 6405f32..e9e624b 100644
--- a/av1/encoder/partition_strategy.h
+++ b/av1/encoder/partition_strategy.h
@@ -140,6 +140,7 @@
                                                  int mi_row, int mi_col,
                                                  BLOCK_SIZE bsize) {
   const AV1_COMMON *const cm = &cpi->common;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   const int num_planes = av1_num_planes(cm);
   MACROBLOCKD *const xd = &x->e_mbd;
   const int mi_width = mi_size_wide[bsize];
@@ -153,8 +154,8 @@
 
   // Set up limit values for MV components.
   // Mv beyond the range do not produce new/different prediction block.
-  av1_set_mv_limits(cm, &x->mv_limits, mi_row, mi_col, mi_height, mi_width,
-                    cpi->oxcf.border_in_pixels);
+  av1_set_mv_limits(mi_params, &x->mv_limits, mi_row, mi_col, mi_height,
+                    mi_width, cpi->oxcf.border_in_pixels);
 
   set_plane_n4(xd, mi_width, mi_height, num_planes);
 
@@ -165,10 +166,10 @@
   assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
   xd->mb_to_top_edge = -GET_MV_SUBPEL(mi_row * MI_SIZE);
   xd->mb_to_bottom_edge =
-      GET_MV_SUBPEL((cm->mi_rows - mi_height - mi_row) * MI_SIZE);
+      GET_MV_SUBPEL((mi_params->mi_rows - mi_height - mi_row) * MI_SIZE);
   xd->mb_to_left_edge = -GET_MV_SUBPEL(mi_col * MI_SIZE);
   xd->mb_to_right_edge =
-      GET_MV_SUBPEL((cm->mi_cols - mi_width - mi_col) * MI_SIZE);
+      GET_MV_SUBPEL((mi_params->mi_cols - mi_width - mi_col) * MI_SIZE);
 
   // Set up source buffers.
   av1_setup_src_planes(x, cpi->source, mi_row, mi_col, num_planes, bsize);
@@ -190,13 +191,13 @@
   }
 }
 
-static INLINE int is_full_sb(AV1_COMMON *const cm, int mi_row, int mi_col,
-                             BLOCK_SIZE sb_size) {
+static INLINE int is_full_sb(const CommonModeInfoParams *const mi_params,
+                             int mi_row, int mi_col, BLOCK_SIZE sb_size) {
   const int sb_mi_wide = mi_size_wide[sb_size];
   const int sb_mi_high = mi_size_high[sb_size];
 
-  return (mi_row + sb_mi_high) <= cm->mi_rows &&
-         (mi_col + sb_mi_wide) <= cm->mi_cols;
+  return (mi_row + sb_mi_high) <= mi_params->mi_rows &&
+         (mi_col + sb_mi_wide) <= mi_params->mi_cols;
 }
 
 // Do not use this criteria for screen content videos.
@@ -211,7 +212,8 @@
   return !frame_is_intra_only(cm) && !cpi->is_screen_content_type &&
          cpi->sf.part_sf.auto_max_partition_based_on_simple_motion !=
              NOT_IN_USE &&
-         sb_size == BLOCK_128X128 && is_full_sb(cm, mi_row, mi_col, sb_size) &&
+         sb_size == BLOCK_128X128 &&
+         is_full_sb(&cm->mi_params, mi_row, mi_col, sb_size) &&
          cpi->gf_group.update_type[cpi->gf_group.index] != OVERLAY_UPDATE &&
          cpi->gf_group.update_type[cpi->gf_group.index] != INTNL_OVERLAY_UPDATE;
 }
diff --git a/av1/encoder/pass2_strategy.c b/av1/encoder/pass2_strategy.c
index 794e877..c2d8620 100644
--- a/av1/encoder/pass2_strategy.c
+++ b/av1/encoder/pass2_strategy.c
@@ -225,7 +225,7 @@
   } else {
     const int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE)
                             ? cpi->initial_mbs
-                            : cpi->common.MBs;
+                            : cpi->common.mi_params.MBs;
     const int active_mbs = AOMMAX(1, num_mbs - (int)(num_mbs * inactive_zone));
     const double av_err_per_mb = section_err / active_mbs;
     const int target_norm_bits_per_mb =
@@ -1658,8 +1658,9 @@
   // Was the group length constrained by the requirement for a new KF?
   rc->constrained_gf_group = (i >= rc->frames_to_key) ? 1 : 0;
 
-  const int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE) ? cpi->initial_mbs
-                                                             : cpi->common.MBs;
+  const int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE)
+                          ? cpi->initial_mbs
+                          : cm->mi_params.MBs;
   assert(num_mbs > 0);
 
   average_gf_stats(i, &next_frame, &gf_stats);
@@ -1818,7 +1819,7 @@
         gf_stats.gf_group_skip_pct / rc->baseline_gf_interval;
     const double group_av_inactive_zone =
         ((gf_stats.gf_group_inactive_zone_rows * 2) /
-         (rc->baseline_gf_interval * (double)cm->mb_rows));
+         (rc->baseline_gf_interval * (double)cm->mi_params.mb_rows));
 
     int tmp_q;
     // rc factor is a weight factor that corrects for local rate control drift.
@@ -2419,7 +2420,7 @@
         twopass->total_left_stats->intra_skip_pct / section_length;
     const double section_inactive_zone =
         (twopass->total_left_stats->inactive_zone_rows * 2) /
-        ((double)cm->mb_rows * section_length);
+        ((double)cm->mi_params.mb_rows * section_length);
     const int tmp_q = get_twopass_worst_quality(
         cpi, section_error, section_intra_skip + section_inactive_zone,
         section_target_bandwidth, DEFAULT_GRP_WEIGHT);
@@ -2444,7 +2445,7 @@
   {
     const int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE)
                             ? cpi->initial_mbs
-                            : cpi->common.MBs;
+                            : cm->mi_params.MBs;
     // The multiplication by 256 reverses a scaling factor of (>> 8)
     // applied when combining MB error values for the frame.
     twopass->mb_av_energy = log((this_frame->intra_error / num_mbs) + 1.0);
diff --git a/av1/encoder/pickcdef.c b/av1/encoder/pickcdef.c
index 2c2e2d3..cc323a2 100644
--- a/av1/encoder/pickcdef.c
+++ b/av1/encoder/pickcdef.c
@@ -274,11 +274,12 @@
   return sum >> 2 * coeff_shift;
 }
 
-static int sb_all_skip(const AV1_COMMON *const cm, int mi_row, int mi_col) {
-  const int maxr = AOMMIN(cm->mi_rows - mi_row, MI_SIZE_64X64);
-  const int maxc = AOMMIN(cm->mi_cols - mi_col, MI_SIZE_64X64);
-  const int stride = cm->mi_stride;
-  MB_MODE_INFO **mbmi = cm->mi_grid_base + mi_row * stride + mi_col;
+static int sb_all_skip(const CommonModeInfoParams *const mi_params, int mi_row,
+                       int mi_col) {
+  const int maxr = AOMMIN(mi_params->mi_rows - mi_row, MI_SIZE_64X64);
+  const int maxc = AOMMIN(mi_params->mi_cols - mi_col, MI_SIZE_64X64);
+  const int stride = mi_params->mi_stride;
+  MB_MODE_INFO **mbmi = mi_params->mi_grid_base + mi_row * stride + mi_col;
   for (int r = 0; r < maxr; ++r, mbmi += stride) {
     for (int c = 0; c < maxc; ++c) {
       if (!mbmi[c]->skip) return 0;
@@ -332,14 +333,15 @@
   cdef_info->cdef_uv_strengths[0] =
       predicted_uv_f1 * CDEF_SEC_STRENGTHS + predicted_uv_f2;
 
-  const int nvfb = (cm->mi_rows + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
-  const int nhfb = (cm->mi_cols + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
-  MB_MODE_INFO **mbmi = cm->mi_grid_base;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
+  const int nvfb = (mi_params->mi_rows + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
+  const int nhfb = (mi_params->mi_cols + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
+  MB_MODE_INFO **mbmi = mi_params->mi_grid_base;
   for (int r = 0; r < nvfb; ++r) {
     for (int c = 0; c < nhfb; ++c) {
       mbmi[MI_SIZE_64X64 * c]->cdef_strength = 0;
     }
-    mbmi += MI_SIZE_64X64 * cm->mi_stride;
+    mbmi += MI_SIZE_64X64 * mi_params->mi_stride;
   }
 }
 
@@ -356,8 +358,9 @@
   cdef_list dlist[MI_SIZE_128X128 * MI_SIZE_128X128];
   int dir[CDEF_NBLOCKS][CDEF_NBLOCKS] = { { 0 } };
   int var[CDEF_NBLOCKS][CDEF_NBLOCKS] = { { 0 } };
-  const int nvfb = (cm->mi_rows + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
-  const int nhfb = (cm->mi_cols + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
+  const int nvfb = (mi_params->mi_rows + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
+  const int nhfb = (mi_params->mi_cols + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
   int *sb_index = aom_malloc(nvfb * nhfb * sizeof(*sb_index));
   const int damping = 3 + (cm->base_qindex >> 6);
   const int fast = (pick_method == CDEF_FAST_SEARCH_LVL1 ||
@@ -394,22 +397,23 @@
         ref_stride = ref->uv_stride;
         break;
     }
-    src[pli] = aom_memalign(
-        32, sizeof(*src) * cm->mi_rows * cm->mi_cols * MI_SIZE * MI_SIZE);
-    ref_coeff[pli] = aom_memalign(
-        32, sizeof(*ref_coeff) * cm->mi_rows * cm->mi_cols * MI_SIZE * MI_SIZE);
+    src[pli] = aom_memalign(32, sizeof(*src) * mi_params->mi_rows *
+                                    mi_params->mi_cols * MI_SIZE * MI_SIZE);
+    ref_coeff[pli] =
+        aom_memalign(32, sizeof(*ref_coeff) * mi_params->mi_rows *
+                             mi_params->mi_cols * MI_SIZE * MI_SIZE);
     xdec[pli] = xd->plane[pli].subsampling_x;
     ydec[pli] = xd->plane[pli].subsampling_y;
     bsize[pli] = ydec[pli] ? (xdec[pli] ? BLOCK_4X4 : BLOCK_8X4)
                            : (xdec[pli] ? BLOCK_4X8 : BLOCK_8X8);
-    stride[pli] = cm->mi_cols << MI_SIZE_LOG2;
+    stride[pli] = mi_params->mi_cols << MI_SIZE_LOG2;
     mi_wide_l2[pli] = MI_SIZE_LOG2 - xd->plane[pli].subsampling_x;
     mi_high_l2[pli] = MI_SIZE_LOG2 - xd->plane[pli].subsampling_y;
 
     const int frame_height =
-        (cm->mi_rows * MI_SIZE) >> xd->plane[pli].subsampling_y;
+        (mi_params->mi_rows * MI_SIZE) >> xd->plane[pli].subsampling_y;
     const int frame_width =
-        (cm->mi_cols * MI_SIZE) >> xd->plane[pli].subsampling_x;
+        (mi_params->mi_cols * MI_SIZE) >> xd->plane[pli].subsampling_x;
     const int plane_sride = stride[pli];
     const int dst_stride = xd->plane[pli].dst.stride;
     for (int r = 0; r < frame_height; ++r) {
@@ -435,19 +439,20 @@
   for (int fbr = 0; fbr < nvfb; ++fbr) {
     for (int fbc = 0; fbc < nhfb; ++fbc) {
       // No filtering if the entire filter block is skipped
-      if (sb_all_skip(cm, fbr * MI_SIZE_64X64, fbc * MI_SIZE_64X64)) continue;
+      if (sb_all_skip(mi_params, fbr * MI_SIZE_64X64, fbc * MI_SIZE_64X64))
+        continue;
 
       const MB_MODE_INFO *const mbmi =
-          cm->mi_grid_base[MI_SIZE_64X64 * fbr * cm->mi_stride +
-                           MI_SIZE_64X64 * fbc];
+          mi_params->mi_grid_base[MI_SIZE_64X64 * fbr * mi_params->mi_stride +
+                                  MI_SIZE_64X64 * fbc];
       if (((fbc & 1) &&
            (mbmi->sb_type == BLOCK_128X128 || mbmi->sb_type == BLOCK_128X64)) ||
           ((fbr & 1) &&
            (mbmi->sb_type == BLOCK_128X128 || mbmi->sb_type == BLOCK_64X128)))
         continue;
 
-      int nhb = AOMMIN(MI_SIZE_64X64, cm->mi_cols - MI_SIZE_64X64 * fbc);
-      int nvb = AOMMIN(MI_SIZE_64X64, cm->mi_rows - MI_SIZE_64X64 * fbr);
+      int nhb = AOMMIN(MI_SIZE_64X64, mi_params->mi_cols - MI_SIZE_64X64 * fbc);
+      int nvb = AOMMIN(MI_SIZE_64X64, mi_params->mi_rows - MI_SIZE_64X64 * fbr);
       int hb_step = 1;
       int vb_step = 1;
       BLOCK_SIZE bs;
@@ -455,11 +460,13 @@
           mbmi->sb_type == BLOCK_64X128) {
         bs = mbmi->sb_type;
         if (bs == BLOCK_128X128 || bs == BLOCK_128X64) {
-          nhb = AOMMIN(MI_SIZE_128X128, cm->mi_cols - MI_SIZE_64X64 * fbc);
+          nhb =
+              AOMMIN(MI_SIZE_128X128, mi_params->mi_cols - MI_SIZE_64X64 * fbc);
           hb_step = 2;
         }
         if (bs == BLOCK_128X128 || bs == BLOCK_64X128) {
-          nvb = AOMMIN(MI_SIZE_128X128, cm->mi_rows - MI_SIZE_64X64 * fbr);
+          nvb =
+              AOMMIN(MI_SIZE_128X128, mi_params->mi_rows - MI_SIZE_64X64 * fbr);
           vb_step = 2;
         }
       } else {
@@ -467,7 +474,7 @@
       }
 
       const int cdef_count = av1_cdef_compute_sb_list(
-          cm, fbr * MI_SIZE_64X64, fbc * MI_SIZE_64X64, dlist, bs);
+          mi_params, fbr * MI_SIZE_64X64, fbc * MI_SIZE_64X64, dlist, bs);
 
       const int yoff = CDEF_VBORDER * (fbr != 0);
       const int xoff = CDEF_HBORDER * (fbc != 0);
@@ -504,7 +511,7 @@
         }
       }
       sb_index[sb_count++] =
-          MI_SIZE_64X64 * fbr * cm->mi_stride + MI_SIZE_64X64 * fbc;
+          MI_SIZE_64X64 * fbr * mi_params->mi_stride + MI_SIZE_64X64 * fbc;
     }
   }
 
@@ -555,7 +562,7 @@
         best_mse = curr;
       }
     }
-    cm->mi_grid_base[sb_index[i]]->cdef_strength = best_gi;
+    mi_params->mi_grid_base[sb_index[i]]->cdef_strength = best_gi;
   }
 
   if (fast) {
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 48a9d8b..2ed7206 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -2141,7 +2141,7 @@
       coded_to_superres_mi(mi_col + mi_wide, cm->superres_scale_denominator);
   const int mi_cols_sr = av1_pixels_to_mi(cm->superres_upscaled_width);
 
-  for (int row = mi_row; row < AOMMIN(mi_row + mi_high, cm->mi_rows);
+  for (int row = mi_row; row < AOMMIN(mi_row + mi_high, cm->mi_params.mi_rows);
        row += step) {
     for (int col = mi_col_sr; col < AOMMIN(mi_col_end_sr, mi_cols_sr);
          col += step) {
@@ -2281,8 +2281,10 @@
   int ref_match_found_in_above_nb = 0;
   int ref_match_found_in_left_nb = 0;
   if (prune_modes_based_on_tpl) {
-    ref_match_found_in_above_nb = find_ref_match_in_above_nbs(cm->mi_cols, xd);
-    ref_match_found_in_left_nb = find_ref_match_in_left_nbs(cm->mi_rows, xd);
+    ref_match_found_in_above_nb =
+        find_ref_match_in_above_nbs(cm->mi_params.mi_cols, xd);
+    ref_match_found_in_left_nb =
+        find_ref_match_in_left_nbs(cm->mi_params.mi_rows, xd);
   }
 
   // First, perform a simple translation search for each of the indices. If
diff --git a/av1/encoder/rdopt.h b/av1/encoder/rdopt.h
index b07f56c..821c485 100644
--- a/av1/encoder/rdopt.h
+++ b/av1/encoder/rdopt.h
@@ -134,7 +134,7 @@
 
 // This function will return number of mi's in a superblock.
 static INLINE int av1_get_sb_mi_size(const AV1_COMMON *const cm) {
-  const int mi_alloc_size_1d = mi_size_wide[cm->mi_alloc_bsize];
+  const int mi_alloc_size_1d = mi_size_wide[cm->mi_params.mi_alloc_bsize];
   int sb_mi_rows =
       (mi_size_wide[cm->seq_params.sb_size] + mi_alloc_size_1d - 1) /
       mi_alloc_size_1d;
diff --git a/av1/encoder/segmentation.c b/av1/encoder/segmentation.c
index d2b0ab0..c34c3fc 100644
--- a/av1/encoder/segmentation.c
+++ b/av1/encoder/segmentation.c
@@ -49,16 +49,15 @@
                        unsigned (*temporal_predictor_count)[2],
                        unsigned *t_unpred_seg_counts, int bw, int bh,
                        int mi_row, int mi_col) {
-  int segment_id;
-
-  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
+  if (mi_row >= mi_params->mi_rows || mi_col >= mi_params->mi_cols) return;
 
   xd->mi = mi;
-  segment_id = xd->mi[0]->segment_id;
-
-  set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols);
+  set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, mi_params->mi_rows,
+                 mi_params->mi_cols);
 
   // Count the number of hits on each segment with no prediction
+  const int segment_id = xd->mi[0]->segment_id;
   no_pred_segcounts[segment_id]++;
 
   // Temporal prediction not allowed on key frames
@@ -67,7 +66,8 @@
     // Test to see if the segment id matches the predicted value.
     const int pred_segment_id =
         cm->last_frame_seg_map
-            ? get_segment_id(cm, cm->last_frame_seg_map, bsize, mi_row, mi_col)
+            ? get_segment_id(mi_params, cm->last_frame_seg_map, bsize, mi_row,
+                             mi_col)
             : 0;
     const int pred_flag = pred_segment_id == segment_id;
     const int pred_context = av1_get_pred_context_seg_id(xd);
@@ -88,12 +88,13 @@
                           unsigned (*temporal_predictor_count)[2],
                           unsigned *t_unpred_seg_counts, int mi_row, int mi_col,
                           BLOCK_SIZE bsize) {
-  const int mis = cm->mi_stride;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
+  const int mis = mi_params->mi_stride;
   const int bs = mi_size_wide[bsize], hbs = bs / 2;
   PARTITION_TYPE partition;
   const int qbs = bs / 4;
 
-  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
+  if (mi_row >= mi_params->mi_rows || mi_col >= mi_params->mi_cols) return;
 
 #define CSEGS(cs_bw, cs_bh, cs_rowoff, cs_coloff)                              \
   count_segs(cm, xd, tile, mi + mis * (cs_rowoff) + (cs_coloff),               \
@@ -138,14 +139,14 @@
       CSEGS(bs, qbs, 0, 0);
       CSEGS(bs, qbs, qbs, 0);
       CSEGS(bs, qbs, 2 * qbs, 0);
-      if (mi_row + 3 * qbs < cm->mi_rows) CSEGS(bs, qbs, 3 * qbs, 0);
+      if (mi_row + 3 * qbs < mi_params->mi_rows) CSEGS(bs, qbs, 3 * qbs, 0);
       break;
 
     case PARTITION_VERT_4:
       CSEGS(qbs, bs, 0, 0);
       CSEGS(qbs, bs, 0, qbs);
       CSEGS(qbs, bs, 0, 2 * qbs);
-      if (mi_col + 3 * qbs < cm->mi_cols) CSEGS(qbs, bs, 0, 3 * qbs);
+      if (mi_col + 3 * qbs < mi_params->mi_cols) CSEGS(qbs, bs, 0, 3 * qbs);
       break;
 
     case PARTITION_SPLIT: {
@@ -189,11 +190,12 @@
       for (tile_col = 0; tile_col < cm->tiles.cols; tile_col++) {
         MB_MODE_INFO **mi_ptr;
         av1_tile_set_col(&tile_info, cm, tile_col);
-        mi_ptr = cm->mi_grid_base + tile_info.mi_row_start * cm->mi_stride +
+        mi_ptr = cm->mi_params.mi_grid_base +
+                 tile_info.mi_row_start * cm->mi_params.mi_stride +
                  tile_info.mi_col_start;
         for (mi_row = tile_info.mi_row_start; mi_row < tile_info.mi_row_end;
              mi_row += cm->seq_params.mib_size,
-            mi_ptr += cm->seq_params.mib_size * cm->mi_stride) {
+            mi_ptr += cm->seq_params.mib_size * cm->mi_params.mi_stride) {
           MB_MODE_INFO **mi = mi_ptr;
           for (mi_col = tile_info.mi_col_start; mi_col < tile_info.mi_col_end;
                mi_col += cm->seq_params.mib_size,
diff --git a/av1/encoder/svc_layercontext.c b/av1/encoder/svc_layercontext.c
index 1564e31..b72d8aa 100644
--- a/av1/encoder/svc_layercontext.c
+++ b/av1/encoder/svc_layercontext.c
@@ -24,8 +24,8 @@
   AV1_COMMON *const cm = &cpi->common;
   const AV1EncoderConfig *const oxcf = &cpi->oxcf;
   SVC *const svc = &cpi->svc;
-  int mi_rows = cpi->common.mi_rows;
-  int mi_cols = cpi->common.mi_cols;
+  int mi_rows = cpi->common.mi_params.mi_rows;
+  int mi_cols = cpi->common.mi_params.mi_cols;
   svc->base_framerate = 30.0;
   svc->current_superframe = 0;
 
diff --git a/av1/encoder/temporal_filter.c b/av1/encoder/temporal_filter.c
index af5ccdb..c0aaa41 100644
--- a/av1/encoder/temporal_filter.c
+++ b/av1/encoder/temporal_filter.c
@@ -962,12 +962,12 @@
       TF_ENABLE_PLANEWISE_STRATEGY && AOMMIN(frame_height, frame_width) >= 480;
   // Perform temporal filtering block by block.
   for (int mb_row = 0; mb_row < mb_rows; mb_row++) {
-    av1_set_mv_row_limits(&cpi->common, &mb->mv_limits, (mb_row << mi_h),
-                          (mb_height >> MI_SIZE_LOG2),
+    av1_set_mv_row_limits(&cpi->common.mi_params, &mb->mv_limits,
+                          (mb_row << mi_h), (mb_height >> MI_SIZE_LOG2),
                           cpi->oxcf.border_in_pixels);
     for (int mb_col = 0; mb_col < mb_cols; mb_col++) {
-      av1_set_mv_col_limits(&cpi->common, &mb->mv_limits, (mb_col << mi_w),
-                            (mb_width >> MI_SIZE_LOG2),
+      av1_set_mv_col_limits(&cpi->common.mi_params, &mb->mv_limits,
+                            (mb_col << mi_w), (mb_width >> MI_SIZE_LOG2),
                             cpi->oxcf.border_in_pixels);
       memset(accum, 0, num_planes * mb_pels * sizeof(accum[0]));
       memset(count, 0, num_planes * mb_pels * sizeof(count[0]));
diff --git a/av1/encoder/tokenize.c b/av1/encoder/tokenize.c
index c8fb128..eb57f88 100644
--- a/av1/encoder/tokenize.c
+++ b/av1/encoder/tokenize.c
@@ -187,7 +187,8 @@
   MACROBLOCKD *const xd = &x->e_mbd;
   const int mi_row = xd->mi_row;
   const int mi_col = xd->mi_col;
-  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
+  if (mi_row >= cm->mi_params.mi_rows || mi_col >= cm->mi_params.mi_cols)
+    return;
 
   const int num_planes = av1_num_planes(cm);
   MB_MODE_INFO *const mbmi = xd->mi[0];
diff --git a/av1/encoder/tpl_model.c b/av1/encoder/tpl_model.c
index ee0c496..4a35fa3 100644
--- a/av1/encoder/tpl_model.c
+++ b/av1/encoder/tpl_model.c
@@ -235,7 +235,7 @@
   const int mi_height = mi_size_high[bsize];
   set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
   set_mi_row_col(xd, &xd->tile, mi_row, mi_height, mi_col, mi_width,
-                 cm->mi_rows, cm->mi_cols);
+                 cm->mi_params.mi_rows, cm->mi_params.mi_cols);
   set_plane_n4(xd, mi_size_wide[bsize], mi_size_high[bsize],
                av1_num_planes(cm));
   xd->mi[0]->sb_type = bsize;
@@ -455,7 +455,7 @@
     for (int idx = 0; idx < mi_width; ++idx) {
       if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > idx &&
           (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > idy) {
-        xd->mi[idx + idy * cm->mi_stride] = xd->mi[0];
+        xd->mi[idx + idy * cm->mi_params.mi_stride] = xd->mi[0];
       }
     }
   }
@@ -677,6 +677,7 @@
                                              NULL, NULL, NULL };
 
   AV1_COMMON *cm = &cpi->common;
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
   struct scale_factors sf;
   int rdmult, idx;
   ThreadData *td = &cpi->td;
@@ -742,21 +743,22 @@
   tpl_frame->base_rdmult =
       av1_compute_rd_mult_based_on_qindex(cpi, pframe_qindex) / 6;
 
-  for (mi_row = 0; mi_row < cm->mi_rows; mi_row += mi_height) {
+  for (mi_row = 0; mi_row < mi_params->mi_rows; mi_row += mi_height) {
     // Motion estimation row boundary
-    av1_set_mv_row_limits(cm, &x->mv_limits, mi_row, mi_height,
+    av1_set_mv_row_limits(mi_params, &x->mv_limits, mi_row, mi_height,
                           cpi->oxcf.border_in_pixels);
     xd->mb_to_top_edge = -GET_MV_SUBPEL(mi_row * MI_SIZE);
     xd->mb_to_bottom_edge =
-        GET_MV_SUBPEL((cm->mi_rows - mi_height - mi_row) * MI_SIZE);
-    for (mi_col = 0; mi_col < cm->mi_cols; mi_col += mi_width) {
+        GET_MV_SUBPEL((mi_params->mi_rows - mi_height - mi_row) * MI_SIZE);
+    for (mi_col = 0; mi_col < mi_params->mi_cols; mi_col += mi_width) {
       TplDepStats tpl_stats;
 
       // Motion estimation column boundary
-      av1_set_mv_col_limits(cm, &x->mv_limits, mi_col, mi_width,
+      av1_set_mv_col_limits(mi_params, &x->mv_limits, mi_col, mi_width,
                             cpi->oxcf.border_in_pixels);
       xd->mb_to_left_edge = -GET_MV_SUBPEL(mi_col * MI_SIZE);
-      xd->mb_to_right_edge = GET_MV_SUBPEL(cm->mi_cols - mi_width - mi_col);
+      xd->mb_to_right_edge =
+          GET_MV_SUBPEL(mi_params->mi_cols - mi_width - mi_col);
       mode_estimation(cpi, x, xd, &sf, frame_idx, mi_row, mi_col, bsize,
                       tx_size, ref_frame, src_frame, &tpl_stats);
 
@@ -779,8 +781,8 @@
   const int mi_height = mi_size_high[bsize];
   const int mi_width = mi_size_wide[bsize];
 
-  for (int mi_row = 0; mi_row < cm->mi_rows; mi_row += mi_height) {
-    for (int mi_col = 0; mi_col < cm->mi_cols; mi_col += mi_width) {
+  for (int mi_row = 0; mi_row < cm->mi_params.mi_rows; mi_row += mi_height) {
+    for (int mi_col = 0; mi_col < cm->mi_params.mi_cols; mi_col += mi_width) {
       if (frame_idx) {
         tpl_model_update(cpi, cpi->tpl_frame, tpl_frame->tpl_stats_ptr, mi_row,
                          mi_col, bsize, frame_idx);
@@ -1042,7 +1044,7 @@
     const int step = 1 << cpi->tpl_stats_block_mis_log2;
     const int mi_cols_sr = av1_pixels_to_mi(cm->superres_upscaled_width);
 
-    for (int row = 0; row < cm->mi_rows; row += step) {
+    for (int row = 0; row < cm->mi_params.mi_rows; row += step) {
       for (int col = 0; col < mi_cols_sr; col += step) {
         TplDepStats *this_stats =
             &tpl_stats[av1_tpl_ptr_pos(cpi, row, col, tpl_stride)];
@@ -1083,7 +1085,7 @@
   const int num_mi_w = mi_size_wide[block_size];
   const int num_mi_h = mi_size_high[block_size];
   const int num_cols = (mi_cols_sr + num_mi_w - 1) / num_mi_w;
-  const int num_rows = (cm->mi_rows + num_mi_h - 1) / num_mi_h;
+  const int num_rows = (cm->mi_params.mi_rows + num_mi_h - 1) / num_mi_h;
   const double c = 1.2;
   const int step = 1 << cpi->tpl_stats_block_mis_log2;
 
@@ -1098,7 +1100,7 @@
            mi_row += step) {
         for (int mi_col = col * num_mi_w; mi_col < (col + 1) * num_mi_w;
              mi_col += step) {
-          if (mi_row >= cm->mi_rows || mi_col >= mi_cols_sr) continue;
+          if (mi_row >= cm->mi_params.mi_rows || mi_col >= mi_cols_sr) continue;
           const TplDepStats *this_stats =
               &tpl_stats[av1_tpl_ptr_pos(cpi, mi_row, mi_col, tpl_stride)];
           int64_t mc_dep_delta =
@@ -1134,8 +1136,8 @@
   const int bsize_base = BLOCK_16X16;
   const int num_mi_w = mi_size_wide[bsize_base];
   const int num_mi_h = mi_size_high[bsize_base];
-  const int num_cols = (cm->mi_cols + num_mi_w - 1) / num_mi_w;
-  const int num_rows = (cm->mi_rows + num_mi_h - 1) / num_mi_h;
+  const int num_cols = (cm->mi_params.mi_cols + num_mi_w - 1) / num_mi_w;
+  const int num_rows = (cm->mi_params.mi_rows + num_mi_h - 1) / num_mi_h;
   const int num_bcols = (mi_size_wide[sb_size] + num_mi_w - 1) / num_mi_w;
   const int num_brows = (mi_size_high[sb_size] + num_mi_h - 1) / num_mi_h;
   int row, col;
diff --git a/av1/encoder/tune_vmaf.c b/av1/encoder/tune_vmaf.c
index 5aecb4e..6a5ea75 100644
--- a/av1/encoder/tune_vmaf.c
+++ b/av1/encoder/tune_vmaf.c
@@ -552,8 +552,8 @@
   const int bsize_base = BLOCK_64X64;
   const int num_mi_w = mi_size_wide[bsize_base];
   const int num_mi_h = mi_size_high[bsize_base];
-  const int num_cols = (cm->mi_cols + num_mi_w - 1) / num_mi_w;
-  const int num_rows = (cm->mi_rows + num_mi_h - 1) / num_mi_h;
+  const int num_cols = (cm->mi_params.mi_cols + num_mi_w - 1) / num_mi_w;
+  const int num_rows = (cm->mi_params.mi_rows + num_mi_h - 1) / num_mi_h;
   const int num_bcols = (mi_size_wide[bsize] + num_mi_w - 1) / num_mi_w;
   const int num_brows = (mi_size_high[bsize] + num_mi_h - 1) / num_mi_h;
   int row, col;
diff --git a/av1/encoder/var_based_part.c b/av1/encoder/var_based_part.c
index 90e9413..d9e4d1a 100644
--- a/av1/encoder/var_based_part.c
+++ b/av1/encoder/var_based_part.c
@@ -173,7 +173,8 @@
 static AOM_INLINE void set_block_size(AV1_COMP *const cpi, MACROBLOCK *const x,
                                       MACROBLOCKD *const xd, int mi_row,
                                       int mi_col, BLOCK_SIZE bsize) {
-  if (cpi->common.mi_cols > mi_col && cpi->common.mi_rows > mi_row) {
+  if (cpi->common.mi_params.mi_cols > mi_col &&
+      cpi->common.mi_params.mi_rows > mi_row) {
     set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
     xd->mi[0]->sb_type = bsize;
   }
@@ -452,12 +453,9 @@
 
 // Set temporal variance low flag for superblock 64x64.
 // Only first 25 in the array are used in this case.
-static AOM_INLINE void set_low_temp_var_flag_64x64(AV1_COMP *cpi, MACROBLOCK *x,
-                                                   MACROBLOCKD *xd, v64x64 *vt,
-                                                   int64_t thresholds[],
-                                                   int mi_col, int mi_row) {
-  AV1_COMMON *const cm = &cpi->common;
-
+static AOM_INLINE void set_low_temp_var_flag_64x64(
+    CommonModeInfoParams *mi_params, MACROBLOCK *x, MACROBLOCKD *xd, v64x64 *vt,
+    const int64_t thresholds[], int mi_col, int mi_row) {
   if (xd->mi[0]->sb_type == BLOCK_64X64) {
     if ((vt->part_variances).none.variance < (thresholds[0] >> 1))
       x->variance_low[0] = 1;
@@ -475,11 +473,11 @@
     static const int idx[4][2] = { { 0, 0 }, { 0, 8 }, { 8, 0 }, { 8, 8 } };
     for (int i = 0; i < 4; i++) {
       const int idx_str =
-          cm->mi_stride * (mi_row + idx[i][0]) + mi_col + idx[i][1];
-      MB_MODE_INFO **this_mi = cm->mi_grid_base + idx_str;
+          mi_params->mi_stride * (mi_row + idx[i][0]) + mi_col + idx[i][1];
+      MB_MODE_INFO **this_mi = mi_params->mi_grid_base + idx_str;
 
-      if (cm->mi_cols <= mi_col + idx[i][1] ||
-          cm->mi_rows <= mi_row + idx[i][0])
+      if (mi_params->mi_cols <= mi_col + idx[i][1] ||
+          mi_params->mi_rows <= mi_row + idx[i][0])
         continue;
 
       if (*this_mi == NULL) continue;
@@ -506,10 +504,8 @@
 }
 
 static AOM_INLINE void set_low_temp_var_flag_128x128(
-    AV1_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd, v128x128 *vt,
-    int64_t thresholds[], int mi_col, int mi_row) {
-  AV1_COMMON *const cm = &cpi->common;
-
+    CommonModeInfoParams *mi_params, MACROBLOCK *x, MACROBLOCKD *xd,
+    v128x128 *vt, const int64_t thresholds[], int mi_col, int mi_row) {
   if (xd->mi[0]->sb_type == BLOCK_128X128) {
     if (vt->part_variances.none.variance < (thresholds[0] >> 1))
       x->variance_low[0] = 1;
@@ -530,11 +526,11 @@
     static const int idx32[4][2] = { { 0, 0 }, { 0, 8 }, { 8, 0 }, { 8, 8 } };
     for (int i = 0; i < 4; i++) {
       const int idx_str =
-          cm->mi_stride * (mi_row + idx64[i][0]) + mi_col + idx64[i][1];
-      MB_MODE_INFO **mi_64 = cm->mi_grid_base + idx_str;
+          mi_params->mi_stride * (mi_row + idx64[i][0]) + mi_col + idx64[i][1];
+      MB_MODE_INFO **mi_64 = mi_params->mi_grid_base + idx_str;
       if (*mi_64 == NULL) continue;
-      if (cm->mi_cols <= mi_col + idx64[i][1] ||
-          cm->mi_rows <= mi_row + idx64[i][0])
+      if (mi_params->mi_cols <= mi_col + idx64[i][1] ||
+          mi_params->mi_rows <= mi_row + idx64[i][0])
         continue;
       const int64_t threshold_64x64 = (5 * thresholds[1]) >> 3;
       if ((*mi_64)->sb_type == BLOCK_64X64) {
@@ -552,12 +548,12 @@
             x->variance_low[17 + (i << 1) + j] = 1;
       } else {
         for (int k = 0; k < 4; k++) {
-          const int idx_str1 = cm->mi_stride * idx32[k][0] + idx32[k][1];
-          MB_MODE_INFO **mi_32 = cm->mi_grid_base + idx_str + idx_str1;
+          const int idx_str1 = mi_params->mi_stride * idx32[k][0] + idx32[k][1];
+          MB_MODE_INFO **mi_32 = mi_params->mi_grid_base + idx_str + idx_str1;
           if (*mi_32 == NULL) continue;
 
-          if (cm->mi_cols <= mi_col + idx64[i][1] + idx32[k][1] ||
-              cm->mi_rows <= mi_row + idx64[i][0] + idx32[k][0])
+          if (mi_params->mi_cols <= mi_col + idx64[i][1] + idx32[k][1] ||
+              mi_params->mi_rows <= mi_row + idx64[i][0] + idx32[k][0])
             continue;
           const int64_t threshold_32x32 = (5 * thresholds[2]) >> 3;
           if ((*mi_32)->sb_type == BLOCK_32X32) {
@@ -604,10 +600,11 @@
         xd->mi[0]->mv[0].as_mv.row > -mv_thr))) {
     const int is_small_sb = (cm->seq_params.sb_size == BLOCK_64X64);
     if (is_small_sb)
-      set_low_temp_var_flag_64x64(cpi, x, xd, &(vt->split[0]), thresholds,
-                                  mi_col, mi_row);
+      set_low_temp_var_flag_64x64(&cm->mi_params, x, xd, &(vt->split[0]),
+                                  thresholds, mi_col, mi_row);
     else
-      set_low_temp_var_flag_128x128(cpi, x, xd, vt, thresholds, mi_col, mi_row);
+      set_low_temp_var_flag_128x128(&cm->mi_params, x, xd, vt, thresholds,
+                                    mi_col, mi_row);
   }
 }
 
@@ -830,15 +827,16 @@
     // If the y_sad is very small, take 64x64 as partition and exit.
     // Don't check on boosted segment for now, as 64x64 is suppressed there.
 #if 0
-        if (segment_id == CR_SEGMENT_ID_BASE && y_sad < cpi->vbp_threshold_sad)
-       { const int block_width = num_8x8_blocks_wide_lookup[BLOCK_64X64]; const
-       int block_height = num_8x8_blocks_high_lookup[BLOCK_64X64]; 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_128X128);
-            x->variance_low[0] = 1;
-            return 0;
-          }
-        }
+    if (segment_id == CR_SEGMENT_ID_BASE && y_sad < cpi->vbp_threshold_sad) {
+      const int block_width = num_8x8_blocks_wide_lookup[BLOCK_64X64];
+      const int block_height = num_8x8_blocks_high_lookup[BLOCK_64X64];
+      if (mi_col + block_width / 2 < cm->mi_params.mi_cols &&
+          mi_row + block_height / 2 < cm->mi_params.mi_rows) {
+        set_block_size(cpi, x, xd, mi_row, mi_col, BLOCK_128X128);
+        x->variance_low[0] = 1;
+        return 0;
+      }
+    }
 #endif
   } else {
     d = AV1_VAR_OFFS;