Rework sub8x8 chroma reference check to support non-420 format

Make is_chroma_reference() account for all the YUV420, 444, and
422 formats.

Change-Id: Ia87e51894493dcea86843194a34e5de05799248a
diff --git a/av1/common/blockd.c b/av1/common/blockd.c
index 8bc1291..4eb6f01 100644
--- a/av1/common/blockd.c
+++ b/av1/common/blockd.c
@@ -165,7 +165,9 @@
 
   for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
 #if CONFIG_CB4X4
-    if (bsize < BLOCK_8X8 && plane && !is_chroma_reference(mi_row, mi_col))
+    if (!is_chroma_reference(mi_row, mi_col, bsize,
+                             xd->plane[plane].subsampling_x,
+                             xd->plane[plane].subsampling_y))
       continue;
 #else
     (void)mi_row;
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index 67a587b..f5558b2 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -722,11 +722,19 @@
 }
 
 #if CONFIG_CB4X4
-static INLINE int is_chroma_reference(const int mi_row, const int mi_col) {
+static INLINE int is_chroma_reference(const int mi_row, const int mi_col,
+                                      const BLOCK_SIZE bsize,
+                                      const int subsampling_x,
+                                      const int subsampling_y) {
 #if CONFIG_CHROMA_2X2
   return 1;
 #endif
-  return !((mi_row & 0x01) || (mi_col & 0x01));
+  int ref_pos = !(((mi_row & 0x01) && subsampling_y) ||
+                  ((mi_col & 0x01) && subsampling_x));
+
+  if (bsize >= BLOCK_8X8) ref_pos = 1;
+
+  return ref_pos;
 }
 #endif
 
diff --git a/av1/common/reconinter.c b/av1/common/reconinter.c
index 7e16e29..232e137 100644
--- a/av1/common/reconinter.c
+++ b/av1/common/reconinter.c
@@ -1198,7 +1198,8 @@
     const int bh = pd->height;
 
 #if CONFIG_CB4X4
-    if (bsize < BLOCK_8X8 && plane && !is_chroma_reference(mi_row, mi_col))
+    if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x,
+                             pd->subsampling_y))
       continue;
 #endif
 
diff --git a/av1/common/reconintra.c b/av1/common/reconintra.c
index 9f59fc1..d3f5454 100644
--- a/av1/common/reconintra.c
+++ b/av1/common/reconintra.c
@@ -2182,7 +2182,14 @@
 
 #if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
   // force 4x4 chroma component block size.
-  if (plane && bsize < BLOCK_8X8) bsize = BLOCK_8X8;
+  if (plane && bsize < BLOCK_8X8) {
+    if (pd->subsampling_x == 1 && pd->subsampling_y == 1)
+      bsize = BLOCK_8X8;
+    else if (pd->subsampling_x == 1)
+      bsize = BLOCK_8X4;
+    else if (pd->subsampling_y == 1)
+      bsize = BLOCK_4X8;
+  }
 #endif
 
   const int have_right =
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index c726483..a209d6d 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -1684,7 +1684,8 @@
       const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
       const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
 #if CONFIG_CB4X4
-      if (bsize < BLOCK_8X8 && plane && !is_chroma_reference(mi_row, mi_col))
+      if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x,
+                               pd->subsampling_y))
         continue;
 #endif
 
@@ -1779,7 +1780,8 @@
         int row, col;
 
 #if CONFIG_CB4X4
-        if (bsize < BLOCK_8X8 && plane && !is_chroma_reference(mi_row, mi_col))
+        if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x,
+                                 pd->subsampling_y))
           continue;
 #endif
 
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index 001694d..3011ecc 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -968,7 +968,8 @@
 #endif
 
 #if CONFIG_CB4X4
-  if (bsize >= BLOCK_8X8 || is_chroma_reference(mi_row, mi_col))
+  if (is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
+                          xd->plane[1].subsampling_y))
     mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode);
 #else
   mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode);
@@ -1299,7 +1300,8 @@
 #endif
 
 #if CONFIG_CB4X4
-  if (bsize >= BLOCK_8X8 || is_chroma_reference(mi_row, mi_col))
+  if (is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
+                          xd->plane[1].subsampling_y))
     mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode);
 #else
   mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode);
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 68d68a7..fe1a9e9 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -1692,7 +1692,8 @@
       }
     }
 #if CONFIG_CB4X4
-    if (bsize >= BLOCK_8X8 || is_chroma_reference(mi_row, mi_col))
+    if (is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
+                            xd->plane[1].subsampling_y))
       write_intra_uv_mode(ec_ctx, mbmi->uv_mode, mode, w);
 #else  // !CONFIG_CB4X4
     write_intra_uv_mode(ec_ctx, mbmi->uv_mode, mode, w);
@@ -2042,7 +2043,8 @@
   }
 
 #if CONFIG_CB4X4
-  if (bsize >= BLOCK_8X8 || is_chroma_reference(mi_row, mi_col))
+  if (is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
+                          xd->plane[1].subsampling_y))
     write_intra_uv_mode(ec_ctx, mbmi->uv_mode, mbmi->mode, w);
 #else  // !CONFIG_CB4X4
   write_intra_uv_mode(ec_ctx, mbmi->uv_mode, mbmi->mode, w);
@@ -2322,8 +2324,9 @@
     for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
 
 #if CONFIG_CB4X4
-      if (mbmi->sb_type < BLOCK_8X8 && plane &&
-          !is_chroma_reference(mi_row, mi_col)) {
+      if (!is_chroma_reference(mi_row, mi_col, mbmi->sb_type,
+                               xd->plane[plane].subsampling_x,
+                               xd->plane[plane].subsampling_y)) {
         (*tok)++;
         continue;
       }
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index fa65bb9..1158dc9 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -1882,7 +1882,8 @@
 
 #if CONFIG_CB4X4
   x->skip_chroma_rd =
-      (bsize < BLOCK_8X8) && !is_chroma_reference(mi_row, mi_col);
+      !is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
+                           xd->plane[1].subsampling_y);
 #endif
 
 #if CONFIG_AOM_HIGHBITDEPTH
@@ -5550,10 +5551,10 @@
   }
 }
 
-static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi,
-                            const MODE_INFO *above_mi, const MODE_INFO *left_mi,
-                            const int intraonly, const int mi_row,
-                            const int mi_col) {
+static void sum_intra_stats(FRAME_COUNTS *counts, MACROBLOCKD *xd,
+                            const MODE_INFO *mi, const MODE_INFO *above_mi,
+                            const MODE_INFO *left_mi, const int intraonly,
+                            const int mi_row, const int mi_col) {
   const PREDICTION_MODE y_mode = mi->mbmi.mode;
   const PREDICTION_MODE uv_mode = mi->mbmi.uv_mode;
   const BLOCK_SIZE bsize = mi->mbmi.sb_type;
@@ -5586,10 +5587,13 @@
   }
 
 #if CONFIG_CB4X4
-  if (bsize < BLOCK_8X8 && !is_chroma_reference(mi_row, mi_col)) return;
+  if (!is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
+                           xd->plane[1].subsampling_y))
+    return;
 #else
   (void)mi_row;
   (void)mi_col;
+  (void)xd;
 #endif
   ++counts->uv_mode[y_mode][uv_mode];
 }
@@ -5755,7 +5759,7 @@
       av1_encode_intra_block_plane((AV1_COMMON *)cm, x, block_size, plane, 1,
                                    mi_row, mi_col);
     if (!dry_run)
-      sum_intra_stats(td->counts, mi, xd->above_mi, xd->left_mi,
+      sum_intra_stats(td->counts, xd, mi, xd->above_mi, xd->left_mi,
                       frame_is_intra_only(cm), mi_row, mi_col);
 
     // TODO(huisu): move this into sum_intra_stats().
diff --git a/av1/encoder/encodemb.c b/av1/encoder/encodemb.c
index aa743db..02b7ab0 100644
--- a/av1/encoder/encodemb.c
+++ b/av1/encoder/encodemb.c
@@ -943,7 +943,9 @@
 
   for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
 #if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
-    if (bsize < BLOCK_8X8 && plane && !is_chroma_reference(mi_row, mi_col))
+    if (!is_chroma_reference(mi_row, mi_col, bsize,
+                             xd->plane[plane].subsampling_x,
+                             xd->plane[plane].subsampling_y))
       continue;
     if (plane) bsize = AOMMAX(bsize, BLOCK_8X8);
 #else
@@ -1121,7 +1123,9 @@
   };
 
 #if CONFIG_CB4X4
-  if (bsize < BLOCK_8X8 && plane && !is_chroma_reference(mi_row, mi_col))
+  if (!is_chroma_reference(mi_row, mi_col, bsize,
+                           xd->plane[plane].subsampling_x,
+                           xd->plane[plane].subsampling_y))
     return;
 #else
   (void)mi_row;
diff --git a/av1/encoder/tokenize.c b/av1/encoder/tokenize.c
index f14410e..2a354ab 100644
--- a/av1/encoder/tokenize.c
+++ b/av1/encoder/tokenize.c
@@ -711,7 +711,9 @@
 
   for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
 #if CONFIG_CB4X4
-    if (bsize < BLOCK_8X8 && plane && !is_chroma_reference(mi_row, mi_col)) {
+    if (!is_chroma_reference(mi_row, mi_col, bsize,
+                             xd->plane[plane].subsampling_x,
+                             xd->plane[plane].subsampling_y)) {
 #if !CONFIG_PVQ
       if (!dry_run) {
         (*t)->token = EOSB_TOKEN;
@@ -781,7 +783,9 @@
     td->counts->skip[ctx][0] += skip_inc;
     for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
 #if CONFIG_CB4X4
-      if (bsize < BLOCK_8X8 && plane && !is_chroma_reference(mi_row, mi_col)) {
+      if (!is_chroma_reference(mi_row, mi_col, bsize,
+                               xd->plane[plane].subsampling_x,
+                               xd->plane[plane].subsampling_y)) {
 #if !CONFIG_PVQ
         (*t)->token = EOSB_TOKEN;
         (*t)++;
@@ -806,7 +810,9 @@
     int plane;
     for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
 #if CONFIG_CB4X4
-      if (bsize < BLOCK_8X8 && plane && !is_chroma_reference(mi_row, mi_col))
+      if (!is_chroma_reference(mi_row, mi_col, bsize,
+                               xd->plane[plane].subsampling_x,
+                               xd->plane[plane].subsampling_y))
         continue;
 #else
       (void)mi_row;
@@ -819,7 +825,9 @@
     int plane;
     for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
 #if CONFIG_CB4X4
-      if (bsize < BLOCK_8X8 && plane && !is_chroma_reference(mi_row, mi_col))
+      if (!is_chroma_reference(mi_row, mi_col, bsize,
+                               xd->plane[plane].subsampling_x,
+                               xd->plane[plane].subsampling_y))
         continue;
 #else
       (void)mi_row;