Refactor av1_update_and_record_txb_context()
Adjust the order of operations to avoid unnecesary computations.
For example, when eob is 0, there is no need to copy data to the
coefficient buffer.
Change-Id: I6d8b3e071955ea7bab85df9f21852b6e4c54ec08
diff --git a/av1/encoder/encodetxb.c b/av1/encoder/encodetxb.c
index 01fa561..197f570 100644
--- a/av1/encoder/encodetxb.c
+++ b/av1/encoder/encodetxb.c
@@ -1706,35 +1706,20 @@
struct macroblock_plane *p = &x->plane[plane];
struct macroblockd_plane *pd = &xd->plane[plane];
MB_MODE_INFO *mbmi = xd->mi[0];
- int eob = p->eobs[block];
- const PLANE_TYPE plane_type = pd->plane_type;
- const tran_low_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
- tran_low_t *tcoeff = BLOCK_OFFSET(x->mbmi_ext->tcoeff[plane], block);
- const int segment_id = mbmi->segment_id;
- const TX_TYPE tx_type = av1_get_tx_type(plane_type, xd, blk_row, blk_col,
- tx_size, cm->reduced_tx_set_used);
- const SCAN_ORDER *const scan_order = get_scan(tx_size, tx_type);
- const int16_t *const scan = scan_order->scan;
- const int seg_eob = av1_get_tx_eob(&cpi->common.seg, segment_id, tx_size);
- int c;
+ const int eob = p->eobs[block];
TXB_CTX txb_ctx;
get_txb_ctx(plane_bsize, tx_size, plane, pd->above_context + blk_col,
pd->left_context + blk_row, &txb_ctx);
const int bwl = get_txb_bwl(tx_size);
const int width = get_txb_wide(tx_size);
const int height = get_txb_high(tx_size);
- uint8_t levels_buf[TX_PAD_2D];
- uint8_t *const levels = set_levels(levels_buf, width);
const uint8_t allow_update_cdf = args->allow_update_cdf;
-
- TX_SIZE txsize_ctx = get_txsize_entropy_ctx(tx_size);
+ const TX_SIZE txsize_ctx = get_txsize_entropy_ctx(tx_size);
FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
- DECLARE_ALIGNED(16, int8_t, coeff_contexts[MAX_TX_SQUARE]);
#if CONFIG_ENTROPY_STATS
int cdf_idx = cm->coef_cdf_category;
#endif // CONFIG_ENTROPY_STATS
- memcpy(tcoeff, qcoeff, sizeof(*tcoeff) * seg_eob);
#if CONFIG_ENTROPY_STATS
++td->counts->txb_skip[cdf_idx][txsize_ctx][txb_ctx.txb_skip_ctx][eob == 0];
#endif // CONFIG_ENTROPY_STATS
@@ -1742,8 +1727,8 @@
update_cdf(ec_ctx->txb_skip_cdf[txsize_ctx][txb_ctx.txb_skip_ctx], eob == 0,
2);
}
- x->mbmi_ext->txb_skip_ctx[plane][block] = txb_ctx.txb_skip_ctx;
+ x->mbmi_ext->txb_skip_ctx[plane][block] = txb_ctx.txb_skip_ctx;
x->mbmi_ext->eobs[plane][block] = eob;
if (eob == 0) {
@@ -1751,9 +1736,23 @@
return;
}
+ tran_low_t *tcoeff = BLOCK_OFFSET(x->mbmi_ext->tcoeff[plane], block);
+ const int segment_id = mbmi->segment_id;
+ const int seg_eob = av1_get_tx_eob(&cpi->common.seg, segment_id, tx_size);
+ const tran_low_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
+ memcpy(tcoeff, qcoeff, sizeof(*tcoeff) * seg_eob);
+
+ uint8_t levels_buf[TX_PAD_2D];
+ uint8_t *const levels = set_levels(levels_buf, width);
av1_txb_init_levels(tcoeff, width, height, levels);
av1_update_tx_type_count(cm, xd, blk_row, blk_col, plane, tx_size, td->counts,
allow_update_cdf);
+
+ const PLANE_TYPE plane_type = pd->plane_type;
+ const TX_TYPE tx_type = av1_get_tx_type(plane_type, xd, blk_row, blk_col,
+ tx_size, cm->reduced_tx_set_used);
+ const SCAN_ORDER *const scan_order = get_scan(tx_size, tx_type);
+ const int16_t *const scan = scan_order->scan;
#if CONFIG_ENTROPY_STATS
av1_update_eob_context(cdf_idx, eob, tx_size, tx_type, plane_type, ec_ctx,
td->counts, allow_update_cdf);
@@ -1761,16 +1760,16 @@
av1_update_eob_context(eob, tx_size, tx_type, plane_type, ec_ctx,
allow_update_cdf);
#endif
+
+ DECLARE_ALIGNED(16, int8_t, coeff_contexts[MAX_TX_SQUARE]);
av1_get_nz_map_contexts(levels, scan, eob, tx_size, tx_type, coeff_contexts);
- for (c = eob - 1; c >= 0; --c) {
+ for (int c = eob - 1; c >= 0; --c) {
const int pos = scan[c];
const int coeff_ctx = coeff_contexts[pos];
const tran_low_t v = qcoeff[pos];
const tran_low_t level = abs(v);
- const int is_nz = (v != 0);
- (void)is_nz;
if (allow_update_cdf) {
if (c == eob - 1) {
assert(coeff_ctx < 4);
@@ -1821,18 +1820,18 @@
}
// Update the context needed to code the DC sign (if applicable)
- const int sign = (tcoeff[0] < 0) ? 1 : 0;
if (tcoeff[0] != 0) {
- int dc_sign_ctx = txb_ctx.dc_sign_ctx;
+ const int dc_sign = (tcoeff[0] < 0) ? 1 : 0;
+ const int dc_sign_ctx = txb_ctx.dc_sign_ctx;
#if CONFIG_ENTROPY_STATS
- ++td->counts->dc_sign[plane_type][dc_sign_ctx][sign];
+ ++td->counts->dc_sign[plane_type][dc_sign_ctx][dc_sign];
#endif // CONFIG_ENTROPY_STATS
if (allow_update_cdf)
- update_cdf(ec_ctx->dc_sign_cdf[plane_type][dc_sign_ctx], sign, 2);
+ update_cdf(ec_ctx->dc_sign_cdf[plane_type][dc_sign_ctx], dc_sign, 2);
x->mbmi_ext->dc_sign_ctx[plane][block] = dc_sign_ctx;
}
- int cul_level = av1_get_txb_entropy_context(tcoeff, scan_order, eob);
+ const int cul_level = av1_get_txb_entropy_context(tcoeff, scan_order, eob);
av1_set_contexts(xd, pd, plane, tx_size, cul_level, blk_col, blk_row);
}