[CFL] UV_PREDICTION_MODE

A separate prediction mode struct is added to allow
for uv-only modes (like CfL). Note: CfL will be
added as a separate mode in an upcoming commit.

Results on Subset1 (Compared to 4266a7ed with CfL enabled)
  PSNR | PSNR Cb | PSNR Cr | PSNR HVS |   SSIM | MS SSIM | CIEDE 2000
0.0000 |  0.0000 |  0.0000 |   0.0000 | 0.0000 |  0.0000 |     0.0000

Change-Id: Ie80711c641c97f745daac899eadce6201ed97fcc
diff --git a/av1/common/blockd.h b/av1/common/blockd.h
index 4e876ac..4ba0def 100644
--- a/av1/common/blockd.h
+++ b/av1/common/blockd.h
@@ -377,7 +377,7 @@
   int8_t seg_id_predicted;  // valid only when temporal_update is enabled
 
   // Only for INTRA blocks
-  PREDICTION_MODE uv_mode;
+  UV_PREDICTION_MODE uv_mode;
 #if CONFIG_PALETTE
   PALETTE_MODE_INFO palette_mode_info;
 #endif  // CONFIG_PALETTE
@@ -497,6 +497,33 @@
 #endif
 }
 
+#if CONFIG_CFL
+static INLINE PREDICTION_MODE get_uv_mode(UV_PREDICTION_MODE mode) {
+  static const PREDICTION_MODE uv2y[UV_INTRA_MODES] = {
+    DC_PRED,    // UV_DC_PRED
+    V_PRED,     // UV_V_PRED
+    H_PRED,     // UV_H_PRED
+    D45_PRED,   // UV_D45_PRED
+    D135_PRED,  // UV_D135_PRED
+    D117_PRED,  // UV_D117_PRED
+    D153_PRED,  // UV_D153_PRED
+    D207_PRED,  // UV_D207_PRED
+    D63_PRED,   // UV_D63_PRED
+#if CONFIG_ALT_INTRA
+    SMOOTH_PRED,  // UV_SMOOTH_PRED
+#if CONFIG_SMOOTH_HV
+    SMOOTH_V_PRED,  // UV_SMOOTH_V_PRED
+    SMOOTH_H_PRED,  // UV_SMOOTH_H_PRED
+#endif              // CONFIG_SMOOTH_HV
+#endif              // CONFIG_ALT_INTRA
+    TM_PRED,        // UV_TM_PRED
+  };
+  return uv2y[mode];
+}
+#else
+static INLINE PREDICTION_MODE get_uv_mode(PREDICTION_MODE mode) { return mode; }
+#endif  // CONFIG_CFL
+
 static INLINE int is_inter_block(const MB_MODE_INFO *mbmi) {
 #if CONFIG_INTRABC
   if (is_intrabc_block(mbmi)) return 1;
@@ -1191,7 +1218,8 @@
   if (is_inter_block(mbmi)) return mbmi->mode;
 
   int block_raster_idx = av1_block_index_to_raster_order(tx_size, block_idx);
-  return (plane == 0) ? get_y_mode(mi, block_raster_idx) : mbmi->uv_mode;
+  return (plane == PLANE_TYPE_Y) ? get_y_mode(mi, block_raster_idx)
+                                 : get_uv_mode(mbmi->uv_mode);
 }
 #endif
 
@@ -1206,7 +1234,7 @@
 
   return intra_mode_to_tx_type_context[plane_type == PLANE_TYPE_Y
                                            ? get_y_mode(xd->mi[0], block_idx)
-                                           : mbmi->uv_mode];
+                                           : get_uv_mode(mbmi->uv_mode)];
 }
 
 static INLINE TX_TYPE av1_get_tx_type(PLANE_TYPE plane_type,
@@ -1281,7 +1309,7 @@
     return DCT_DCT;
   else
 #endif  // CONFIG_CHROMA_2X2
-    return intra_mode_to_tx_type_context[mbmi->uv_mode];
+    return intra_mode_to_tx_type_context[get_uv_mode(mbmi->uv_mode)];
 #else   // CONFIG_CB4X4
   // Sub8x8-Inter/Intra OR UV-Intra
   if (is_inter_block(mbmi)) {  // Sub8x8-Inter
@@ -1291,7 +1319,7 @@
         av1_block_index_to_raster_order(tx_size, block);
     return intra_mode_to_tx_type_context[plane_type == PLANE_TYPE_Y
                                              ? get_y_mode(mi, block_raster_idx)
-                                             : mbmi->uv_mode];
+                                             : get_uv_mode(mbmi->uv_mode)];
   }
 #endif  // CONFIG_CB4X4
 #else   // CONFIG_EXT_TX
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c
index 7566e8d..c4d75c5 100644
--- a/av1/common/entropymode.c
+++ b/av1/common/entropymode.c
@@ -2614,7 +2614,7 @@
     };
 
 static const aom_cdf_prob
-    default_uv_mode_cdf[INTRA_MODES][CDF_SIZE(INTRA_MODES)] = {
+    default_uv_mode_cdf[INTRA_MODES][CDF_SIZE(UV_INTRA_MODES)] = {
       { AOM_ICDF(23552), AOM_ICDF(23660), AOM_ICDF(26044), AOM_ICDF(28731),
         AOM_ICDF(29093), AOM_ICDF(29590), AOM_ICDF(30000), AOM_ICDF(30465),
         AOM_ICDF(30825), AOM_ICDF(31478), AOM_ICDF(32088), AOM_ICDF(32401),
@@ -2686,7 +2686,7 @@
     };
 
 static const aom_cdf_prob
-    default_uv_mode_cdf[INTRA_MODES][CDF_SIZE(INTRA_MODES)] = {
+    default_uv_mode_cdf[INTRA_MODES][CDF_SIZE(UV_INTRA_MODES)] = {
       { AOM_ICDF(25472), AOM_ICDF(25558), AOM_ICDF(27783), AOM_ICDF(30779),
         AOM_ICDF(30988), AOM_ICDF(31269), AOM_ICDF(31492), AOM_ICDF(31741),
         AOM_ICDF(32014), AOM_ICDF(32420), AOM_ICDF(32768), 0 },
@@ -2740,7 +2740,7 @@
     };
 
 static const aom_cdf_prob
-    default_uv_mode_cdf[INTRA_MODES][CDF_SIZE(INTRA_MODES)] = {
+    default_uv_mode_cdf[INTRA_MODES][CDF_SIZE(UV_INTRA_MODES)] = {
       { AOM_ICDF(15360), AOM_ICDF(15836), AOM_ICDF(20863), AOM_ICDF(27513),
         AOM_ICDF(28269), AOM_ICDF(29048), AOM_ICDF(29455), AOM_ICDF(30154),
         AOM_ICDF(31206), AOM_ICDF(32768), 0 },
diff --git a/av1/common/entropymode.h b/av1/common/entropymode.h
index 61e2fcd..83beb6a 100644
--- a/av1/common/entropymode.h
+++ b/av1/common/entropymode.h
@@ -92,7 +92,7 @@
 
 typedef struct frame_contexts {
   aom_prob y_mode_prob[BLOCK_SIZE_GROUPS][INTRA_MODES - 1];
-  aom_prob uv_mode_prob[INTRA_MODES][INTRA_MODES - 1];
+  aom_prob uv_mode_prob[INTRA_MODES][UV_INTRA_MODES - 1];
 #if CONFIG_EXT_PARTITION_TYPES
   aom_prob partition_prob[PARTITION_CONTEXTS][EXT_PARTITION_TYPES - 1];
 #else
@@ -321,7 +321,7 @@
   aom_prob switchable_restore_prob[RESTORE_SWITCHABLE_TYPES - 1];
 #endif  // CONFIG_LOOP_RESTORATION
   aom_cdf_prob y_mode_cdf[BLOCK_SIZE_GROUPS][CDF_SIZE(INTRA_MODES)];
-  aom_cdf_prob uv_mode_cdf[INTRA_MODES][CDF_SIZE(INTRA_MODES)];
+  aom_cdf_prob uv_mode_cdf[INTRA_MODES][CDF_SIZE(UV_INTRA_MODES)];
 #if CONFIG_EXT_PARTITION_TYPES
   aom_cdf_prob partition_cdf[PARTITION_CONTEXTS][CDF_SIZE(EXT_PARTITION_TYPES)];
 #else
@@ -376,7 +376,7 @@
 #if CONFIG_ENTROPY_STATS
   unsigned int kf_y_mode[INTRA_MODES][INTRA_MODES][INTRA_MODES];
   unsigned int y_mode[BLOCK_SIZE_GROUPS][INTRA_MODES];
-  unsigned int uv_mode[INTRA_MODES][INTRA_MODES];
+  unsigned int uv_mode[INTRA_MODES][UV_INTRA_MODES];
 #endif  // CONFIG_ENTROPY_STATS
 #if CONFIG_EXT_PARTITION_TYPES
   unsigned int partition[PARTITION_CONTEXTS][EXT_PARTITION_TYPES];
diff --git a/av1/common/enums.h b/av1/common/enums.h
index bd9b277..a4dfbf8 100644
--- a/av1/common/enums.h
+++ b/av1/common/enums.h
@@ -415,6 +415,37 @@
   INTRA_INVALID = MB_MODE_COUNT  // For uv_mode in inter blocks
 } PREDICTION_MODE;
 
+#if CONFIG_CFL
+// TODO(ltrudeau) Do we really want to pack this?
+// TODO(ltrudeau) Do we match with PREDICTION_MODE?
+typedef enum ATTRIBUTE_PACKED {
+  UV_DC_PRED,    // Average of above and left pixels
+  UV_V_PRED,     // Vertical
+  UV_H_PRED,     // Horizontal
+  UV_D45_PRED,   // Directional 45  deg = round(arctan(1/1) * 180/pi)
+  UV_D135_PRED,  // Directional 135 deg = 180 - 45
+  UV_D117_PRED,  // Directional 117 deg = 180 - 63
+  UV_D153_PRED,  // Directional 153 deg = 180 - 27
+  UV_D207_PRED,  // Directional 207 deg = 180 + 27
+  UV_D63_PRED,   // Directional 63  deg = round(arctan(2/1) * 180/pi)
+#if CONFIG_ALT_INTRA
+  UV_SMOOTH_PRED,  // Combination of horizontal and vertical interpolation
+#if CONFIG_SMOOTH_HV
+  UV_SMOOTH_V_PRED,  // Vertical interpolation
+  UV_SMOOTH_H_PRED,  // Horizontal interpolation
+#endif               // CONFIG_SMOOTH_HV
+#endif               // CONFIG_ALT_INTRA
+  UV_TM_PRED,        // True-motion
+  UV_INTRA_MODES,
+  UV_MODE_INVALID,  // For uv_mode in inter blocks
+} UV_PREDICTION_MODE;
+#else
+#define UV_INTRA_MODES (INTRA_MODES)
+#define UV_PREDICTION_MODE PREDICTION_MODE
+#define UV_DC_PRED (DC_PRED)
+#define UV_MODE_INVALID (INTRA_INVALID)
+#endif  // CONFIG_CFL
+
 typedef enum {
   SIMPLE_TRANSLATION = 0,
 #if CONFIG_MOTION_VAR
diff --git a/av1/common/reconintra.c b/av1/common/reconintra.c
index 6f62902..13fe11e 100644
--- a/av1/common/reconintra.c
+++ b/av1/common/reconintra.c
@@ -3045,18 +3045,19 @@
 
 void av1_predict_intra_block_facade(MACROBLOCKD *xd, int plane, int block_idx,
                                     int blk_col, int blk_row, TX_SIZE tx_size) {
+  const MODE_INFO *mi = xd->mi[0];
+  const MB_MODE_INFO *const mbmi = &mi->mbmi;
   struct macroblockd_plane *const pd = &xd->plane[plane];
   const int dst_stride = pd->dst.stride;
   uint8_t *dst =
       &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
-  const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
   const int block_raster_idx =
       av1_block_index_to_raster_order(tx_size, block_idx);
-  const PREDICTION_MODE mode =
-      (plane == 0) ? get_y_mode(xd->mi[0], block_raster_idx) : mbmi->uv_mode;
-
+  const PREDICTION_MODE mode = (plane == AOM_PLANE_Y)
+                                   ? get_y_mode(mi, block_raster_idx)
+                                   : get_uv_mode(mbmi->uv_mode);
 #if CONFIG_CFL
-  if (plane != AOM_PLANE_Y && mbmi->uv_mode == DC_PRED) {
+  if (plane != AOM_PLANE_Y && mbmi->uv_mode == UV_DC_PRED) {
     if (plane == AOM_PLANE_U && blk_col == 0 && blk_row == 0) {
       // Avoid computing the CfL parameters twice, if they have already been
       // computed in cfl_rd_pick_alpha.