Commit a47cd6c0 authored by Dake He's avatar Dake He Committed by Yaowu Xu

[eob first] code eob first

This commit makes the following changes to level-map coding
	1. Encode and decode eob position first
	2. Context derivation for non-zero flags
	3. Single pass in optimize-txb

lowres 0.33% gain

Change-Id: Ia2b6cfd70425f49ac021454d42d5950bfcfab50a
parent 2e868abe
This diff is collapsed.
......@@ -320,3 +320,49 @@ void av1_init_lv_map(AV1_COMMON *cm) {
}
}
}
#if CONFIG_EOB_FIRST
const int16_t k_eob_group_start[12] = { 0, 1, 2, 3, 5, 9,
17, 33, 65, 129, 257, 513 };
const int16_t k_eob_offset_bits[12] = { 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int get_eob_pos_ctx(int eob_token) { return eob_token - 1; }
int16_t get_eob_pos_token(int eob, int16_t *extra) {
int16_t t;
if (eob < 3) {
t = eob;
} else {
t = 3;
if (eob > 4) {
t++;
}
if (eob > 8) {
t++;
}
if (eob > 16) {
t++;
}
if (eob > 32) {
t++;
}
if (eob > 64) {
t++;
}
if (eob > 128) {
t++;
}
if (eob > 256) {
t++;
}
if (eob > 512) {
t++;
}
}
*extra = eob - k_eob_group_start[t];
return t;
}
#endif
......@@ -15,6 +15,13 @@
#define REDUCE_CONTEXT_DEPENDENCY 0
#define MIN_SCAN_IDX_REDUCE_CONTEXT_DEPENDENCY 0
#if CONFIG_EOB_FIRST
extern const int16_t k_eob_group_start[12];
extern const int16_t k_eob_offset_bits[12];
int16_t get_eob_pos_token(int eob, int16_t *extra);
int get_eob_pos_ctx(int eob_token);
#endif
extern const int16_t av1_coeff_band_4x4[16];
extern const int16_t av1_coeff_band_8x8[64];
......@@ -193,12 +200,21 @@ static INLINE int get_base_ctx(const uint8_t *const levels,
}
#define BR_CONTEXT_POSITION_NUM 8 // Base range coefficient context
#if CONFIG_EOB_FIRST
static const int br_ref_offset[BR_CONTEXT_POSITION_NUM][2] = {
/* clang-format off*/
{ -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, -1 },
{ 0, 1 }, { 1, -1 }, { 1, 0 }, { 1, 1 },
/* clang-format on*/
};
#else
static const int br_ref_offset[BR_CONTEXT_POSITION_NUM][2] = {
/* clang-format off*/
{ -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, -1 },
{ 0, 1 }, { 1, -1 }, { 1, 0 }, { 1, 1 },
/* clang-format on*/
};
#endif
static const int br_level_map[9] = {
0, 0, 1, 1, 2, 2, 3, 3, 3,
......@@ -303,6 +319,45 @@ static INLINE int get_br_ctx_coeff(const tran_low_t *const tcoeffs,
}
#define SIG_REF_OFFSET_NUM 7
#if CONFIG_EOB_FIRST
static int sig_ref_offset[SIG_REF_OFFSET_NUM][2] = {
{ 2, 1 }, { 2, 0 }, { 1, 2 }, { 1, 1 }, { 1, 0 }, { 0, 2 }, { 0, 1 },
};
static int sig_ref_offset_vert[SIG_REF_OFFSET_NUM][2] = {
{ 2, 1 }, { 2, 0 }, { 3, 0 }, { 1, 1 }, { 1, 0 }, { 4, 0 }, { 0, 1 },
};
static int sig_ref_offset_horiz[SIG_REF_OFFSET_NUM][2] = {
{ 0, 3 }, { 0, 4 }, { 1, 2 }, { 1, 1 }, { 1, 0 }, { 0, 2 }, { 0, 1 },
};
static INLINE int get_nz_count(const tran_low_t *tcoeffs, int bwl, int height,
int row, int col, TX_CLASS tx_class,
const int coeff_is_byte_flag) {
int count = 0;
for (int idx = 0; idx < SIG_REF_OFFSET_NUM; ++idx) {
const int ref_row = row + ((tx_class == TX_CLASS_2D)
? sig_ref_offset[idx][0]
: ((tx_class == TX_CLASS_VERT)
? sig_ref_offset_vert[idx][0]
: sig_ref_offset_horiz[idx][0]));
const int ref_col = col + ((tx_class == TX_CLASS_2D)
? sig_ref_offset[idx][1]
: ((tx_class == TX_CLASS_VERT)
? sig_ref_offset_vert[idx][1]
: sig_ref_offset_horiz[idx][1]));
if (ref_row < 0 || ref_col < 0 || ref_row >= height ||
ref_col >= (1 << bwl))
continue;
const int nb_pos = (ref_row << bwl) + ref_col;
count +=
((coeff_is_byte_flag ? ((const uint8_t *)tcoeffs)[nb_pos]
: ((const tran_low_t *)tcoeffs)[nb_pos]) != 0);
}
return count;
}
#else
static int sig_ref_offset[SIG_REF_OFFSET_NUM][2] = {
{ -2, -1 }, { -2, 0 }, { -1, -2 }, { -1, -1 },
{ -1, 0 }, { 0, -2 }, { 0, -1 },
......@@ -347,6 +402,8 @@ static INLINE int get_nz_count(const void *const tcoeffs, const int bwl,
}
#endif
#endif
static INLINE TX_CLASS get_tx_class(TX_TYPE tx_type) {
switch (tx_type) {
#if CONFIG_EXT_TX
......@@ -365,7 +422,11 @@ static INLINE TX_CLASS get_tx_class(TX_TYPE tx_type) {
// count to ctx
static INLINE int get_nz_map_ctx_from_count(int count,
int coeff_idx, // raster order
int bwl, TX_TYPE tx_type) {
int bwl,
#if CONFIG_EOB_FIRST
int height,
#endif
TX_TYPE tx_type) {
(void)tx_type;
const int row = coeff_idx >> bwl;
const int col = coeff_idx - (row << bwl);
......@@ -383,6 +444,32 @@ static INLINE int get_nz_map_ctx_from_count(int count,
int offset = 0;
#endif
#if CONFIG_EOB_FIRST
(void)height;
ctx = (count + 1) >> 1;
if (tx_class == TX_CLASS_2D) {
{
if (row == 0 && col == 0) return offset + 0;
if (row + col < 2) return offset + ctx + 1;
if (row + col < 4) return offset + 5 + ctx + 1;
return offset + 11 + AOMMIN(ctx, 4);
}
} else {
if (tx_class == TX_CLASS_VERT) {
if (row == 0) return offset + ctx;
if (row < 2) return offset + 5 + ctx;
return offset + 10 + ctx;
} else {
if (col == 0) return offset + ctx;
if (col < 2) return offset + 5 + ctx;
return offset + 10 + ctx;
}
}
#else
if (row == 0 && col == 0) return offset + 0;
if (row == 0 && col == 1) return offset + 1 + count;
......@@ -416,6 +503,7 @@ static INLINE int get_nz_map_ctx_from_count(int count,
assert(12 + ctx < 16);
return offset + 12 + ctx;
#endif
}
static INLINE int get_nz_map_ctx(const void *const tcoeffs, const int scan_idx,
......@@ -441,10 +529,19 @@ static INLINE int get_nz_map_ctx(const void *const tcoeffs, const int scan_idx,
const int count = get_nz_count(tcoeffs, bwl, height, row, col,
coeff_is_byte_flag, prev_row, prev_col);
#else
const int count =
get_nz_count(tcoeffs, bwl, height, row, col, coeff_is_byte_flag);
#if CONFIG_EOB_FIRST
int tx_class = get_tx_class(tx_type);
int count = get_nz_count(tcoeffs, bwl, height, row, col, tx_class,
coeff_is_byte_flag);
#else
int count = get_nz_count(tcoeffs, bwl, height, row, col, coeff_is_byte_flag);
#endif
#endif
return get_nz_map_ctx_from_count(count, coeff_idx, bwl,
#if CONFIG_EOB_FIRST
height,
#endif
return get_nz_map_ctx_from_count(count, coeff_idx, bwl, tx_type);
tx_type);
}
static INLINE int get_eob_ctx(const int coeff_idx, // raster order
......
......@@ -267,6 +267,16 @@ static INLINE int read_nz_map_horiz(aom_reader *r, uint8_t *levels, int plane,
}
#endif
#if CONFIG_EOB_FIRST
static INLINE int rec_eob_pos(int16_t eob_token, int16_t extra) {
int eob = k_eob_group_start[eob_token];
if (eob > 2) {
eob += extra;
}
return eob;
}
#endif
uint8_t av1_read_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd,
aom_reader *r, int blk_row, int blk_col, int block,
int plane, tran_low_t *tcoeffs, TXB_CTX *txb_ctx,
......@@ -327,6 +337,76 @@ uint8_t av1_read_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd,
const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, mbmi);
const int16_t *scan = scan_order->scan;
#if CONFIG_EOB_FIRST
unsigned int(*nz_map_count)[SIG_COEF_CONTEXTS][2] =
(counts) ? &counts->nz_map[txs_ctx][plane_type] : NULL;
int16_t dummy;
int16_t max_eob_pt = get_eob_pos_token(seg_eob, &dummy);
int16_t eob_extra = 0;
int16_t eob_pt = 0;
int is_equal = 0;
for (int i = 1; i < max_eob_pt; i++) {
int eob_pos_ctx = get_eob_pos_ctx(i);
is_equal = av1_read_record_bin(
counts, r, ec_ctx->eob_flag_cdf[txs_ctx][plane_type][eob_pos_ctx], 2,
ACCT_STR);
// aom_read_symbol(r,
// ec_ctx->eob_flag_cdf[AOMMIN(txs_ctx,3)][plane_type][eob_pos_ctx], 2,
// ACCT_STR);
if (counts) ++counts->eob_flag[txs_ctx][plane_type][eob_pos_ctx][is_equal];
if (is_equal) {
eob_pt = i;
break;
}
}
if (is_equal == 0) {
eob_pt = max_eob_pt;
}
// printf("Dec: ");
if (k_eob_offset_bits[eob_pt] > 0) {
for (int i = 0; i < k_eob_offset_bits[eob_pt]; i++) {
int eob_shift = k_eob_offset_bits[eob_pt] - 1 - i;
int bit = av1_read_record_bit(counts, r, ACCT_STR);
if (bit) {
eob_extra += (1 << eob_shift);
}
// printf("%d ", bit);
}
}
*eob = rec_eob_pos(eob_pt, eob_extra);
// printf("=>[%d, %d], (%d, %d)\n", seg_eob, *eob, eob_pt, eob_extra);
for (int i = 0; i < *eob; ++i) {
c = *eob - 1 - i;
int is_nz;
int coeff_ctx = get_nz_map_ctx(levels, c, scan, bwl, height, tx_type, 1);
// int eob_ctx = get_eob_ctx(tcoeffs, scan[c], txs_ctx, tx_type);
if (c < *eob - 1) {
#if LV_MAP_PROB
is_nz = av1_read_record_bin(
counts, r, ec_ctx->nz_map_cdf[txs_ctx][plane_type][coeff_ctx], 2,
ACCT_STR);
#else
is_nz = aom_read(r, nz_map[coeff_ctx], ACCT_STR);
#endif
} else {
is_nz = 1;
}
// set non-zero coefficient map.
levels[scan[c]] = is_nz;
if (counts) ++(*nz_map_count)[coeff_ctx][is_nz];
}
#else
#if CONFIG_CTX1D
const int16_t *iscan = scan_order->iscan;
TX_CLASS tx_class = get_tx_class(tx_type);
......@@ -358,6 +438,8 @@ uint8_t av1_read_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd,
}
#else
*eob = read_nz_map(r, levels, plane, scan, tx_size, tx_type, ec_ctx, counts);
#endif
#endif
*max_scan_line = *eob;
......
......@@ -165,6 +165,7 @@ static int optimize_b_greedy(const AV1_COMMON *cm, MACROBLOCK *mb, int plane,
mb->token_head_costs[txsize_sqr_map[tx_size]][plane_type][ref];
int(*tail_token_costs)[COEFF_CONTEXTS][TAIL_TOKENS] =
mb->token_tail_costs[txsize_sqr_map[tx_size]][plane_type][ref];
const int64_t rdmult = (mb->rdmult * plane_rd_mult[ref][plane_type]) >> 1;
int64_t rate0, rate1;
int64_t eob_cost0, eob_cost1;
......
This diff is collapsed.
......@@ -133,6 +133,7 @@ set(CONFIG_DEPENDENT_HORZTILES 0 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_DIST_8X8 1 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_DUAL_FILTER 1 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_ENTROPY_STATS 0 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_EOB_FIRST 0 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_EXT_COMP_REFS 1 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_EXT_DELTA_Q 1 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_EXT_INTRA 1 CACHE NUMBER "AV1 experiment flag.")
......
......@@ -35,6 +35,15 @@ macro (fix_experiment_configs)
endif ()
endif ()
if (CONFIG_EOB_FIRST)
if (NOT CONFIG_EXT_TX)
change_config_and_warn(CONFIG_EXT_TX 1 CONFIG_EOB_FIRST)
endif ()
if (NOT CONFIG_LV_MAP)
change_config_and_warn(CONFIG_LV_MAP 1 CONFIG_EOB_FIRST)
endif ()
endif ()
if (CONFIG_DAALA_TX)
set(CONFIG_DAALA_TX4 1)
set(CONFIG_DAALA_TX8 1)
......
......@@ -347,6 +347,7 @@ EXPERIMENT_LIST="
ext_warped_motion
horzonly_frame_superres
simple_bwd_adapt
eob_first
"
CONFIG_LIST="
dependency_tracking
......@@ -546,6 +547,8 @@ post_process_cmdline() {
# Fix up experiment dependencies
enabled lv_map && disable_feature mrc_tx
enabled eob_first && enable_feature lv_map
enabled eob_first && enable_feature ext_tx
enabled coef_interleave && disable_feature mrc_tx
enabled mrc_tx && enable_feature ext_tx
enabled txk_sel && soft_enable lv_map
......
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