Commit 79551e77 authored by Luc Trudeau's avatar Luc Trudeau

[NORMATIVE] Lossless CfL Workgroup fix

In the 23/03/2018 work group call, it was decided
that CfL cannot break the assumption that the CfL
prediction size and the transform size remain
equivalent.

For lossless, this implies that CfL is only
available when the CfL prediction is 4x4.

BUG=aomedia:1212

Results on Subset 1 indicate:
  * A 0.01% rate increase for lossless compression
https://arewecompressedyet.com/?job=Lossless-Master%402018-03-23T17%3A32%3A30.993Z&job=Lossless-CfLWGFix%402018-03-23T17%3A01%3A12.689Z
  * No impact on lossy compression
  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
https://arewecompressedyet.com/?job=Lossless-Master%402018-03-23T17%3A26%3A08.496Z&job=Lossless-CfLWGFix%402018-03-23T17%3A26%3A24.792Z

Change-Id: If90c39ff2e4070dad977dfb8232cd070373c26ad
parent ba908f17
......@@ -220,7 +220,7 @@ void cfl_predict_block(MACROBLOCKD *const xd, uint8_t *dst, int dst_stride,
TX_SIZE tx_size, int plane) {
CFL_CTX *const cfl = &xd->cfl;
MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
assert(is_cfl_allowed(mbmi));
assert(is_cfl_allowed(xd));
if (!cfl->are_parameters_computed) cfl_compute_parameters(xd, tx_size);
......@@ -486,7 +486,7 @@ void cfl_store_tx(MACROBLOCKD *const xd, int row, int col, TX_SIZE tx_size,
uint8_t *dst =
&pd->dst.buf[(row * pd->dst.stride + col) << tx_size_wide_log2[0]];
assert(is_cfl_allowed(&xd->mi[0]->mbmi));
assert(is_cfl_allowed(xd));
if (block_size_high[bsize] == 4 || block_size_wide[bsize] == 4) {
// Only dimensions of size 4 can have an odd offset.
assert(!((col & 1) && tx_size_wide[tx_size] != 4));
......@@ -503,7 +503,7 @@ void cfl_store_block(MACROBLOCKD *const xd, BLOCK_SIZE bsize, TX_SIZE tx_size) {
int row = 0;
int col = 0;
assert(is_cfl_allowed(&xd->mi[0]->mbmi));
assert(is_cfl_allowed(xd));
if (block_size_high[bsize] == 4 || block_size_wide[bsize] == 4) {
sub8x8_adjust_offset(cfl, &row, &col);
}
......
......@@ -14,9 +14,19 @@
#include "av1/common/blockd.h"
static INLINE CFL_ALLOWED_TYPE is_cfl_allowed(const MB_MODE_INFO *mbmi) {
static INLINE CFL_ALLOWED_TYPE is_cfl_allowed(const MACROBLOCKD *xd) {
const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
const BLOCK_SIZE bsize = mbmi->sb_type;
assert(bsize < BLOCK_SIZES_ALL);
if (xd->lossless[mbmi->segment_id]) {
// In lossless, CfL is available when the partition size is equal to the
// transform size.
const int plane_bsize =
get_plane_block_size(bsize, &xd->plane[AOM_PLANE_U]);
return (CFL_ALLOWED_TYPE)(block_size_wide[plane_bsize] == 4 &&
block_size_high[plane_bsize] == 4);
}
// Spec: CfL is available to luma partitions lesser than or equal to 32x32
return (CFL_ALLOWED_TYPE)(block_size_wide[bsize] <= 32 &&
block_size_high[bsize] <= 32);
}
......
......@@ -1641,7 +1641,7 @@ void av1_predict_intra_block_facade(const AV1_COMMON *cm, MACROBLOCKD *xd,
if (plane != AOM_PLANE_Y && mbmi->uv_mode == UV_CFL_PRED) {
#if CONFIG_DEBUG
assert(is_cfl_allowed(mbmi));
assert(is_cfl_allowed(xd));
const BLOCK_SIZE plane_bsize = get_plane_block_size(mbmi->sb_type, pd);
(void)plane_bsize;
assert(plane_bsize < BLOCK_SIZES_ALL);
......
......@@ -181,7 +181,7 @@ static void predict_and_reconstruct_intra_block(
max_scan_line, eob, cm->reduced_tx_set_used);
}
}
if (plane == AOM_PLANE_Y && xd->cfl.store_y && is_cfl_allowed(mbmi)) {
if (plane == AOM_PLANE_Y && xd->cfl.store_y && is_cfl_allowed(xd)) {
cfl_store_tx(xd, row, col, tx_size, mbmi->sb_type);
}
}
......@@ -514,7 +514,7 @@ static void decode_token_and_recon_block(AV1Decoder *const pbi,
}
if (mbmi->uv_mode != UV_CFL_PRED) {
if (!cfl->is_chroma_reference && is_inter_block(mbmi) &&
is_cfl_allowed(mbmi)) {
is_cfl_allowed(xd)) {
cfl_store_block(xd, mbmi->sb_type, mbmi->tx_size);
}
}
......
......@@ -845,7 +845,7 @@ static void read_intra_frame_mode_info(AV1_COMMON *const cm,
{
xd->cfl.is_chroma_reference = 1;
mbmi->uv_mode =
read_intra_mode_uv(ec_ctx, r, is_cfl_allowed(mbmi), mbmi->mode);
read_intra_mode_uv(ec_ctx, r, is_cfl_allowed(xd), mbmi->mode);
if (mbmi->uv_mode == UV_CFL_PRED) {
mbmi->cfl_alpha_idx = read_cfl_alphas(ec_ctx, r, &mbmi->cfl_alpha_signs);
xd->cfl.store_y = 1;
......@@ -1116,7 +1116,7 @@ static void read_intra_block_mode_info(AV1_COMMON *const cm, const int mi_row,
#endif // CONFIG_MONO_VIDEO
{
mbmi->uv_mode =
read_intra_mode_uv(ec_ctx, r, is_cfl_allowed(mbmi), mbmi->mode);
read_intra_mode_uv(ec_ctx, r, is_cfl_allowed(xd), mbmi->mode);
if (mbmi->uv_mode == UV_CFL_PRED) {
mbmi->cfl_alpha_idx =
read_cfl_alphas(xd->tile_ctx, r, &mbmi->cfl_alpha_signs);
......
......@@ -1046,7 +1046,7 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row,
is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
xd->plane[1].subsampling_y)) {
const UV_PREDICTION_MODE uv_mode = mbmi->uv_mode;
write_intra_uv_mode(ec_ctx, uv_mode, mode, is_cfl_allowed(mbmi), w);
write_intra_uv_mode(ec_ctx, uv_mode, mode, is_cfl_allowed(xd), w);
if (uv_mode == UV_CFL_PRED)
write_cfl_alphas(ec_ctx, mbmi->cfl_alpha_idx, mbmi->cfl_alpha_signs, w);
if (use_angle_delta && av1_is_directional_mode(get_uv_mode(uv_mode))) {
......@@ -1289,7 +1289,7 @@ static void write_mb_modes_kf(AV1_COMP *cpi, MACROBLOCKD *xd,
is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
xd->plane[1].subsampling_y)) {
const UV_PREDICTION_MODE uv_mode = mbmi->uv_mode;
write_intra_uv_mode(ec_ctx, uv_mode, mode, is_cfl_allowed(mbmi), w);
write_intra_uv_mode(ec_ctx, uv_mode, mode, is_cfl_allowed(xd), w);
if (uv_mode == UV_CFL_PRED)
write_cfl_alphas(ec_ctx, mbmi->cfl_alpha_idx, mbmi->cfl_alpha_signs, w);
if (use_angle_delta && av1_is_directional_mode(get_uv_mode(uv_mode))) {
......
......@@ -828,10 +828,10 @@ static void sum_intra_stats(const AV1_COMMON *const cm, FRAME_COUNTS *counts,
return;
#if CONFIG_ENTROPY_STATS
++counts->uv_mode[is_cfl_allowed(mbmi)][y_mode][uv_mode];
++counts->uv_mode[is_cfl_allowed(xd)][y_mode][uv_mode];
#endif // CONFIG_ENTROPY_STATS
if (allow_update_cdf) {
const CFL_ALLOWED_TYPE cfl_allowed = is_cfl_allowed(mbmi);
const CFL_ALLOWED_TYPE cfl_allowed = is_cfl_allowed(xd);
update_cdf(fc->uv_mode_cdf[cfl_allowed][y_mode], uv_mode,
UV_INTRA_MODES - !cfl_allowed);
}
......@@ -4841,7 +4841,7 @@ static void encode_superblock(const AV1_COMP *const cpi, TileDataEnc *tile_data,
if (is_inter_block(mbmi) &&
!is_chroma_reference(mi_row, mi_col, bsize, cfl->subsampling_x,
cfl->subsampling_y) &&
is_cfl_allowed(mbmi)) {
is_cfl_allowed(xd)) {
cfl_store_block(xd, mbmi->sb_type, mbmi->tx_size);
}
}
......@@ -567,7 +567,7 @@ void av1_encode_block_intra(int plane, int block, int blk_row, int blk_col,
// very expensive.
*(args->skip) = 0;
if (plane == AOM_PLANE_Y && xd->cfl.store_y && is_cfl_allowed(mbmi)) {
if (plane == AOM_PLANE_Y && xd->cfl.store_y && is_cfl_allowed(xd)) {
cfl_store_tx(xd, blk_row, blk_col, tx_size, plane_bsize);
}
}
......
......@@ -2121,7 +2121,7 @@ static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
a, l, 0, args->use_fast_coef_costing,
args->best_rd - args->this_rd, &this_rd_stats);
if (plane == AOM_PLANE_Y && xd->cfl.store_y && is_cfl_allowed(mbmi)) {
if (plane == AOM_PLANE_Y && xd->cfl.store_y && is_cfl_allowed(xd)) {
assert(!is_inter_block(mbmi) || plane_bsize < BLOCK_8X8);
cfl_store_tx(xd, blk_row, blk_col, tx_size, plane_bsize);
}
......@@ -4778,7 +4778,7 @@ static int cfl_rd_pick_alpha(MACROBLOCK *const x, const AV1_COMP *const cpi,
const BLOCK_SIZE bsize = mbmi->sb_type;
#if CONFIG_DEBUG
assert(is_cfl_allowed(mbmi));
assert(is_cfl_allowed(xd));
const BLOCK_SIZE plane_bsize =
get_plane_block_size(mbmi->sb_type, &xd->plane[AOM_PLANE_U]);
(void)plane_bsize;
......@@ -4919,7 +4919,7 @@ static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
mbmi->uv_mode = mode;
int cfl_alpha_rate = 0;
if (mode == UV_CFL_PRED) {
if (!is_cfl_allowed(mbmi)) continue;
if (!is_cfl_allowed(xd)) continue;
assert(!is_directional_mode);
const TX_SIZE uv_tx_size = av1_get_tx_size(AOM_PLANE_U, xd);
cfl_alpha_rate = cfl_rd_pick_alpha(x, cpi, uv_tx_size, best_rd);
......@@ -4928,7 +4928,7 @@ static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
mbmi->angle_delta[PLANE_TYPE_UV] = 0;
if (is_directional_mode && av1_use_angle_delta(mbmi->sb_type)) {
const int rate_overhead =
x->intra_uv_mode_cost[is_cfl_allowed(mbmi)][mbmi->mode][mode];
x->intra_uv_mode_cost[is_cfl_allowed(xd)][mbmi->mode][mode];
if (!rd_pick_intra_angle_sbuv(cpi, x, bsize, rate_overhead, best_rd,
&this_rate, &tokenonly_rd_stats))
continue;
......@@ -4938,12 +4938,12 @@ static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
}
}
const int mode_cost =
x->intra_uv_mode_cost[is_cfl_allowed(mbmi)][mbmi->mode][mode] +
x->intra_uv_mode_cost[is_cfl_allowed(xd)][mbmi->mode][mode] +
cfl_alpha_rate;
this_rate = tokenonly_rd_stats.rate +
intra_mode_info_cost_uv(cpi, x, mbmi, bsize, mode_cost);
if (mode == UV_CFL_PRED) {
assert(is_cfl_allowed(mbmi));
assert(is_cfl_allowed(xd));
#if CONFIG_DEBUG
if (!xd->lossless[mbmi->segment_id])
assert(xd->cfl.rate == tokenonly_rd_stats.rate + mode_cost);
......@@ -4967,7 +4967,7 @@ static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
uint8_t *best_palette_color_map = x->palette_buffer->best_palette_color_map;
rd_pick_palette_intra_sbuv(
cpi, x,
x->intra_uv_mode_cost[is_cfl_allowed(mbmi)][mbmi->mode][UV_DC_PRED],
x->intra_uv_mode_cost[is_cfl_allowed(xd)][mbmi->mode][UV_DC_PRED],
best_palette_color_map, &best_mbmi, &best_rd, rate, rate_tokenonly,
distortion, skippable);
}
......@@ -9017,7 +9017,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
}
if (num_planes > 1 && !x->skip_chroma_rd) {
const int uv_mode_cost =
x->intra_uv_mode_cost[is_cfl_allowed(mbmi)][mbmi->mode]
x->intra_uv_mode_cost[is_cfl_allowed(xd)][mbmi->mode]
[mbmi->uv_mode];
rate2 += rate_uv +
intra_mode_info_cost_uv(cpi, x, mbmi, bsize, uv_mode_cost);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment