[CFL] Store luma as prediction for chroma
Stores the reconstructed luma pixels for each transform block inside a
prediction block. Rectangular transform blocks are supported.
As for RDO, after all the modes have been tested for luma, an extra
encoding is perform in order to store the reconstructed pixel values of
the best mode. These values are then used for RDO on the chromatic
planes.
Change-Id: I354d9827e32fd41065f1b2ce02832d943a6fa156
diff --git a/av1/encoder/block.h b/av1/encoder/block.h
index 28bbaf4..39e08d5 100644
--- a/av1/encoder/block.h
+++ b/av1/encoder/block.h
@@ -228,6 +228,10 @@
// 4x4 blocks are coded.
int rate_4x4[256];
#endif
+#if CONFIG_CFL
+ // Whether luma needs to be stored during RDO.
+ int cfl_store_y;
+#endif
};
#ifdef __cplusplus
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index b943b64..6fb7c85 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -1869,6 +1869,10 @@
x->pvq_speed = 1;
x->pvq_coded = 0;
#endif
+#if CONFIG_CFL
+ // Don't store luma during RDO (we will store the best mode later).
+ x->cfl_store_y = 0;
+#endif
set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
mbmi = &xd->mi[0]->mbmi;
@@ -4574,6 +4578,10 @@
*rate_nocoef = best_rate_nocoef;
#endif // CONFIG_SUPERTX
+#if CONFIG_CFL
+ // Store the luma for the best mode
+ x->cfl_store_y = 1;
+#endif
if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX &&
pc_tree->index != 3) {
if (bsize == cm->sb_size) {
@@ -4587,6 +4595,9 @@
pc_tree, NULL);
}
}
+#if CONFIG_CFL
+ x->cfl_store_y = 0;
+#endif
if (bsize == cm->sb_size) {
#if !CONFIG_PVQ && !CONFIG_LV_MAP
@@ -5036,6 +5047,7 @@
#if CONFIG_CFL
td->mb.e_mbd.cfl = &this_tile->cfl;
+ memset(&this_tile->cfl.y_pix, 0, sizeof(uint8_t) * MAX_SB_SQUARE);
#endif
#if CONFIG_PVQ
@@ -5921,6 +5933,9 @@
x->pvq_speed = 0;
x->pvq_coded = (dry_run == OUTPUT_ENABLED) ? 1 : 0;
#endif
+#if CONFIG_CFL
+ x->cfl_store_y = (dry_run == OUTPUT_ENABLED) ? 1 : 0;
+#endif
if (!is_inter) {
int plane;
diff --git a/av1/encoder/encodemb.c b/av1/encoder/encodemb.c
index f9208f5..dbb7525 100644
--- a/av1/encoder/encodemb.c
+++ b/av1/encoder/encodemb.c
@@ -38,6 +38,10 @@
#include "av1/encoder/pvq_encoder.h"
#endif
+#if CONFIG_CFL
+#include "av1/common/cfl.h"
+#endif
+
// Check if one needs to use c version subtraction.
static int check_subtract_block_size(int w, int h) { return w < 4 || h < 4; }
@@ -1475,6 +1479,11 @@
#else
// Note : *(args->skip) == mbmi->skip
#endif
+#if CONFIG_CFL
+ if (plane == AOM_PLANE_Y && x->cfl_store_y) {
+ cfl_store(xd->cfl, dst, dst_stride, blk_row, blk_col, tx_size);
+ }
+#endif
}
void av1_encode_intra_block_plane(AV1_COMMON *cm, MACROBLOCK *x,
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c
index 5528dc3..13837b3 100644
--- a/av1/encoder/firstpass.c
+++ b/av1/encoder/firstpass.c
@@ -537,6 +537,10 @@
xd->mi = cm->mi_grid_visible;
xd->mi[0] = cm->mi;
+#if CONFIG_CFL
+ // Don't store luma on the fist pass since chroma is not computed
+ x->cfl_store_y = 0;
+#endif
av1_frame_init_quantizer(cpi);
#if CONFIG_PVQ
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 458f2b4..f13c585 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -3714,6 +3714,16 @@
od_encode_rollback(&x->daala_enc, &post_buf);
#endif // CONFIG_PVQ
+#if CONFIG_CFL
+ // Perform one extra txfm_rd_in_plane() call, this time with the best value so
+ // we can store reconstructed luma values
+ RD_STATS this_rd_stats;
+ x->cfl_store_y = 1;
+ txfm_rd_in_plane(x, cpi, &this_rd_stats, INT64_MAX, 0, bsize,
+ mic->mbmi.tx_size, cpi->sf.use_fast_coef_costing);
+ x->cfl_store_y = 0;
+#endif
+
#if CONFIG_PALETTE
if (try_palette) {
rd_pick_palette_intra_sby(cpi, x, bsize, palette_y_mode_ctx,