Add table av1_nz_map_ctx_offset[]
There are too much if branches in get_nz_map_ctx_from_stats().
Look up the table to get the ctx offset when tx_class is TX_CLASS_2D.
Change-Id: Id08d450add5d17aeff8ab27c699d7e97ff88993d
diff --git a/av1/common/txb_common.c b/av1/common/txb_common.c
index 7980c52..3b6678e 100644
--- a/av1/common/txb_common.c
+++ b/av1/common/txb_common.c
@@ -96,6 +96,131 @@
22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24,
};
+// The ctx offset table when TX is TX_CLASS_2D.
+// TX col and row indices are clamped to 4.
+const int8_t av1_nz_map_ctx_offset[TX_SIZES_ALL][5][5] = {
+ // TX_4X4
+ { { 0, 1, 6, 6, 0 },
+ { 1, 6, 6, 21, 0 },
+ { 6, 6, 21, 21, 0 },
+ { 6, 21, 21, 21, 0 },
+ { 0, 0, 0, 0, 0 } },
+ // TX_8X8
+ { { 0, 1, 6, 6, 21 },
+ { 1, 6, 6, 21, 21 },
+ { 6, 6, 21, 21, 21 },
+ { 6, 21, 21, 21, 21 },
+ { 21, 21, 21, 21, 21 } },
+ // TX_16X16
+ { { 0, 1, 6, 6, 21 },
+ { 1, 6, 6, 21, 21 },
+ { 6, 6, 21, 21, 21 },
+ { 6, 21, 21, 21, 21 },
+ { 21, 21, 21, 21, 21 } },
+ // TX_32X32
+ { { 0, 1, 6, 6, 21 },
+ { 1, 6, 6, 21, 21 },
+ { 6, 6, 21, 21, 21 },
+ { 6, 21, 21, 21, 21 },
+ { 21, 21, 21, 21, 21 } },
+#if CONFIG_TX64X64
+ // TX_64X64
+ { { 0, 11, 11, 11, 11 },
+ { 11, 11, 11, 11, 11 },
+ { 6, 6, 21, 21, 21 },
+ { 6, 21, 21, 21, 21 },
+ { 21, 21, 21, 21, 21 } },
+#endif // CONFIG_TX64X64
+ // TX_4X8
+ { { 0, 11, 11, 11, 0 },
+ { 11, 11, 11, 11, 0 },
+ { 6, 6, 21, 21, 0 },
+ { 6, 21, 21, 21, 0 },
+ { 21, 21, 21, 21, 0 } },
+ // TX_8X4
+ { { 0, 16, 6, 6, 21 },
+ { 16, 16, 6, 21, 21 },
+ { 16, 16, 21, 21, 21 },
+ { 16, 16, 21, 21, 21 },
+ { 0, 0, 0, 0, 0 } },
+ // TX_8X16
+ { { 0, 11, 11, 11, 11 },
+ { 11, 11, 11, 11, 11 },
+ { 6, 6, 21, 21, 21 },
+ { 6, 21, 21, 21, 21 },
+ { 21, 21, 21, 21, 21 } },
+ // TX_16X8
+ { { 0, 16, 6, 6, 21 },
+ { 16, 16, 6, 21, 21 },
+ { 16, 16, 21, 21, 21 },
+ { 16, 16, 21, 21, 21 },
+ { 16, 16, 21, 21, 21 } },
+ // TX_16X32
+ { { 0, 11, 11, 11, 11 },
+ { 11, 11, 11, 11, 11 },
+ { 6, 6, 21, 21, 21 },
+ { 6, 21, 21, 21, 21 },
+ { 21, 21, 21, 21, 21 } },
+ // TX_32X16
+ { { 0, 16, 6, 6, 21 },
+ { 16, 16, 6, 21, 21 },
+ { 16, 16, 21, 21, 21 },
+ { 16, 16, 21, 21, 21 },
+ { 16, 16, 21, 21, 21 } },
+#if CONFIG_TX64X64
+ // TX_32X64
+ { { 0, 11, 11, 11, 11 },
+ { 11, 11, 11, 11, 11 },
+ { 6, 6, 21, 21, 21 },
+ { 6, 21, 21, 21, 21 },
+ { 21, 21, 21, 21, 21 } },
+ // TX_64X32
+ { { 0, 1, 6, 6, 21 },
+ { 1, 6, 6, 21, 21 },
+ { 6, 6, 21, 21, 21 },
+ { 6, 21, 21, 21, 21 },
+ { 21, 21, 21, 21, 21 } },
+#endif // CONFIG_TX64X64
+ // TX_4X16
+ { { 0, 11, 11, 11, 0 },
+ { 11, 11, 11, 11, 0 },
+ { 6, 6, 21, 21, 0 },
+ { 6, 21, 21, 21, 0 },
+ { 21, 21, 21, 21, 0 } },
+ // TX_16X4
+ { { 0, 16, 6, 6, 21 },
+ { 16, 16, 6, 21, 21 },
+ { 16, 16, 21, 21, 21 },
+ { 16, 16, 21, 21, 21 },
+ { 0, 0, 0, 0, 0 } },
+ // TX_8X32
+ { { 0, 11, 11, 11, 11 },
+ { 11, 11, 11, 11, 11 },
+ { 6, 6, 21, 21, 21 },
+ { 6, 21, 21, 21, 21 },
+ { 21, 21, 21, 21, 21 } },
+ // TX_32X8
+ { { 0, 16, 6, 6, 21 },
+ { 16, 16, 6, 21, 21 },
+ { 16, 16, 21, 21, 21 },
+ { 16, 16, 21, 21, 21 },
+ { 16, 16, 21, 21, 21 } },
+#if CONFIG_TX64X64
+ // TX_16X64
+ { { 0, 11, 11, 11, 11 },
+ { 11, 11, 11, 11, 11 },
+ { 6, 6, 21, 21, 21 },
+ { 6, 21, 21, 21, 21 },
+ { 21, 21, 21, 21, 21 } },
+ // TX_64X16
+ { { 0, 16, 6, 6, 21 },
+ { 16, 16, 6, 21, 21 },
+ { 16, 16, 21, 21, 21 },
+ { 16, 16, 21, 21, 21 },
+ { 16, 16, 21, 21, 21 } }
+#endif // CONFIG_TX64X64
+};
+
void av1_init_txb_probs(FRAME_CONTEXT *fc) {
TX_SIZE tx_size;
int plane, ctx;
diff --git a/av1/common/txb_common.h b/av1/common/txb_common.h
index 8260ad6..9f300f5 100644
--- a/av1/common/txb_common.h
+++ b/av1/common/txb_common.h
@@ -23,6 +23,8 @@
extern const int8_t av1_coeff_band_32x32[1024];
+extern const int8_t av1_nz_map_ctx_offset[TX_SIZES_ALL][5][5];
+
typedef struct txb_ctx {
int txb_skip_ctx;
int dc_sign_ctx;
@@ -496,7 +498,7 @@
static INLINE int get_nz_map_ctx_from_stats(
const int stats,
const int coeff_idx, // raster order
- const int bwl, const int height, const TX_CLASS tx_class) {
+ const int bwl, const TX_SIZE tx_size, const TX_CLASS tx_class) {
const int row = coeff_idx >> bwl;
const int col = coeff_idx - (row << bwl);
int ctx = (stats + 1) >> 1;
@@ -505,10 +507,12 @@
#endif
if (tx_class == TX_CLASS_2D) {
- const int width = 1 << bwl;
-
if (row == 0 && col == 0) return 0;
+#if 0
+ // This is the algorithm to generate table av1_nz_map_ctx_offset[].
+ const int width = 1 << bwl;
+ const int height = tx_size_high[tx_size];
if (width < height) {
if (row < 2) return 11 + ctx;
} else if (width > height) {
@@ -519,6 +523,8 @@
if (row + col < 4) return 5 + ctx + 1;
return 21 + ctx;
+#endif
+ return ctx + av1_nz_map_ctx_offset[tx_size][AOMMIN(row, 4)][AOMMIN(col, 4)];
} else {
static const int pos_to_offset[3] = {
SIG_COEF_CONTEXTS_2D, SIG_COEF_CONTEXTS_2D + 5, SIG_COEF_CONTEXTS_2D + 10
@@ -541,11 +547,11 @@
static INLINE int get_nz_map_ctx(const uint8_t *const levels,
const int coeff_idx, const int bwl,
- const int height,
#if CONFIG_LV_MAP_MULTI
- const int scan_idx, const int is_eob,
+ const int height, const int scan_idx,
+ const int is_eob,
#endif
- const TX_TYPE tx_type) {
+ const TX_SIZE tx_size, const TX_TYPE tx_type) {
#if CONFIG_LV_MAP_MULTI
if (is_eob) {
if (scan_idx == 0) return SIG_COEF_CONTEXTS - 4;
@@ -561,7 +567,7 @@
#else
get_nz_count(levels + get_padded_idx(coeff_idx, bwl), bwl, tx_class);
#endif
- return get_nz_map_ctx_from_stats(stats, coeff_idx, bwl, height, tx_class);
+ return get_nz_map_ctx_from_stats(stats, coeff_idx, bwl, tx_size, tx_class);
}
static INLINE void set_dc_sign(int *cul_level, tran_low_t v) {
diff --git a/av1/decoder/decodetxb.c b/av1/decoder/decodetxb.c
index 3efc611..fdfe6f0 100644
--- a/av1/decoder/decodetxb.c
+++ b/av1/decoder/decodetxb.c
@@ -163,8 +163,8 @@
c = *eob - 1 - i;
const int pos = scan[c];
#if CONFIG_LV_MAP_MULTI
- const int coeff_ctx =
- get_nz_map_ctx(levels, pos, bwl, height, c, c == *eob - 1, tx_type);
+ const int coeff_ctx = get_nz_map_ctx(levels, pos, bwl, height, c,
+ c == *eob - 1, tx_size, tx_type);
#if USE_BASE_EOB_ALPHABET
aom_cdf_prob *cdf;
int nsymbs;
@@ -214,7 +214,7 @@
}
#else
int is_nz;
- const int coeff_ctx = get_nz_map_ctx(levels, pos, bwl, height, tx_type);
+ const int coeff_ctx = get_nz_map_ctx(levels, pos, bwl, tx_size, tx_type);
if (c < *eob - 1) {
is_nz = av1_read_record_bin(
diff --git a/av1/encoder/encodetxb.c b/av1/encoder/encodetxb.c
index 6d1750d..71bc63c 100644
--- a/av1/encoder/encodetxb.c
+++ b/av1/encoder/encodetxb.c
@@ -270,7 +270,7 @@
}
#else
const int coeff_ctx = get_nz_map_ctx(levels, coeff_idx, txb_info->bwl,
- txb_info->height, txb_info->tx_type);
+ txb_info->tx_size, txb_info->tx_type);
if ((stats->rd_low < stats->rd) && (stats->low_qc == 0)) {
stats->nz_rate = txb_costs->nz_map_cost[coeff_ctx][0];
} else {
@@ -389,8 +389,8 @@
const int pos = scan[c];
#if CONFIG_LV_MAP_MULTI
- coeff_ctx =
- get_nz_map_ctx(levels, pos, bwl, height, c, c == eob - 1, tx_type);
+ coeff_ctx = get_nz_map_ctx(levels, pos, bwl, height, c, c == eob - 1,
+ tx_size, tx_type);
const tran_low_t v = tcoeff[pos];
#if USE_BASE_EOB_ALPHABET
if (c == eob - 1) {
@@ -410,7 +410,7 @@
ec_ctx->coeff_base_cdf[txs_ctx][plane_type][coeff_ctx], 4);
#endif
#else
- coeff_ctx = get_nz_map_ctx(levels, pos, bwl, height, tx_type);
+ coeff_ctx = get_nz_map_ctx(levels, pos, bwl, tx_size, tx_type);
const tran_low_t v = tcoeff[pos];
const int is_nz = (v != 0);
@@ -436,7 +436,7 @@
for (int i = 1; i < eob; ++i) {
c = eob - 1 - i;
const int pos = scan[c];
- const int coeff_ctx = get_nz_map_ctx(levels, pos, bwl, height, tx_type);
+ const int coeff_ctx = get_nz_map_ctx(levels, pos, bwl, tx_size, tx_type);
const tran_low_t v = tcoeff[pos];
const int is_nz = (v != 0);
@@ -717,8 +717,8 @@
const int is_nz = (v != 0);
const int level = abs(v);
#if CONFIG_LV_MAP_MULTI
- coeff_ctx =
- get_nz_map_ctx(levels, pos, bwl, height, c, c == eob - 1, tx_type);
+ coeff_ctx = get_nz_map_ctx(levels, pos, bwl, height, c, c == eob - 1,
+ tx_size, tx_type);
#if USE_BASE_EOB_ALPHABET
if (c == eob - 1) {
cost += coeff_costs
@@ -732,12 +732,12 @@
#endif
#else // CONFIG_LV_MAP_MULTI
#if USE_CAUSAL_BASE_CTX
- coeff_ctx = get_nz_map_ctx(levels, pos, bwl, height, tx_type);
+ coeff_ctx = get_nz_map_ctx(levels, pos, bwl, tx_size, tx_type);
#endif
if (c < eob - 1) {
#if !USE_CAUSAL_BASE_CTX
- const int coeff_ctx = get_nz_map_ctx(levels, pos, bwl, height, tx_type);
+ const int coeff_ctx = get_nz_map_ctx(levels, pos, bwl, tx_size, tx_type);
#endif
cost += coeff_costs->nz_map_cost[coeff_ctx][is_nz];
}
@@ -879,7 +879,7 @@
#else
txb_cache->nz_count_arr[coeff_idx],
#endif
- coeff_idx, bwl, height, txb_info->tx_type);
+ coeff_idx, bwl, txb_info->tx_size, txb_info->tx_type);
// gen_base_count_mag_arr
if (!has_base(qcoeff[coeff_idx], 0)) continue;
@@ -1101,7 +1101,7 @@
#else
count - 1,
#endif
- coeff_idx, txb_info->bwl, txb_info->height, txb_info->tx_type);
+ coeff_idx, txb_info->bwl, txb_info->tx_size, txb_info->tx_type);
update_qcoeff(nb_coeff_idx, nb_coeff, txb_info);
const int ctx = txb_cache->nz_ctx_arr[coeff_idx];
#if CONFIG_LV_MAP_MULTI
@@ -1497,7 +1497,7 @@
#else
txb_cache->nz_count_arr[nb_coeff_idx],
#endif
- nb_coeff_idx, txb_info->bwl, txb_info->height, txb_info->tx_type);
+ nb_coeff_idx, txb_info->bwl, txb_info->tx_size, txb_info->tx_type);
}
}
}
@@ -1591,7 +1591,7 @@
#if CONFIG_LV_MAP_MULTI
const int coeff_ctx =
get_nz_map_ctx(txb_info->levels, pos, txb_info->bwl, txb_info->height,
- scan_idx, is_eob, txb_info->tx_type);
+ scan_idx, is_eob, txb_info->tx_size, txb_info->tx_type);
#if USE_BASE_EOB_ALPHABET
if (is_eob) {
cost +=
@@ -1607,12 +1607,12 @@
#else
#if USE_CAUSAL_BASE_CTX
const int coeff_ctx = get_nz_map_ctx(txb_info->levels, pos, txb_info->bwl,
- txb_info->height, txb_info->tx_type);
+ txb_info->tx_size, txb_info->tx_type);
#endif
if (scan_idx < txb_info->eob - 1) {
#if !USE_CAUSAL_BASE_CTX
const int coeff_ctx = get_nz_map_ctx(txb_info->levels, pos, txb_info->bwl,
- txb_info->height, txb_info->tx_type);
+ txb_info->tx_size, txb_info->tx_type);
#endif
cost += txb_costs->nz_map_cost[coeff_ctx][is_nz];
}
@@ -2288,8 +2288,8 @@
#if CONFIG_LV_MAP_MULTI
(void)is_nz;
(void)nz_map_count;
- coeff_ctx =
- get_nz_map_ctx(levels, pos, bwl, height, c, c == eob - 1, tx_type);
+ coeff_ctx = get_nz_map_ctx(levels, pos, bwl, height, c, c == eob - 1,
+ tx_size, tx_type);
#if USE_BASE_EOB_ALPHABET
if (c == eob - 1) {
update_cdf(ec_ctx->coeff_base_eob_cdf[txsize_ctx][plane_type]
@@ -2318,7 +2318,7 @@
AOMMIN(abs(v), 3), 4);
#endif
#elif USE_CAUSAL_BASE_CTX
- coeff_ctx = get_nz_map_ctx(levels, pos, bwl, height, tx_type);
+ coeff_ctx = get_nz_map_ctx(levels, pos, bwl, tx_size, tx_type);
if (c < eob - 1) {
++(*nz_map_count)[coeff_ctx][is_nz];
@@ -2341,7 +2341,7 @@
}
}
#else
- const int coeff_ctx = get_nz_map_ctx(levels, pos, bwl, height, tx_type);
+ const int coeff_ctx = get_nz_map_ctx(levels, pos, bwl, tx_size, tx_type);
if (c == eob - 1) continue;