Update txb context calculation code Split coefficients into signs (0 or 1) and levels (0 to 255), so that they both can be fit in 1-byte. Change-Id: I0f486368b7b819a77aaddda4710e83189e53fc55
diff --git a/av1/common/txb_common.h b/av1/common/txb_common.h index 3bf8f8c..aa06495 100644 --- a/av1/common/txb_common.h +++ b/av1/common/txb_common.h
@@ -32,7 +32,7 @@ return txsize_sqr_up_map[tx_size]; } -static int base_ref_offset[BASE_CONTEXT_POSITION_NUM][2] = { +static const int base_ref_offset[BASE_CONTEXT_POSITION_NUM][2] = { /* clang-format off*/ { -2, 0 }, { -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, -2 }, { 0, -1 }, { 0, 1 }, { 0, 2 }, { 1, -1 }, { 1, 0 }, { 1, 1 }, { 2, 0 } @@ -110,10 +110,30 @@ } } -static INLINE int get_level_count_mag(int *mag, const tran_low_t *tcoeffs, - int bwl, int height, int row, int col, - int level, int (*nb_offset)[2], - int nb_num) { +static INLINE int get_level_count_mag( + int *const mag, const uint8_t *const levels, const int bwl, + const int height, const int row, const int col, const int level, + const int (*nb_offset)[2], const int nb_num) { + const int stride = 1 << bwl; + int count = 0; + *mag = 0; + for (int idx = 0; idx < nb_num; ++idx) { + const int ref_row = row + nb_offset[idx][0]; + const int ref_col = col + nb_offset[idx][1]; + if (ref_row < 0 || ref_col < 0 || ref_row >= height || ref_col >= stride) + continue; + const int pos = (ref_row << bwl) + ref_col; + count += levels[pos] > level; + if (nb_offset[idx][0] >= 0 && nb_offset[idx][1] >= 0) + *mag = AOMMAX(*mag, levels[pos]); + } + return count; +} + +static INLINE int get_level_count_mag_coeff( + int *const mag, const tran_low_t *const tcoeffs, const int bwl, + const int height, const int row, const int col, const int level, + const int (*nb_offset)[2], const int nb_num) { const int stride = 1 << bwl; int count = 0; *mag = 0; @@ -154,23 +174,23 @@ return ctx_idx; } -static INLINE int get_base_ctx(const tran_low_t *tcoeffs, - int c, // raster order +static INLINE int get_base_ctx(const uint8_t *const levels, + const int c, // raster order const int bwl, const int height, const int level) { const int row = c >> bwl; const int col = c - (row << bwl); const int level_minus_1 = level - 1; int mag; - int count = - get_level_count_mag(&mag, tcoeffs, bwl, height, row, col, level_minus_1, + const int count = + get_level_count_mag(&mag, levels, bwl, height, row, col, level_minus_1, base_ref_offset, BASE_CONTEXT_POSITION_NUM); - int ctx_idx = get_base_ctx_from_count_mag(row, col, count, mag > level); + const int ctx_idx = get_base_ctx_from_count_mag(row, col, count, mag > level); return ctx_idx; } #define BR_CONTEXT_POSITION_NUM 8 // Base range coefficient context -static int br_ref_offset[BR_CONTEXT_POSITION_NUM][2] = { +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 }, @@ -251,7 +271,7 @@ return 8 + ctx; } -static INLINE int get_br_ctx(const tran_low_t *tcoeffs, +static INLINE int get_br_ctx(const uint8_t *const levels, const int c, // raster order const int bwl, const int height) { const int row = c >> bwl; @@ -259,12 +279,26 @@ const int level_minus_1 = NUM_BASE_LEVELS; int mag; const int count = - get_level_count_mag(&mag, tcoeffs, bwl, height, row, col, level_minus_1, + get_level_count_mag(&mag, levels, bwl, height, row, col, level_minus_1, br_ref_offset, BR_CONTEXT_POSITION_NUM); const int ctx = get_br_ctx_from_count_mag(row, col, count, mag); return ctx; } +static INLINE int get_br_ctx_coeff(const tran_low_t *const tcoeffs, + const int c, // raster order + const int bwl, const int height) { + const int row = c >> bwl; + const int col = c - (row << bwl); + const int level_minus_1 = NUM_BASE_LEVELS; + int mag; + const int count = get_level_count_mag_coeff(&mag, tcoeffs, bwl, height, row, + col, level_minus_1, br_ref_offset, + BR_CONTEXT_POSITION_NUM); + const int ctx = get_br_ctx_from_count_mag(row, col, count, mag); + return ctx; +} + #define SIG_REF_OFFSET_NUM 7 static int sig_ref_offset[SIG_REF_OFFSET_NUM][2] = { { -2, -1 }, { -2, 0 }, { -1, -2 }, { -1, -1 },
diff --git a/av1/decoder/decodetxb.c b/av1/decoder/decodetxb.c index 13f944b..df8bc11 100644 --- a/av1/decoder/decodetxb.c +++ b/av1/decoder/decodetxb.c
@@ -289,6 +289,9 @@ const int bwl = b_width_log2_lookup[txsize_to_bsize[tx_size]] + 2; const int height = tx_size_high[tx_size]; int cul_level = 0; + uint8_t levels[64 * 64]; + int8_t signs[64 * 64]; + memset(tcoeffs, 0, sizeof(*tcoeffs) * seg_eob); #if LV_MAP_PROB @@ -311,6 +314,8 @@ return 0; } + memset(signs, 0, sizeof(signs[0]) * seg_eob); + (void)blk_row; (void)blk_col; #if CONFIG_TXK_SEL @@ -357,19 +362,23 @@ *max_scan_line = *eob; int i; + for (i = 0; i < seg_eob; i++) { + levels[i] = (uint8_t)tcoeffs[i]; + } + for (i = 0; i < NUM_BASE_LEVELS; ++i) { #if !LV_MAP_PROB aom_prob *coeff_base = ec_ctx->coeff_base[txs_ctx][plane_type][i]; #endif update_eob = 0; for (c = *eob - 1; c >= 0; --c) { - tran_low_t *v = &tcoeffs[scan[c]]; - int sign; + uint8_t *const level = &levels[scan[c]]; + int8_t *const sign = &signs[scan[c]]; int ctx; - if (*v <= i) continue; + if (*level <= i) continue; - ctx = get_base_ctx(tcoeffs, scan[c], bwl, height, i + 1); + ctx = get_base_ctx(levels, scan[c], bwl, height, i + 1); #if LV_MAP_PROB if (av1_read_record_bin( @@ -379,7 +388,7 @@ if (aom_read(r, coeff_base[ctx], ACCT_STR)) #endif { - *v = i + 1; + assert(*level == i + 1); cul_level += i + 1; if (counts) ++counts->coeff_base[txs_ctx][plane_type][i][ctx][1]; @@ -387,21 +396,20 @@ if (c == 0) { int dc_sign_ctx = txb_ctx->dc_sign_ctx; #if LV_MAP_PROB - sign = av1_read_record_bin( + *sign = av1_read_record_bin( counts, r, ec_ctx->dc_sign_cdf[plane_type][dc_sign_ctx], 2, ACCT_STR); #else - sign = + *sign = aom_read(r, ec_ctx->dc_sign[plane_type][dc_sign_ctx], ACCT_STR); #endif - if (counts) ++counts->dc_sign[plane_type][dc_sign_ctx][sign]; + if (counts) ++counts->dc_sign[plane_type][dc_sign_ctx][*sign]; } else { - sign = av1_read_record_bit(counts, r, ACCT_STR); + *sign = av1_read_record_bit(counts, r, ACCT_STR); } - if (sign) *v = -(*v); continue; } - *v = i + 2; + *level = i + 2; if (counts) ++counts->coeff_base[txs_ctx][plane_type][i][ctx][0]; // update the eob flag for coefficients with magnitude above 1. @@ -410,27 +418,27 @@ } for (c = update_eob; c >= 0; --c) { - tran_low_t *v = &tcoeffs[scan[c]]; - int sign; + uint8_t *const level = &levels[scan[c]]; + int8_t *const sign = &signs[scan[c]]; int idx; int ctx; - if (*v <= NUM_BASE_LEVELS) continue; + if (*level <= NUM_BASE_LEVELS) continue; if (c == 0) { int dc_sign_ctx = txb_ctx->dc_sign_ctx; #if LV_MAP_PROB - sign = av1_read_record_bin( + *sign = av1_read_record_bin( counts, r, ec_ctx->dc_sign_cdf[plane_type][dc_sign_ctx], 2, ACCT_STR); #else - sign = aom_read(r, ec_ctx->dc_sign[plane_type][dc_sign_ctx], ACCT_STR); + *sign = aom_read(r, ec_ctx->dc_sign[plane_type][dc_sign_ctx], ACCT_STR); #endif - if (counts) ++counts->dc_sign[plane_type][dc_sign_ctx][sign]; + if (counts) ++counts->dc_sign[plane_type][dc_sign_ctx][*sign]; } else { - sign = av1_read_record_bit(counts, r, ACCT_STR); + *sign = av1_read_record_bit(counts, r, ACCT_STR); } - ctx = get_br_ctx(tcoeffs, scan[c], bwl, height); + ctx = get_br_ctx(levels, scan[c], bwl, height); #if BR_NODE for (idx = 0; idx < BASE_RANGE_SETS; ++idx) { @@ -468,9 +476,8 @@ int br_base = br_index_to_coeff[idx]; - *v = NUM_BASE_LEVELS + 1 + br_base + br_offset; - cul_level += *v; - if (sign) *v = -(*v); + *level = NUM_BASE_LEVELS + 1 + br_base + br_offset; + cul_level += *level; break; } if (counts) ++counts->coeff_br[txs_ctx][plane_type][idx][ctx][0]; @@ -487,9 +494,8 @@ if (aom_read(r, ec_ctx->coeff_lps[txs_ctx][plane_type][ctx], ACCT_STR)) #endif { - *v = (idx + 1 + NUM_BASE_LEVELS); - if (sign) *v = -(*v); - cul_level += abs(*v); + *level = idx + 1 + NUM_BASE_LEVELS; + cul_level += *level; if (counts) ++counts->coeff_lps[txs_ctx][plane_type][ctx][1]; break; @@ -500,20 +506,19 @@ #endif // decode 0-th order Golomb code - *v = read_golomb(xd, r, counts) + COEFF_BASE_RANGE + 1 + NUM_BASE_LEVELS; - if (sign) *v = -(*v); - cul_level += abs(*v); + *level = + read_golomb(xd, r, counts) + COEFF_BASE_RANGE + 1 + NUM_BASE_LEVELS; + cul_level += *level; } for (c = 0; c < *eob; ++c) { - int16_t dqv = (c == 0) ? dequant[0] : dequant[1]; - tran_low_t *v = &tcoeffs[scan[c]]; + const int16_t dqv = (c == 0) ? dequant[0] : dequant[1]; + const int level = levels[scan[c]]; + const int16_t t = (level * dqv) >> shift; #if CONFIG_SYMBOLRATE - av1_record_coeff(counts, abs(*v)); + av1_record_coeff(counts, level); #endif - int sign = (*v) < 0; - *v = (abs(*v) * dqv) >> shift; - if (sign) *v = -(*v); + tcoeffs[scan[c]] = signs[scan[c]] ? -t : t; } cul_level = AOMMIN(63, cul_level);
diff --git a/av1/encoder/encodetxb.c b/av1/encoder/encodetxb.c index e7af3bf..87707ad 100644 --- a/av1/encoder/encodetxb.c +++ b/av1/encoder/encodetxb.c
@@ -272,11 +272,15 @@ av1_get_tx_type(plane_type, xd, blk_row, blk_col, block, tx_size); const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, mbmi); const int16_t *scan = scan_order->scan; + const int seg_eob = tx_size_2d[tx_size]; int c; const int bwl = b_width_log2_lookup[txsize_to_bsize[tx_size]] + 2; const int height = tx_size_high[tx_size]; uint16_t update_eob = 0; FRAME_CONTEXT *ec_ctx = xd->tile_ctx; + uint8_t levels[64 * 64]; + int8_t signs[64 * 64]; + int i; (void)blk_row; (void)blk_col; @@ -289,6 +293,12 @@ #endif if (eob == 0) return; + + for (i = 0; i < seg_eob; i++) { + levels[i] = (uint8_t)abs(tcoeff[i]); + signs[i] = (int8_t)(tcoeff[i] < 0); + } + #if CONFIG_TXK_SEL av1_write_tx_type(cm, xd, blk_row, blk_col, block, plane, get_min_tx_size(tx_size), w); @@ -325,21 +335,19 @@ write_nz_map(w, tcoeff, eob, plane, scan, tx_size, tx_type, ec_ctx); #endif // CONFIG_CTX1D - int i; for (i = 0; i < NUM_BASE_LEVELS; ++i) { #if !LV_MAP_PROB aom_prob *coeff_base = ec_ctx->coeff_base[txs_ctx][plane_type][i]; #endif update_eob = 0; for (c = eob - 1; c >= 0; --c) { - tran_low_t v = tcoeff[scan[c]]; - tran_low_t level = abs(v); - int sign = (v < 0) ? 1 : 0; + const int level = levels[scan[c]]; + const int sign = signs[scan[c]]; int ctx; if (level <= i) continue; - ctx = get_base_ctx(tcoeff, scan[c], bwl, height, i + 1); + ctx = get_base_ctx(levels, scan[c], bwl, height, i + 1); if (level == i + 1) { #if LV_MAP_PROB @@ -373,9 +381,8 @@ } for (c = update_eob; c >= 0; --c) { - tran_low_t v = tcoeff[scan[c]]; - tran_low_t level = abs(v); - int sign = (v < 0) ? 1 : 0; + const int level = levels[scan[c]]; + const int sign = signs[scan[c]]; int idx; int ctx; @@ -393,7 +400,7 @@ } // level is above 1. - ctx = get_br_ctx(tcoeff, scan[c], bwl, height); + ctx = get_br_ctx(levels, scan[c], bwl, height); #if BR_NODE int base_range = level - 1 - NUM_BASE_LEVELS; @@ -770,7 +777,7 @@ if (level > NUM_BASE_LEVELS) { int ctx; - ctx = get_br_ctx(qcoeff, scan[c], bwl, height); + ctx = get_br_ctx_coeff(qcoeff, scan[c], bwl, height); #if BR_NODE int base_range = level - 1 - NUM_BASE_LEVELS; if (base_range < COEFF_BASE_RANGE) { @@ -1289,7 +1296,7 @@ ref_num = BASE_CONTEXT_POSITION_NUM; } #else - int(*ref_offset)[2] = base_ref_offset; + const int(*ref_offset)[2] = base_ref_offset; int ref_num = BASE_CONTEXT_POSITION_NUM; #endif for (int i = 0; i < ref_num; ++i) { @@ -1325,7 +1332,7 @@ ref_num = BR_CONTEXT_POSITION_NUM; } #else - int(*ref_offset)[2] = br_ref_offset; + const int(*ref_offset)[2] = br_ref_offset; const int ref_num = BR_CONTEXT_POSITION_NUM; #endif for (int i = 0; i < ref_num; ++i) { @@ -1594,8 +1601,8 @@ } if (abs_qc > NUM_BASE_LEVELS) { - int ctx = get_br_ctx(txb_info->qcoeff, scan[scan_idx], txb_info->bwl, - txb_info->height); + int ctx = get_br_ctx_coeff(txb_info->qcoeff, scan[scan_idx], + txb_info->bwl, txb_info->height); cost += get_br_cost(abs_qc, ctx, txb_costs->lps_cost[ctx]); cost += get_golomb_cost(abs_qc); } @@ -2176,6 +2183,8 @@ const int bwl = b_width_log2_lookup[txsize_to_bsize[tx_size]] + 2; const int height = tx_size_high[tx_size]; int cul_level = 0; + uint8_t levels[64 * 64]; + int8_t signs[64 * 64]; TX_SIZE txsize_ctx = get_txsize_context(tx_size); FRAME_CONTEXT *ec_ctx = xd->tile_ctx; @@ -2196,6 +2205,11 @@ return; } + for (i = 0; i < seg_eob; i++) { + levels[i] = (uint8_t)abs(tcoeff[i]); + signs[i] = (int8_t)(tcoeff[i] < 0); + } + #if CONFIG_TXK_SEL av1_update_tx_type_count(cm, xd, blk_row, blk_col, block, plane, mbmi->sb_type, get_min_tx_size(tx_size), td->counts); @@ -2239,13 +2253,13 @@ for (i = 0; i < NUM_BASE_LEVELS; ++i) { update_eob = 0; for (c = eob - 1; c >= 0; --c) { - tran_low_t v = qcoeff[scan[c]]; - tran_low_t level = abs(v); + const int level = levels[scan[c]]; + const int sign = signs[scan[c]]; int ctx; if (level <= i) continue; - ctx = get_base_ctx(tcoeff, scan[c], bwl, height, i + 1); + ctx = get_base_ctx(levels, scan[c], bwl, height, i + 1); if (level == i + 1) { ++td->counts->coeff_base[txsize_ctx][plane_type][i][ctx][1]; @@ -2256,9 +2270,9 @@ if (c == 0) { int dc_sign_ctx = txb_ctx.dc_sign_ctx; - ++td->counts->dc_sign[plane_type][dc_sign_ctx][v < 0]; + ++td->counts->dc_sign[plane_type][dc_sign_ctx][sign]; #if LV_MAP_PROB - update_bin(ec_ctx->dc_sign_cdf[plane_type][dc_sign_ctx], v < 0, 2); + update_bin(ec_ctx->dc_sign_cdf[plane_type][dc_sign_ctx], sign, 2); #endif x->mbmi_ext->dc_sign_ctx[plane][block] = dc_sign_ctx; } @@ -2274,8 +2288,8 @@ } for (c = update_eob; c >= 0; --c) { - tran_low_t v = qcoeff[scan[c]]; - tran_low_t level = abs(v); + const int level = levels[scan[c]]; + const int sign = signs[scan[c]]; int idx; int ctx; @@ -2285,15 +2299,15 @@ if (c == 0) { int dc_sign_ctx = txb_ctx.dc_sign_ctx; - ++td->counts->dc_sign[plane_type][dc_sign_ctx][v < 0]; + ++td->counts->dc_sign[plane_type][dc_sign_ctx][sign]; #if LV_MAP_PROB - update_bin(ec_ctx->dc_sign_cdf[plane_type][dc_sign_ctx], v < 0, 2); + update_bin(ec_ctx->dc_sign_cdf[plane_type][dc_sign_ctx], sign, 2); #endif x->mbmi_ext->dc_sign_ctx[plane][block] = dc_sign_ctx; } // level is above 1. - ctx = get_br_ctx(tcoeff, scan[c], bwl, height); + ctx = get_br_ctx(levels, scan[c], bwl, height); #if BR_NODE int base_range = level - 1 - NUM_BASE_LEVELS;