[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.