Commit 80592c72 authored by Debargha Mukherjee's avatar Debargha Mukherjee
Browse files

Option to disable small tx size for intra chroma

This is essentially an implementation of Mozilla's big_chorma_tx
proposal, and CFL is already using this.

The option is turned on by default.
Also includes some associated refactoring.

AWCY Subset1 results:
PSNR | PSNR Cb | PSNR Cr | PSNR HVS |    SSIM | MS SSIM | CIEDE 2000
-0.0136 | -1.0317 | -1.3525 |  -0.0140 | -0.0188 | -0.0156 | -0.4665
Link:
https://beta.arewecompressedyet.com/?job=debargha-base-lvmap%402017-12-21T06%3A08%3A35.079Z&job=debargha-nosmltxi-lvmap%402017-12-21T06%3A10%3A57.767Z

Also resolves the bug below:

BUG=aomedia:1158

Change-Id: I9b806b57c008b7a9bb79357f0bc44dbb091e5278
parent 1b63eb33
......@@ -1418,7 +1418,7 @@ static void get_filter_level_and_masks_non420(
const int skip_this_r = skip_this && !block_edge_above;
TX_SIZE tx_size = (plane->plane_type == PLANE_TYPE_UV)
? av1_get_uv_tx_size(mbmi, plane)
? av1_get_uv_tx_size(mbmi, ss_x, ss_y)
: mbmi->tx_size;
const int skip_border_4x4_c =
......@@ -2013,7 +2013,8 @@ static TX_SIZE av1_get_transform_size(const MODE_INFO *const mi,
const MB_MODE_INFO *mbmi = &mi->mbmi;
TX_SIZE tx_size = (plane == AOM_PLANE_Y)
? mbmi->tx_size
: av1_get_uv_tx_size(mbmi, plane_ptr);
: av1_get_uv_tx_size(mbmi, plane_ptr->subsampling_x,
plane_ptr->subsampling_y);
assert(tx_size < TX_SIZES_ALL);
// mi_row and mi_col is the absolute position of the MI block.
......
......@@ -42,6 +42,9 @@ extern "C" {
// Disables vartx transform split for chroma
#define DISABLE_VARTX_FOR_CHROMA 1
// Disables small transform split for intra modes.
#define DISABLE_SMLTX_FOR_CHROMA_INTRA 1
// SEG_MASK_TYPES should not surpass 1 << MAX_SEG_MASK_BITS
typedef enum {
#if COMPOUND_SEGMENT_TYPE == 0
......@@ -1128,27 +1131,52 @@ static INLINE TX_SIZE depth_to_tx_size(int depth, BLOCK_SIZE bsize,
return tx_size;
}
static INLINE TX_SIZE av1_get_uv_tx_size(const MB_MODE_INFO *mbmi,
const struct macroblockd_plane *pd) {
#if CONFIG_CFL
if (!is_inter_block(mbmi) && mbmi->uv_mode == UV_CFL_PRED) {
const BLOCK_SIZE plane_bsize = get_plane_block_size(mbmi->sb_type, pd);
assert(plane_bsize < BLOCK_SIZES_ALL);
return max_txsize_rect_lookup[0][plane_bsize];
static INLINE TX_SIZE av1_get_max_uv_txsize(BLOCK_SIZE bsize, int is_inter,
int ss_x, int ss_y) {
const BLOCK_SIZE plane_bsize = ss_size_lookup[bsize][ss_x][ss_y];
assert(plane_bsize < BLOCK_SIZES_ALL);
TX_SIZE uv_tx = max_txsize_rect_lookup[is_inter][plane_bsize];
#if CONFIG_TX64X64
switch (uv_tx) {
case TX_64X64:
case TX_64X32:
case TX_32X64: return TX_32X32;
case TX_64X16: return TX_32X16;
case TX_16X64: return TX_16X32;
default: break;
}
#endif // CONFIG_TX64X64
return uv_tx;
}
static INLINE TX_SIZE av1_get_uv_tx_size(const MB_MODE_INFO *mbmi, int ss_x,
int ss_y) {
if (is_inter_block(mbmi)) {
#if DISABLE_VARTX_FOR_CHROMA
if (ss_x || ss_y)
return av1_get_max_uv_txsize(mbmi->sb_type, 1, ss_x, ss_y);
#endif // DISABLE_VARTX_FOR_CHROMA
} else {
#if DISABLE_SMLTX_FOR_CHROMA_INTRA
return av1_get_max_uv_txsize(mbmi->sb_type, 0, ss_x, ss_y);
#endif // DISABLE_SMLTX_FOR_CHROMA_INTRA
#if CONFIG_CFL
if (mbmi->uv_mode == UV_CFL_PRED)
return av1_get_max_uv_txsize(mbmi->sb_type, 0, ss_x, ss_y);
#endif
}
const TX_SIZE uv_txsize =
uv_txsize_lookup[mbmi->sb_type][mbmi->tx_size][pd->subsampling_x]
[pd->subsampling_y];
uv_txsize_lookup[mbmi->sb_type][mbmi->tx_size][ss_x][ss_y];
assert(uv_txsize != TX_INVALID);
return uv_txsize;
}
static INLINE TX_SIZE av1_get_tx_size(int plane, const MACROBLOCKD *xd) {
const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
if (xd->lossless[mbmi->segment_id]) return TX_4X4;
if (plane == 0) return mbmi->tx_size;
const MACROBLOCKD_PLANE *pd = &xd->plane[plane];
return av1_get_uv_tx_size(mbmi, pd);
return av1_get_uv_tx_size(mbmi, pd->subsampling_x, pd->subsampling_y);
}
void av1_reset_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col,
......
......@@ -2313,13 +2313,15 @@ void av1_predict_intra_block_facade(const AV1_COMMON *cm, MACROBLOCKD *xd,
#if CONFIG_CFL
if (plane != AOM_PLANE_Y && mbmi->uv_mode == UV_CFL_PRED) {
#if CONFIG_DEBUG
assert(blk_col == 0);
assert(blk_row == 0);
assert(is_cfl_allowed(mbmi));
const BLOCK_SIZE plane_bsize = get_plane_block_size(mbmi->sb_type, pd);
assert(plane_bsize < BLOCK_SIZES_ALL);
assert(block_size_wide[plane_bsize] == tx_size_wide[tx_size]);
assert(block_size_high[plane_bsize] == tx_size_high[tx_size]);
if (!xd->lossless[mbmi->segment_id]) {
assert(blk_col == 0);
assert(blk_row == 0);
assert(block_size_wide[plane_bsize] == tx_size_wide[tx_size]);
assert(block_size_high[plane_bsize] == tx_size_high[tx_size]);
}
#endif
CFL_CTX *const cfl = &xd->cfl;
CFL_PRED_TYPE pred_plane = get_cfl_pred_type(plane);
......
......@@ -3589,7 +3589,7 @@ static int super_block_uvrd(const AV1_COMP *const cpi, MACROBLOCK *x,
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
struct macroblockd_plane *const pd = &xd->plane[AOM_PLANE_U];
const TX_SIZE uv_tx_size = av1_get_uv_tx_size(mbmi, pd);
const TX_SIZE uv_tx_size = av1_get_tx_size(AOM_PLANE_U, xd);
int plane;
int is_cost_valid = 1;
av1_init_rd_stats(rd_stats);
......@@ -5413,8 +5413,10 @@ static int cfl_rd_pick_alpha(MACROBLOCK *const x, const AV1_COMP *const cpi,
const BLOCK_SIZE plane_bsize =
get_plane_block_size(mbmi->sb_type, &xd->plane[AOM_PLANE_U]);
assert(plane_bsize < BLOCK_SIZES_ALL);
assert(block_size_wide[plane_bsize] == tx_size_wide[tx_size]);
assert(block_size_high[plane_bsize] == tx_size_high[tx_size]);
if (!xd->lossless[mbmi->segment_id]) {
assert(block_size_wide[plane_bsize] == tx_size_wide[tx_size]);
assert(block_size_high[plane_bsize] == tx_size_high[tx_size]);
}
#endif
xd->cfl.use_dc_pred_cache = 1;
......@@ -5551,8 +5553,7 @@ static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
if (mode == UV_CFL_PRED) {
if (!is_cfl_allowed(mbmi)) continue;
assert(!is_directional_mode);
const TX_SIZE uv_tx_size =
av1_get_uv_tx_size(mbmi, &xd->plane[AOM_PLANE_U]);
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);
if (cfl_alpha_rate == INT_MAX) continue;
}
......@@ -5585,7 +5586,7 @@ static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
assert(is_cfl_allowed(mbmi));
this_rate += cfl_alpha_rate;
#if CONFIG_DEBUG
assert(xd->cfl.rate == this_rate);
if (!xd->lossless[mbmi->segment_id]) assert(xd->cfl.rate == this_rate);
#endif // CONFIG_DEBUG
}
#endif
......@@ -8890,7 +8891,6 @@ void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
const AV1_COMMON *const cm = &cpi->common;
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
struct macroblockd_plane *const pd = xd->plane;
int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
int y_skip = 0, uv_skip = 0;
int64_t dist_y = 0, dist_uv = 0;
......@@ -8924,8 +8924,7 @@ void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
xd->cfl.store_y = 0;
}
#endif // CONFIG_CFL
max_uv_tx_size = uv_txsize_lookup[bsize][mbmi->tx_size][pd[1].subsampling_x]
[pd[1].subsampling_y];
max_uv_tx_size = av1_get_tx_size(AOM_PLANE_U, xd);
init_sbuv_mode(mbmi);
if (!x->skip_chroma_rd)
rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
......@@ -9792,7 +9791,6 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
if (ref_frame == INTRA_FRAME) {
RD_STATS rd_stats_y;
TX_SIZE uv_tx;
struct macroblockd_plane *const pd = &xd->plane[1];
#if CONFIG_EXT_INTRA
is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
if (is_directional_mode && av1_use_angle_delta(bsize)) {
......@@ -9884,8 +9882,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
if (rate_y == INT_MAX) continue;
uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][pd->subsampling_x]
[pd->subsampling_y];
uv_tx = av1_get_tx_size(AOM_PLANE_U, xd);
if (rate_uv_intra[uv_tx] == INT_MAX) {
choose_intra_uv_mode(cpi, x, bsize, uv_tx, &rate_uv_intra[uv_tx],
&rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
......@@ -10604,8 +10601,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
rows * cols * sizeof(best_palette_color_map[0]));
super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
if (rd_stats_y.rate == INT_MAX) goto PALETTE_EXIT;
uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
[xd->plane[1].subsampling_y];
uv_tx = av1_get_tx_size(AOM_PLANE_U, xd);
if (rate_uv_intra[uv_tx] == INT_MAX) {
choose_intra_uv_mode(cpi, x, bsize, uv_tx, &rate_uv_intra[uv_tx],
&rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
......
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