Fix nightly test failures (issue #131) in CCTX

Bug fix for several ERP related issues in CCTX (#131):
1. Use get_mb_plane_block_size instead of get_plane_block_size
2. Chroma coding block area can be implicitly derived before ERP
   was introduced. Now it is obtained using the functions introduced
   by ERP

Neutral or minor gains expected with and without ERP.

STATS_CHANGED
diff --git a/av1/common/blockd.h b/av1/common/blockd.h
index d4acc31..0bba2b5 100644
--- a/av1/common/blockd.h
+++ b/av1/common/blockd.h
@@ -2625,10 +2625,17 @@
 }
 #endif
 
-// When the current block is sub 8x8, obtain amounts of offset to its parent
-// 8x8 block. Otherwise set the offsets to 0.
-static INLINE void get_offsets_to_8x8(MACROBLOCKD *const xd, TX_SIZE tx_size,
-                                      int *row_offset, int *col_offset) {
+// When the current block is chroma reference, obtain amounts of mi offsets to
+// its corresponding luma region. Otherwise set the offsets to 0.
+static INLINE void get_chroma_mi_offsets(MACROBLOCKD *const xd,
+#if !CONFIG_EXT_RECUR_PARTITIONS
+                                         TX_SIZE tx_size,
+#endif  // !CONFIG_EXT_RECUR_PARTITIONS
+                                         int *row_offset, int *col_offset) {
+#if CONFIG_EXT_RECUR_PARTITIONS
+  *row_offset = xd->mi_row - xd->mi[0]->chroma_ref_info.mi_row_chroma_base;
+  *col_offset = xd->mi_col - xd->mi[0]->chroma_ref_info.mi_col_chroma_base;
+#else
   const struct macroblockd_plane *const pd = &xd->plane[AOM_PLANE_U];
   const int ss_x = pd->subsampling_x;
   const int ss_y = pd->subsampling_y;
@@ -2636,6 +2643,7 @@
       (xd->mi_row & 0x01) && (tx_size_high_unit[tx_size] & 0x01) && ss_y;
   *col_offset =
       (xd->mi_col & 0x01) && (tx_size_wide_unit[tx_size] & 0x01) && ss_x;
+#endif  // CONFIG_EXT_RECUR_PARTITIONS
 }
 
 static INLINE void update_cctx_array(MACROBLOCKD *const xd, int blk_row,
diff --git a/av1/common/pred_common.h b/av1/common/pred_common.h
index ff6f162..8bc8e4c 100644
--- a/av1/common/pred_common.h
+++ b/av1/common/pred_common.h
@@ -377,23 +377,30 @@
 
 static INLINE void get_above_and_left_cctx_type(const AV1_COMMON *cm,
                                                 const MACROBLOCKD *xd,
+#if !CONFIG_EXT_RECUR_PARTITIONS
                                                 TX_SIZE tx_size,
+#endif  // !CONFIG_EXT_RECUR_PARTITIONS
                                                 int *above_cctx,
                                                 int *left_cctx) {
+  const CommonModeInfoParams *const mi_params = &cm->mi_params;
+  const int stride = mi_params->mi_stride;
+
+#if CONFIG_EXT_RECUR_PARTITIONS
+  const int mi_grid_idx =
+      get_mi_grid_idx(mi_params, xd->mi[0]->chroma_ref_info.mi_row_chroma_base,
+                      xd->mi[0]->chroma_ref_info.mi_col_chroma_base);
+#else
   const int ss_x = xd->plane[AOM_PLANE_U].subsampling_x;
   const int ss_y = xd->plane[AOM_PLANE_U].subsampling_y;
   const int txh = tx_size_high_unit[tx_size];
   const int txw = tx_size_wide_unit[tx_size];
-
-  const CommonModeInfoParams *const mi_params = &cm->mi_params;
-  const int stride = mi_params->mi_stride;
-
   // Offsets are needed for sub 8x8 blocks to reach the top left corner of the
   // current block where the current cctx_type is applied
   const int mi_row_offset = (xd->mi_row & 0x01) && (txh & 0x01) && ss_y;
   const int mi_col_offset = (xd->mi_col & 0x01) && (txw & 0x01) && ss_x;
   const int mi_grid_idx = get_mi_grid_idx(mi_params, xd->mi_row - mi_row_offset,
                                           xd->mi_col - mi_col_offset);
+#endif  // CONFIG_EXT_RECUR_PARTITIONS
   CctxType *const cur_cctx_ptr = mi_params->cctx_type_map + mi_grid_idx;
   *above_cctx = xd->chroma_up_available ? (int)cur_cctx_ptr[-stride] : -1;
   *left_cctx = xd->chroma_left_available ? (int)cur_cctx_ptr[-1] : -1;
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index bc43148..7496c05 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -1497,9 +1497,10 @@
       const struct macroblockd_plane *const pd = &xd->plane[AOM_PLANE_U];
       const int ss_x = pd->subsampling_x;
       const int ss_y = pd->subsampling_y;
-      const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, ss_x, ss_y);
+      const BLOCK_SIZE uv_plane_bsize =
+          get_mb_plane_block_size(xd, mbmi, AOM_PLANE_U, ss_x, ss_y);
       const TX_SIZE max_tx_size =
-          get_vartx_max_txsize(xd, plane_bsize, AOM_PLANE_U);
+          get_vartx_max_txsize(xd, uv_plane_bsize, AOM_PLANE_U);
       const int max_blocks_wide = max_block_wide(xd, bsize, 0);
       const int max_blocks_high = max_block_high(xd, bsize, 0);
       const BLOCK_SIZE max_unit_bsize = BLOCK_64X64;
@@ -1508,7 +1509,11 @@
       for (int row = 0; row < max_blocks_high; row += mu_blocks_high) {
         for (int col = 0; col < max_blocks_wide; col += mu_blocks_wide) {
           int row_offset, col_offset;
-          get_offsets_to_8x8(xd, max_tx_size, &row_offset, &col_offset);
+#if CONFIG_EXT_RECUR_PARTITIONS
+          get_chroma_mi_offsets(xd, &row_offset, &col_offset);
+#else
+          get_chroma_mi_offsets(xd, max_tx_size, &row_offset, &col_offset);
+#endif  // CONFIG_EXT_RECUR_PARTITIONS
           update_cctx_array(xd, 0, 0, row_offset, col_offset, max_tx_size,
                             CCTX_NONE);
         }
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index f9bcd37..51ed4f1 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -1234,7 +1234,11 @@
   // parent block area. Then apply cctx type update to this area w.r.t the
   // offsets derived
   int row_offset, col_offset;
-  get_offsets_to_8x8(xd, tx_size, &row_offset, &col_offset);
+#if CONFIG_EXT_RECUR_PARTITIONS
+  get_chroma_mi_offsets(xd, &row_offset, &col_offset);
+#else
+  get_chroma_mi_offsets(xd, tx_size, &row_offset, &col_offset);
+#endif  // CONFIG_EXT_RECUR_PARTITIONS
   update_cctx_array(xd, blk_row, blk_col, row_offset, col_offset, tx_size,
                     CCTX_NONE);
 
@@ -1251,7 +1255,11 @@
   FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
   const TX_SIZE square_tx_size = txsize_sqr_map[tx_size];
   int above_cctx, left_cctx;
+#if CONFIG_EXT_RECUR_PARTITIONS
+  get_above_and_left_cctx_type(cm, xd, &above_cctx, &left_cctx);
+#else
   get_above_and_left_cctx_type(cm, xd, tx_size, &above_cctx, &left_cctx);
+#endif  // CONFIG_EXT_RECUR_PARTITIONS
   const int cctx_ctx = get_cctx_context(xd, &above_cctx, &left_cctx);
   cctx_type = aom_read_symbol(
       r, ec_ctx->cctx_type_cdf[square_tx_size][cctx_ctx], CCTX_TYPES, ACCT_STR);
diff --git a/av1/decoder/decodetxb.c b/av1/decoder/decodetxb.c
index 3eb9512..cd03300 100644
--- a/av1/decoder/decodetxb.c
+++ b/av1/decoder/decodetxb.c
@@ -285,7 +285,11 @@
       av1_read_cctx_type(cm, xd, blk_row, blk_col, tx_size, r);
     } else {
       int row_offset, col_offset;
-      get_offsets_to_8x8(xd, tx_size, &row_offset, &col_offset);
+#if CONFIG_EXT_RECUR_PARTITIONS
+      get_chroma_mi_offsets(xd, &row_offset, &col_offset);
+#else
+      get_chroma_mi_offsets(xd, tx_size, &row_offset, &col_offset);
+#endif  // CONFIG_EXT_RECUR_PARTITIONS
       update_cctx_array(xd, blk_row, blk_col, row_offset, col_offset, tx_size,
                         CCTX_NONE);
     }
@@ -474,7 +478,11 @@
       av1_read_cctx_type(cm, xd, blk_row, blk_col, tx_size, r);
     } else {
       int row_offset, col_offset;
-      get_offsets_to_8x8(xd, tx_size, &row_offset, &col_offset);
+#if CONFIG_EXT_RECUR_PARTITIONS
+      get_chroma_mi_offsets(xd, &row_offset, &col_offset);
+#else
+      get_chroma_mi_offsets(xd, tx_size, &row_offset, &col_offset);
+#endif  // CONFIG_EXT_RECUR_PARTITIONS
       update_cctx_array(xd, blk_row, blk_col, row_offset, col_offset, tx_size,
                         CCTX_NONE);
     }
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index e6f4ce5..77ad982 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -1429,7 +1429,11 @@
     FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
     const TX_SIZE square_tx_size = txsize_sqr_map[tx_size];
     int above_cctx, left_cctx;
+#if CONFIG_EXT_RECUR_PARTITIONS
+    get_above_and_left_cctx_type(cm, xd, &above_cctx, &left_cctx);
+#else
     get_above_and_left_cctx_type(cm, xd, tx_size, &above_cctx, &left_cctx);
+#endif  // CONFIG_EXT_RECUR_PARTITIONS
     const int cctx_ctx = get_cctx_context(xd, &above_cctx, &left_cctx);
     aom_write_symbol(w, cctx_type,
                      ec_ctx->cctx_type_cdf[square_tx_size][cctx_ctx],
@@ -2695,11 +2699,15 @@
   if (mbmi->skip_txfm[xd->tree_type == CHROMA_PART] &&
       xd->tree_type != LUMA_PART && xd->is_chroma_ref) {
     struct macroblockd_plane *const pd = &xd->plane[AOM_PLANE_U];
-    const BLOCK_SIZE uv_bsize =
-        get_plane_block_size(bsize, pd->subsampling_x, pd->subsampling_y);
+    const BLOCK_SIZE uv_bsize = get_mb_plane_block_size(
+        xd, mbmi, AOM_PLANE_U, pd->subsampling_x, pd->subsampling_y);
     const TX_SIZE uv_txsize = max_txsize_rect_lookup[uv_bsize];
     int row_offset, col_offset;
-    get_offsets_to_8x8(xd, uv_txsize, &row_offset, &col_offset);
+#if CONFIG_EXT_RECUR_PARTITIONS
+    get_chroma_mi_offsets(xd, &row_offset, &col_offset);
+#else
+    get_chroma_mi_offsets(xd, uv_txsize, &row_offset, &col_offset);
+#endif  // CONFIG_EXT_RECUR_PARTITIONS
     update_cctx_array(xd, 0, 0, row_offset, col_offset, uv_txsize, CCTX_NONE);
   }
 #endif  // CONFIG_CROSS_CHROMA_TX
diff --git a/av1/encoder/encodeframe_utils.c b/av1/encoder/encodeframe_utils.c
index f7e10b3..0925115 100644
--- a/av1/encoder/encodeframe_utils.c
+++ b/av1/encoder/encodeframe_utils.c
@@ -264,16 +264,27 @@
 #if CONFIG_CROSS_CHROMA_TX
   if (xd->tree_type != LUMA_PART && xd->is_chroma_ref) {
     xd->cctx_type_map = ctx->cctx_type_map;
-    xd->tx_type_map_stride = mi_size_wide[bsize];
+#if CONFIG_EXT_RECUR_PARTITIONS
+    const BLOCK_SIZE chroma_bsize = get_bsize_base(xd, mi, AOM_PLANE_U);
+    xd->tx_type_map_stride = mi_size_wide[chroma_bsize];
+    const int chroma_bw = mi_size_wide[chroma_bsize];
+    const int chroma_bh = mi_size_high[chroma_bsize];
+    const int grid_idx =
+        get_mi_grid_idx(mi_params, mi->chroma_ref_info.mi_row_chroma_base,
+                        mi->chroma_ref_info.mi_col_chroma_base);
+#else
     // If this block is sub 8x8 in luma, derive the parent >= 8x8 block area,
     // then update its corresponding chroma area in cctx_type_map to the
     // current cctx type
+    xd->tx_type_map_stride = mi_size_wide[bsize];
     const int ss_x = pd[AOM_PLANE_U].subsampling_x;
     const int ss_y = pd[AOM_PLANE_U].subsampling_y;
     const int mi_row_offset = (mi_row & 0x01) && (bh & 0x01) && ss_y;
     const int mi_col_offset = (mi_col & 0x01) && (bw & 0x01) && ss_x;
     const int grid_idx = get_mi_grid_idx(mi_params, mi_row - mi_row_offset,
                                          mi_col - mi_col_offset);
+#endif  // CONFIG_EXT_RECUR_PARTITIONS
+
     CctxType *const cctx_type_map = mi_params->cctx_type_map + grid_idx;
     const int mi_stride = mi_params->mi_stride;
     const int allow_cctx = is_cctx_allowed(cm, xd);
@@ -281,10 +292,17 @@
     CctxType cur_cctx_type = (txfm_info->skip_txfm || !allow_cctx)
                                  ? CCTX_NONE
                                  : xd->cctx_type_map[0];
+#if CONFIG_EXT_RECUR_PARTITIONS
+    for (int blk_row = 0; blk_row < chroma_bh; ++blk_row) {
+      memset(&cctx_type_map[blk_row * mi_stride], cur_cctx_type,
+             chroma_bw * sizeof(cctx_type_map[0]));
+    }
+#else
     for (int blk_row = 0; blk_row < (mi_row_offset ? 2 : bh); ++blk_row) {
       memset(&cctx_type_map[blk_row * mi_stride], cur_cctx_type,
              (mi_col_offset ? 2 : bw) * sizeof(cctx_type_map[0]));
     }
+#endif  // CONFIG_EXT_RECUR_PARTITIONS
     if (!dry_run) {
       xd->cctx_type_map = cctx_type_map;
       xd->tx_type_map_stride = mi_stride;
diff --git a/av1/encoder/encodemb.c b/av1/encoder/encodemb.c
index 931306a..f04dfe9 100644
--- a/av1/encoder/encodemb.c
+++ b/av1/encoder/encodemb.c
@@ -1091,8 +1091,8 @@
   for (int plane = plane_start; plane < plane_end; ++plane) {
     const struct macroblockd_plane *const pd = &xd->plane[plane];
     if (plane && !xd->is_chroma_ref) break;
-    const BLOCK_SIZE plane_bsize =
-        get_plane_block_size(bsize, pd->subsampling_x, pd->subsampling_y);
+    const BLOCK_SIZE plane_bsize = get_mb_plane_block_size(
+        xd, mbmi, plane, pd->subsampling_x, pd->subsampling_y);
     av1_subtract_plane(x, plane_bsize, plane);
   }
 #endif  // CONFIG_CROSS_CHROMA_TX
@@ -1561,7 +1561,12 @@
     cpi, x,  NULL,    &(xd->mi[0]->skip_txfm[xd->tree_type == CHROMA_PART]),
     ta,  tl, dry_run, enable_optimize_b
   };
-  const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, ss_x, ss_y);
+  const BLOCK_SIZE plane_bsize =
+      get_mb_plane_block_size(xd, xd->mi[0], AOM_PLANE_U, ss_x, ss_y);
+#if !CONFIG_EXT_RECUR_PARTITIONS
+  assert(plane_bsize == get_plane_block_size(bsize, ss_x, ss_y));
+#endif  // !CONFIG_EXT_RECUR_PARTITIONS
+  (void)bsize;
   if (enable_optimize_b) {
     av1_get_entropy_contexts(plane_bsize, pd_u, ta, tl);
     av1_get_entropy_contexts(plane_bsize, pd_v, &ta[MAX_MIB_SIZE],
diff --git a/av1/encoder/encodetxb.c b/av1/encoder/encodetxb.c
index 80b914f..710f664 100644
--- a/av1/encoder/encodetxb.c
+++ b/av1/encoder/encodetxb.c
@@ -1266,7 +1266,11 @@
       is_cctx_allowed(cm, xd)) {
     const TX_SIZE square_tx_size = txsize_sqr_map[tx_size];
     int above_cctx, left_cctx;
+#if CONFIG_EXT_RECUR_PARTITIONS
+    get_above_and_left_cctx_type(cm, xd, &above_cctx, &left_cctx);
+#else
     get_above_and_left_cctx_type(cm, xd, tx_size, &above_cctx, &left_cctx);
+#endif  // CONFIG_EXT_RECUR_PARTITIONS
     const int cctx_ctx = get_cctx_context(xd, &above_cctx, &left_cctx);
     return x->mode_costs.cctx_type_cost[square_tx_size][cctx_ctx][cctx_type];
   } else {
@@ -3433,7 +3437,11 @@
       !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
     const CctxType cctx_type = av1_get_cctx_type(xd, blk_row, blk_col);
     int above_cctx, left_cctx;
+#if CONFIG_EXT_RECUR_PARTITIONS
+    get_above_and_left_cctx_type(cm, xd, &above_cctx, &left_cctx);
+#else
     get_above_and_left_cctx_type(cm, xd, tx_size, &above_cctx, &left_cctx);
+#endif  // CONFIG_EXT_RECUR_PARTITIONS
     const int cctx_ctx = get_cctx_context(xd, &above_cctx, &left_cctx);
     if (allow_update_cdf)
       update_cdf(fc->cctx_type_cdf[txsize_sqr_map[tx_size]][cctx_ctx],