Commit 41d37c20 authored by Cheng Chen's avatar Cheng Chen

Use arithmetic coding (cdf) to code sb filter lvl

Change-Id: I5446327378938128f27186015619a079c2845d53
parent 5c3b0f86
......@@ -465,6 +465,9 @@ typedef struct MB_MODE_INFO {
BOUNDARY_TYPE boundary_info;
#if CONFIG_LPF_SB
uint8_t filt_lvl;
int reuse_sb_lvl;
int sign;
int delta;
#endif
} MB_MODE_INFO;
......
......@@ -2313,6 +2313,11 @@ void av1_average_tile_intra_cdfs(FRAME_CONTEXT *fc, FRAME_CONTEXT *ec_ctxs[],
AVERAGE_TILE_CDFS(quarter_tx_size_cdf)
#endif
#endif
#if CONFIG_LPF_SB
AVERAGE_TILE_CDFS(lpf_reuse_cdf);
AVERAGE_TILE_CDFS(lpf_delta_cdf);
AVERAGE_TILE_CDFS(lpf_sign_cdf);
#endif // CONFIG_LPF_SB
}
void av1_average_tile_inter_cdfs(AV1_COMMON *cm, FRAME_CONTEXT *fc,
......@@ -2381,6 +2386,11 @@ void av1_average_tile_inter_cdfs(AV1_COMMON *cm, FRAME_CONTEXT *fc,
#if CONFIG_MRC_TX
AVERAGE_TILE_CDFS(mrc_mask_inter_cdf)
#endif // CONFIG_MRC_TX
#if CONFIG_LPF_SB
AVERAGE_TILE_CDFS(lpf_reuse_cdf);
AVERAGE_TILE_CDFS(lpf_delta_cdf);
AVERAGE_TILE_CDFS(lpf_sign_cdf);
#endif // CONFIG_LPF_SB
}
#if CONFIG_PVQ
......
......@@ -5622,6 +5622,40 @@ const aom_cdf_prob default_kf_y_mode_cdf[INTRA_MODES][INTRA_MODES][CDF_SIZE(
};
#endif // CONFIG_KF_CTX
#if CONFIG_LPF_SB
static const aom_cdf_prob default_lpf_reuse_cdf[LPF_REUSE_CONTEXT][CDF_SIZE(
2)] = { { AOM_ICDF(8192), AOM_ICDF(32768), 0 },
{ AOM_ICDF(4096), AOM_ICDF(32768), 0 } };
static const aom_cdf_prob
default_lpf_delta_cdf[LPF_DELTA_CONTEXT][CDF_SIZE(DELTA_RANGE)] = {
{ AOM_ICDF(4096), AOM_ICDF(7680), AOM_ICDF(10816), AOM_ICDF(13560),
AOM_ICDF(15961), AOM_ICDF(18062), AOM_ICDF(19900), AOM_ICDF(32768), 0 },
{ AOM_ICDF(4096), AOM_ICDF(7680), AOM_ICDF(10816), AOM_ICDF(13560),
AOM_ICDF(15961), AOM_ICDF(18062), AOM_ICDF(19900), AOM_ICDF(32768), 0 },
{ AOM_ICDF(4096), AOM_ICDF(7680), AOM_ICDF(10816), AOM_ICDF(13560),
AOM_ICDF(15961), AOM_ICDF(18062), AOM_ICDF(19900), AOM_ICDF(32768), 0 },
{ AOM_ICDF(4096), AOM_ICDF(7680), AOM_ICDF(10816), AOM_ICDF(13560),
AOM_ICDF(15961), AOM_ICDF(18062), AOM_ICDF(19900), AOM_ICDF(32768), 0 },
{ AOM_ICDF(4096), AOM_ICDF(7680), AOM_ICDF(10816), AOM_ICDF(13560),
AOM_ICDF(15961), AOM_ICDF(18062), AOM_ICDF(19900), AOM_ICDF(32768), 0 },
{ AOM_ICDF(4096), AOM_ICDF(7680), AOM_ICDF(10816), AOM_ICDF(13560),
AOM_ICDF(15961), AOM_ICDF(18062), AOM_ICDF(19900), AOM_ICDF(32768), 0 },
{ AOM_ICDF(4096), AOM_ICDF(7680), AOM_ICDF(10816), AOM_ICDF(13560),
AOM_ICDF(15961), AOM_ICDF(18062), AOM_ICDF(19900), AOM_ICDF(32768), 0 },
{ AOM_ICDF(4096), AOM_ICDF(7680), AOM_ICDF(10816), AOM_ICDF(13560),
AOM_ICDF(15961), AOM_ICDF(18062), AOM_ICDF(19900), AOM_ICDF(32768), 0 }
};
static const aom_cdf_prob
default_lpf_sign_cdf[LPF_REUSE_CONTEXT][LPF_SIGN_CONTEXT][CDF_SIZE(2)] = {
{ { AOM_ICDF(6554), AOM_ICDF(32768), 0 },
{ AOM_ICDF(26214), AOM_ICDF(32768), 0 } },
{ { AOM_ICDF(16384), AOM_ICDF(32768), 0 },
{ AOM_ICDF(16384), AOM_ICDF(32768), 0 } }
};
#endif // CONFIG_LPF_SB
static void init_mode_probs(FRAME_CONTEXT *fc) {
av1_copy(fc->partition_prob, default_partition_probs);
av1_copy(fc->intra_inter_prob, default_intra_inter_p);
......@@ -5798,6 +5832,11 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
#if CONFIG_INTRABC
av1_copy(fc->intrabc_cdf, default_intrabc_cdf);
#endif
#if CONFIG_LPF_SB
av1_copy(fc->lpf_reuse_cdf, default_lpf_reuse_cdf);
av1_copy(fc->lpf_delta_cdf, default_lpf_delta_cdf);
av1_copy(fc->lpf_sign_cdf, default_lpf_sign_cdf);
#endif // CONFIG_LPF_SB
}
void av1_adapt_inter_frame_probs(AV1_COMMON *cm) {
......
......@@ -405,6 +405,11 @@ typedef struct frame_contexts {
aom_cdf_prob cfl_sign_cdf[CDF_SIZE(CFL_JOINT_SIGNS)];
aom_cdf_prob cfl_alpha_cdf[CFL_ALPHA_CONTEXTS][CDF_SIZE(CFL_ALPHABET_SIZE)];
#endif
#if CONFIG_LPF_SB
aom_cdf_prob lpf_reuse_cdf[LPF_REUSE_CONTEXT][CDF_SIZE(2)];
aom_cdf_prob lpf_delta_cdf[LPF_DELTA_CONTEXT][CDF_SIZE(DELTA_RANGE)];
aom_cdf_prob lpf_sign_cdf[LPF_REUSE_CONTEXT][LPF_SIGN_CONTEXT][CDF_SIZE(2)];
#endif // CONFIG_LPF_SB
} FRAME_CONTEXT;
typedef struct FRAME_COUNTS {
......@@ -556,6 +561,11 @@ typedef struct FRAME_COUNTS {
#if CONFIG_FILTER_INTRA
unsigned int filter_intra[PLANE_TYPES][2];
#endif // CONFIG_FILTER_INTRA
#if CONFIG_LPF_SB
unsigned int lpf_reuse[LPF_REUSE_CONTEXT][2];
unsigned int lpf_delta[LPF_DELTA_CONTEXT][DELTA_RANGE];
unsigned int lpf_sign[LPF_SIGN_CONTEXT][2];
#endif // CONFIG_LPF_SB
} FRAME_COUNTS;
#if CONFIG_KF_CTX
......
......@@ -92,8 +92,13 @@ extern "C" {
#if CONFIG_LPF_SB
#define LPF_DELTA_BITS 3
#define LPF_STEP 2
#define DELTA_RANGE (1 << LPF_DELTA_BITS)
#define MAX_LPF_OFFSET (LPF_STEP * ((1 << LPF_DELTA_BITS) - 1))
#define LPF_REUSE_CONTEXT 2
#define LPF_DELTA_CONTEXT DELTA_RANGE
#define LPF_SIGN_CONTEXT 2
// Half of maximum loop filter length (15-tap)
#define FILT_BOUNDARY_OFFSET 8
#define FILT_BOUNDARY_MI_OFFSET (FILT_BOUNDARY_OFFSET >> MI_SIZE_LOG2)
......
......@@ -2579,6 +2579,9 @@ static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd,
int filt_lvl;
if (mi_row == 0 && mi_col == 0) {
filt_lvl = aom_read_literal(r, 6, ACCT_STR);
cm->mi_grid_visible[0]->mbmi.reuse_sb_lvl = 0;
cm->mi_grid_visible[0]->mbmi.delta = 0;
cm->mi_grid_visible[0]->mbmi.sign = 0;
} else {
int prev_mi_row, prev_mi_col;
if (mi_col - MAX_MIB_SIZE < 0) {
......@@ -2589,22 +2592,37 @@ static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd,
prev_mi_col = mi_col - MAX_MIB_SIZE;
}
const uint8_t prev_lvl =
cm->mi_grid_visible[prev_mi_row * cm->mi_stride + prev_mi_col]
->mbmi.filt_lvl;
MB_MODE_INFO *curr_mbmi =
&cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col]->mbmi;
MB_MODE_INFO *prev_mbmi =
&cm->mi_grid_visible[prev_mi_row * cm->mi_stride + prev_mi_col]->mbmi;
const uint8_t prev_lvl = prev_mbmi->filt_lvl;
const int reuse_ctx = prev_mbmi->reuse_sb_lvl;
const int reuse_prev_lvl = aom_read_symbol(
r, xd->tile_ctx->lpf_reuse_cdf[reuse_ctx], 2, ACCT_STR);
curr_mbmi->reuse_sb_lvl = reuse_prev_lvl;
const int reuse_prev_lvl = aom_read_literal(r, 1, ACCT_STR);
if (reuse_prev_lvl) {
filt_lvl = prev_lvl;
curr_mbmi->delta = 0;
curr_mbmi->sign = 0;
} else {
unsigned int delta = aom_read_literal(r, LPF_DELTA_BITS, ACCT_STR);
const int delta_ctx = prev_mbmi->delta;
unsigned int delta = aom_read_symbol(
r, xd->tile_ctx->lpf_delta_cdf[delta_ctx], DELTA_RANGE, ACCT_STR);
curr_mbmi->delta = delta;
delta *= LPF_STEP;
if (delta) {
const int sign = aom_read_literal(r, 1, ACCT_STR);
const int sign_ctx = prev_mbmi->sign;
const int sign = aom_read_symbol(
r, xd->tile_ctx->lpf_sign_cdf[reuse_ctx][sign_ctx], 2, ACCT_STR);
curr_mbmi->sign = sign;
filt_lvl = sign ? prev_lvl + delta : prev_lvl - delta;
} else {
filt_lvl = prev_lvl;
curr_mbmi->sign = 0;
}
}
}
......
......@@ -3153,10 +3153,10 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile,
// send filter level for each superblock (64x64)
if (bsize == cm->sb_size) {
if (mi_row == 0 && mi_col == 0) {
aom_write_literal(
w,
cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col]->mbmi.filt_lvl,
6);
aom_write_literal(w, cm->mi_grid_visible[0]->mbmi.filt_lvl, 6);
cm->mi_grid_visible[0]->mbmi.reuse_sb_lvl = 0;
cm->mi_grid_visible[0]->mbmi.delta = 0;
cm->mi_grid_visible[0]->mbmi.sign = 0;
} else {
int prev_mi_row, prev_mi_col;
if (mi_col - MAX_MIB_SIZE < 0) {
......@@ -3174,13 +3174,31 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile,
const uint8_t curr_lvl = curr_mbmi->filt_lvl;
const uint8_t prev_lvl = prev_mbmi->filt_lvl;
aom_write_literal(w, curr_lvl == prev_lvl, 1);
if (curr_lvl != prev_lvl) {
const int sign = curr_lvl > prev_lvl;
const unsigned int delta = abs(curr_lvl - prev_lvl) / LPF_STEP;
const int reuse_prev_lvl = curr_lvl == prev_lvl;
const int reuse_ctx = prev_mbmi->reuse_sb_lvl;
curr_mbmi->reuse_sb_lvl = reuse_prev_lvl;
aom_write_symbol(w, reuse_prev_lvl,
xd->tile_ctx->lpf_reuse_cdf[reuse_ctx], 2);
aom_write_literal(w, delta, LPF_DELTA_BITS);
if (delta) aom_write_literal(w, sign, 1);
if (reuse_prev_lvl) {
curr_mbmi->delta = 0;
curr_mbmi->sign = 0;
} else {
const unsigned int delta = abs(curr_lvl - prev_lvl) / LPF_STEP;
const int delta_ctx = prev_mbmi->delta;
curr_mbmi->delta = delta;
aom_write_symbol(w, delta, xd->tile_ctx->lpf_delta_cdf[delta_ctx],
DELTA_RANGE);
if (delta) {
const int sign = curr_lvl > prev_lvl;
const int sign_ctx = prev_mbmi->sign;
curr_mbmi->sign = sign;
aom_write_symbol(w, sign,
xd->tile_ctx->lpf_sign_cdf[reuse_ctx][sign_ctx], 2);
} else {
curr_mbmi->sign = 0;
}
}
}
}
......
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