Commit cb3a8ef5 authored by David Michael Barr's avatar David Michael Barr

[CFL] separate uv_mode CDFs, split on is_cfl_allowed

This is to exclude coding CFL for block sizes where it is normatively
not allowed.

Reuse the alternate CDFs from the --disable-cfl path.

This yields some improvement on subset1:
   PSNR | PSNR Cb | PSNR Cr | PSNR HVS |    SSIM | MS SSIM | CIEDE 2000
-0.0113 | -0.2630 | -0.2138 |   0.0021 | -0.0110 | -0.0157 |    -0.0511

BUG=aomedia:1182

Change-Id: I1e5f23ef7f2debcf8edce788bfa63ec95db4a679
parent a855cefc
......@@ -25,10 +25,10 @@ typedef void (*cfl_predict_hbd_fn)(const int16_t *pred_buf_q3, uint16_t *dst,
int dst_stride, TX_SIZE tx_size,
int alpha_q3, int bd);
static INLINE int is_cfl_allowed(const MB_MODE_INFO *mbmi) {
static INLINE CFL_ALLOWED_TYPE is_cfl_allowed(const MB_MODE_INFO *mbmi) {
const BLOCK_SIZE bsize = mbmi->sb_type;
assert(bsize < BLOCK_SIZES_ALL);
return bsize <= CFL_MAX_BLOCK_SIZE;
return (CFL_ALLOWED_TYPE)(bsize <= CFL_MAX_BLOCK_SIZE);
}
static INLINE int get_scaled_luma_q0(int alpha_q3, int16_t pred_buf_q3) {
......
This diff is collapsed.
......@@ -170,7 +170,12 @@ typedef struct frame_contexts {
aom_cdf_prob sgrproj_restore_cdf[CDF_SIZE(2)];
#endif // CONFIG_LOOP_RESTORATION
aom_cdf_prob y_mode_cdf[BLOCK_SIZE_GROUPS][CDF_SIZE(INTRA_MODES)];
#if CONFIG_CFL
aom_cdf_prob uv_mode_cdf[CFL_ALLOWED_TYPES][INTRA_MODES]
[CDF_SIZE(UV_INTRA_MODES)];
#else
aom_cdf_prob uv_mode_cdf[INTRA_MODES][CDF_SIZE(UV_INTRA_MODES)];
#endif
#if CONFIG_EXT_PARTITION_TYPES
aom_cdf_prob partition_cdf[PARTITION_CONTEXTS][CDF_SIZE(EXT_PARTITION_TYPES)];
#else
......@@ -224,7 +229,11 @@ typedef struct FRAME_COUNTS {
#endif
unsigned int angle_delta[DIRECTIONAL_MODES][2 * MAX_ANGLE_DELTA + 1];
unsigned int y_mode[BLOCK_SIZE_GROUPS][INTRA_MODES];
#if CONFIG_CFL
unsigned int uv_mode[CFL_ALLOWED_TYPES][INTRA_MODES][UV_INTRA_MODES];
#else
unsigned int uv_mode[INTRA_MODES][UV_INTRA_MODES];
#endif // CONFIG_CFL
#endif // CONFIG_ENTROPY_STATS
#if CONFIG_EXT_PARTITION_TYPES
unsigned int partition[PARTITION_CONTEXTS][EXT_PARTITION_TYPES];
......
......@@ -401,6 +401,12 @@ typedef enum ATTRIBUTE_PACKED {
CFL_SIGNS
} CFL_SIGN_TYPE;
typedef enum ATTRIBUTE_PACKED {
CFL_DISALLOWED,
CFL_ALLOWED,
CFL_ALLOWED_TYPES
} CFL_ALLOWED_TYPE;
// CFL_SIGN_ZERO,CFL_SIGN_ZERO is invalid
#define CFL_JOINT_SIGNS (CFL_SIGNS * CFL_SIGNS - 1)
// CFL_SIGN_U is equivalent to (js + 1) / 3 for js in 0 to 8
......
......@@ -175,10 +175,14 @@ static int read_delta_lflevel(AV1_COMMON *cm, MACROBLOCKD *xd, aom_reader *r,
static UV_PREDICTION_MODE read_intra_mode_uv(FRAME_CONTEXT *ec_ctx,
aom_reader *r,
#if CONFIG_CFL
CFL_ALLOWED_TYPE cfl_allowed,
#endif
PREDICTION_MODE y_mode) {
const UV_PREDICTION_MODE uv_mode =
#if CONFIG_CFL
aom_read_symbol(r, ec_ctx->uv_mode_cdf[y_mode], UV_INTRA_MODES, ACCT_STR);
aom_read_symbol(r, ec_ctx->uv_mode_cdf[cfl_allowed][y_mode],
UV_INTRA_MODES - !cfl_allowed, ACCT_STR);
#else
read_intra_mode(r, ec_ctx->uv_mode_cdf[y_mode]);
#endif // CONFIG_CFL
......@@ -1143,26 +1147,19 @@ static void read_intra_frame_mode_info(AV1_COMMON *const cm,
if (is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
xd->plane[1].subsampling_y)) {
#if CONFIG_CFL
xd->cfl.is_chroma_reference = 1;
#endif // CONFIG_CFL
#if !CONFIG_CFL
mbmi->uv_mode = read_intra_mode_uv(ec_ctx, r, mbmi->mode);
#if CONFIG_CFL
#else
xd->cfl.is_chroma_reference = 1;
mbmi->uv_mode =
read_intra_mode_uv(ec_ctx, r, is_cfl_allowed(mbmi), mbmi->mode);
if (mbmi->uv_mode == UV_CFL_PRED) {
if (!is_cfl_allowed(mbmi)) {
aom_internal_error(
&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
"Chroma from Luma (CfL) cannot be signaled for a %dx%d block.",
block_size_wide[bsize], block_size_high[bsize]);
}
mbmi->cfl_alpha_idx = read_cfl_alphas(ec_ctx, r, &mbmi->cfl_alpha_signs);
xd->cfl.store_y = 1;
} else {
xd->cfl.store_y = 0;
}
#endif // CONFIG_CFL
#endif // !CONFIG_CFL
} else {
// Avoid decoding angle_info if there is is no chroma prediction
mbmi->uv_mode = UV_DC_PRED;
......@@ -1462,24 +1459,19 @@ static void read_intra_block_mode_info(AV1_COMMON *const cm, const int mi_row,
if (is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
xd->plane[1].subsampling_y)) {
#if !CONFIG_CFL
mbmi->uv_mode = read_intra_mode_uv(ec_ctx, r, mbmi->mode);
#if CONFIG_CFL
#else
mbmi->uv_mode =
read_intra_mode_uv(ec_ctx, r, is_cfl_allowed(mbmi), mbmi->mode);
if (mbmi->uv_mode == UV_CFL_PRED) {
if (!is_cfl_allowed(mbmi)) {
aom_internal_error(
&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
"Chroma from Luma (CfL) cannot be signaled for a %dx%d block.",
block_size_wide[bsize], block_size_high[bsize]);
}
mbmi->cfl_alpha_idx =
read_cfl_alphas(xd->tile_ctx, r, &mbmi->cfl_alpha_signs);
xd->cfl.store_y = 1;
} else {
xd->cfl.store_y = 0;
}
#endif // CONFIG_CFL
#endif // !CONFIG_CFL
} else {
// Avoid decoding angle_info if there is is no chroma prediction
mbmi->uv_mode = UV_DC_PRED;
......
......@@ -1101,11 +1101,18 @@ static void write_intra_mode(FRAME_CONTEXT *frame_ctx, BLOCK_SIZE bsize,
static void write_intra_uv_mode(FRAME_CONTEXT *frame_ctx,
UV_PREDICTION_MODE uv_mode,
PREDICTION_MODE y_mode, aom_writer *w) {
#if !CONFIG_CFL
uv_mode = get_uv_mode(uv_mode);
PREDICTION_MODE y_mode,
#if CONFIG_CFL
CFL_ALLOWED_TYPE cfl_allowed,
#endif
aom_writer *w) {
#if CONFIG_CFL
aom_write_symbol(w, uv_mode, frame_ctx->uv_mode_cdf[cfl_allowed][y_mode],
UV_INTRA_MODES - !cfl_allowed);
#else
uv_mode = get_uv_mode(uv_mode);
aom_write_symbol(w, uv_mode, frame_ctx->uv_mode_cdf[y_mode], UV_INTRA_MODES);
#endif
}
#if CONFIG_CFL
......@@ -1334,18 +1341,12 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row,
write_intra_mode(ec_ctx, bsize, mode, w);
if (is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
xd->plane[1].subsampling_y)) {
#if !CONFIG_CFL
write_intra_uv_mode(ec_ctx, mbmi->uv_mode, mode, w);
#if CONFIG_CFL
if (mbmi->uv_mode == UV_CFL_PRED) {
if (!is_cfl_allowed(mbmi)) {
aom_internal_error(
&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
"Chroma from Luma (CfL) cannot be signaled for a %dx%d block.",
block_size_wide[bsize], block_size_high[bsize]);
}
#else
write_intra_uv_mode(ec_ctx, mbmi->uv_mode, mode, is_cfl_allowed(mbmi), w);
if (mbmi->uv_mode == UV_CFL_PRED)
write_cfl_alphas(ec_ctx, mbmi->cfl_alpha_idx, mbmi->cfl_alpha_signs, w);
}
#endif
}
......@@ -1645,18 +1646,13 @@ static void write_mb_modes_kf(AV1_COMP *cpi, MACROBLOCKD *xd,
if (is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
xd->plane[1].subsampling_y)) {
#if !CONFIG_CFL
write_intra_uv_mode(ec_ctx, mbmi->uv_mode, mbmi->mode, w);
#if CONFIG_CFL
if (mbmi->uv_mode == UV_CFL_PRED) {
if (!is_cfl_allowed(mbmi)) {
aom_internal_error(
&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
"Chroma from Luma (CfL) cannot be signaled for a %dx%d block.",
block_size_wide[bsize], block_size_high[bsize]);
}
#else
write_intra_uv_mode(ec_ctx, mbmi->uv_mode, mbmi->mode, is_cfl_allowed(mbmi),
w);
if (mbmi->uv_mode == UV_CFL_PRED)
write_cfl_alphas(ec_ctx, mbmi->cfl_alpha_idx, mbmi->cfl_alpha_signs, w);
}
#endif
}
......
......@@ -293,7 +293,11 @@ struct macroblock {
int interintra_mode_cost[BLOCK_SIZE_GROUPS][INTERINTRA_MODES];
int motion_mode_cost[BLOCK_SIZES_ALL][MOTION_MODES];
int motion_mode_cost1[BLOCK_SIZES_ALL][2];
#if CONFIG_CFL
int intra_uv_mode_cost[CFL_ALLOWED_TYPES][INTRA_MODES][UV_INTRA_MODES];
#else
int intra_uv_mode_cost[INTRA_MODES][UV_INTRA_MODES];
#endif
int y_mode_costs[INTRA_MODES][INTRA_MODES][INTRA_MODES];
#if CONFIG_FILTER_INTRA
int filter_intra_cost[TX_SIZES_ALL][2];
......
......@@ -852,10 +852,22 @@ static void sum_intra_stats(FRAME_COUNTS *counts, MACROBLOCKD *xd,
}
#endif // CONFIG_EXT_INTRA && CONFIG_EXT_INTRA_MOD
#if CONFIG_ENTROPY_STATS
#if CONFIG_CFL
++counts->uv_mode[is_cfl_allowed(mbmi)][y_mode][uv_mode];
#else
++counts->uv_mode[y_mode][uv_mode];
#endif // CONFIG_CFL
#endif // CONFIG_ENTROPY_STATS
#if CONFIG_CFL
if (allow_update_cdf) {
const CFL_ALLOWED_TYPE cfl_allowed = is_cfl_allowed(mbmi);
update_cdf(fc->uv_mode_cdf[cfl_allowed][y_mode], uv_mode,
UV_INTRA_MODES - !cfl_allowed);
}
#else
if (allow_update_cdf)
update_cdf(fc->uv_mode_cdf[y_mode], uv_mode, UV_INTRA_MODES);
#endif // CONFIG_CFL
}
// TODO(anybody) We can add stats accumulation here to train entropy models for
......
......@@ -139,9 +139,16 @@ void av1_fill_mode_rates(AV1_COMMON *const cm, MACROBLOCK *x,
for (i = 0; i < BLOCK_SIZE_GROUPS; ++i)
av1_cost_tokens_from_cdf(x->mbmode_cost[i], fc->y_mode_cdf[i], NULL);
#if CONFIG_CFL
for (i = 0; i < CFL_ALLOWED_TYPES; ++i)
for (j = 0; j < INTRA_MODES; ++j)
av1_cost_tokens_from_cdf(x->intra_uv_mode_cost[i][j],
fc->uv_mode_cdf[i][j], NULL);
#else
for (i = 0; i < INTRA_MODES; ++i)
av1_cost_tokens_from_cdf(x->intra_uv_mode_cost[i], fc->uv_mode_cdf[i],
NULL);
#endif
#if CONFIG_FILTER_INTRA
av1_cost_tokens_from_cdf(x->filter_intra_mode_cost, fc->filter_intra_mode_cdf,
......
......@@ -5133,7 +5133,8 @@ static int cfl_rd_pick_alpha(MACROBLOCK *const x, const AV1_COMP *const cpi,
xd->cfl.use_dc_pred_cache = 1;
const int64_t mode_rd =
RDCOST(x->rdmult, x->intra_uv_mode_cost[mbmi->mode][UV_CFL_PRED], 0);
RDCOST(x->rdmult,
x->intra_uv_mode_cost[CFL_ALLOWED][mbmi->mode][UV_CFL_PRED], 0);
int64_t best_rd_uv[CFL_JOINT_SIGNS][CFL_PRED_PLANES];
int best_c[CFL_JOINT_SIGNS][CFL_PRED_PLANES];
#if CONFIG_DEBUG
......@@ -5211,7 +5212,7 @@ static int cfl_rd_pick_alpha(MACROBLOCK *const x, const AV1_COMP *const cpi,
best_rate_overhead = x->cfl_cost[best_joint_sign][CFL_PRED_U][u] +
x->cfl_cost[best_joint_sign][CFL_PRED_V][v];
#if CONFIG_DEBUG
xd->cfl.rate = x->intra_uv_mode_cost[mbmi->mode][UV_CFL_PRED] +
xd->cfl.rate = x->intra_uv_mode_cost[CFL_ALLOWED][mbmi->mode][UV_CFL_PRED] +
best_rate_overhead +
best_rate_uv[best_joint_sign][CFL_PRED_U] +
best_rate_uv[best_joint_sign][CFL_PRED_V];
......@@ -5273,9 +5274,14 @@ static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
#if CONFIG_EXT_INTRA
mbmi->angle_delta[1] = 0;
if (is_directional_mode && av1_use_angle_delta(mbmi->sb_type)) {
#if CONFIG_CFL
const int rate_overhead =
x->intra_uv_mode_cost[is_cfl_allowed(mbmi)][mbmi->mode][mode] +
#else
const int rate_overhead = x->intra_uv_mode_cost[mbmi->mode][mode] +
#endif // CONFIG_CFL
#if CONFIG_EXT_INTRA_MOD
0;
0;
#else
write_uniform_cost(2 * MAX_ANGLE_DELTA + 1, 0);
#endif // CONFIG_EXT_INTRA_MOD
......@@ -5290,13 +5296,17 @@ static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
#if CONFIG_EXT_INTRA
}
#endif // CONFIG_EXT_INTRA
this_rate =
tokenonly_rd_stats.rate + x->intra_uv_mode_cost[mbmi->mode][mode];
this_rate = tokenonly_rd_stats.rate +
#if CONFIG_CFL
x->intra_uv_mode_cost[is_cfl_allowed(mbmi)][mbmi->mode][mode] +
cfl_alpha_rate;
#else
x->intra_uv_mode_cost[mbmi->mode][mode];
#endif
#if CONFIG_CFL
if (mode == UV_CFL_PRED) {
assert(is_cfl_allowed(mbmi));
this_rate += cfl_alpha_rate;
#if CONFIG_DEBUG
if (!xd->lossless[mbmi->segment_id]) assert(xd->cfl.rate == this_rate);
#endif // CONFIG_DEBUG
......@@ -5331,10 +5341,15 @@ static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
if (try_palette) {
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[mbmi->mode][UV_DC_PRED],
best_palette_color_map, &best_mbmi, &best_rd,
rate, rate_tokenonly, distortion, skippable);
rd_pick_palette_intra_sbuv(
cpi, x,
#if CONFIG_CFL
x->intra_uv_mode_cost[is_cfl_allowed(mbmi)][mbmi->mode][UV_DC_PRED],
#else
x->intra_uv_mode_cost[mbmi->mode][UV_DC_PRED],
#endif
best_palette_color_map, &best_mbmi, &best_rd, rate, rate_tokenonly,
distortion, skippable);
}
*mbmi = best_mbmi;
......@@ -9674,7 +9689,13 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
rate2 = rate_y + intra_mode_cost[mbmi->mode];
if (!x->skip_chroma_rd)
rate2 += rate_uv + x->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
rate2 += rate_uv +
#if CONFIG_CFL
x->intra_uv_mode_cost[is_cfl_allowed(mbmi)][mbmi->mode]
[mbmi->uv_mode];
#else
x->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
#endif
if (try_palette && mbmi->mode == DC_PRED) {
const int bsize_ctx = av1_get_palette_bsize_ctx(bsize);
......
......@@ -356,13 +356,23 @@ int main(int argc, const char **argv) {
"static const aom_cdf_prob\n"
"default_if_y_mode_cdf[BLOCK_SIZE_GROUPS][CDF_SIZE(INTRA_MODES)]");
/* Intra mode (chroma) */
/* Intra mode (chroma) */
#if CONFIG_CFL
cts_each_dim[0] = CFL_ALLOWED_TYPES;
cts_each_dim[1] = INTRA_MODES;
cts_each_dim[2] = UV_INTRA_MODES;
optimize_cdf_table(&fc.uv_mode[0][0][0], probsfile, 3, cts_each_dim,
"static const aom_cdf_prob\n"
"default_uv_mode_cdf[CFL_ALLOWED_TYPES][INTRA_MODES]"
"[CDF_SIZE(UV_INTRA_MODES)]");
#else
cts_each_dim[0] = INTRA_MODES;
cts_each_dim[1] = UV_INTRA_MODES;
optimize_cdf_table(
&fc.uv_mode[0][0], probsfile, 2, cts_each_dim,
"static const aom_cdf_prob\n"
"default_uv_mode_cdf[INTRA_MODES][CDF_SIZE(UV_INTRA_MODES)]");
#endif
/* Partition */
cts_each_dim[0] = PARTITION_CONTEXTS;
......
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