Commit 3120dbdd authored by Ronald S. Bultje's avatar Ronald S. Bultje
Browse files

Redo banding for all transforms.

Now that the first AC coefficient in both directions use the same DC
as their context, there no longer is a purpose in letting both have
their own band. Merging these two bands allows us to split bands for
some of the very high-frequency AC bands.

In addition, I'm redoing the banding for the 1D-ADST col/row scans. I
don't think the old banding made any sense at all (it merged the last
coefficient of the first row/col in the same band as the first two of
the second row/col), which was clearly an oversight from the band being
applied in scan-order (rather than in their actual position). Now,
coefficients at the same position will be in the same band, regardless
what scan order is used. I think this makes most sense for the purpose
of banding, which is basically "predict energy for this coefficient
depending on the energy of context coefficients" (i.e. pt).

After full re-training, together with previous patch, derf gains about
1.2-1.3%, and hd/stdhd gain about 0.9-1.0%.

Change-Id: I7a0cc12ba724e88b278034113cb4adaaebf87e0c
parent 790fb132
This diff is collapsed.
...@@ -42,15 +42,21 @@ DECLARE_ALIGNED(16, const uint8_t, vp9_norm[256]) = { ...@@ -42,15 +42,21 @@ DECLARE_ALIGNED(16, const uint8_t, vp9_norm[256]) = {
}; };
// Unified coefficient band structure used by all block sizes // Unified coefficient band structure used by all block sizes
DECLARE_ALIGNED(16, const int, vp9_coef_bands[32]) = { DECLARE_ALIGNED(16, const int, vp9_coef_bands8x8[64]) = {
0, 1, 2, 3, 3, 3, 4, 4, 0, 1, 2, 3, 4, 4, 5, 5,
4, 4, 4, 4, 4, 4, 4, 5, 1, 2, 3, 4, 4, 5, 5, 5,
2, 3, 4, 4, 5, 5, 5, 5,
3, 4, 4, 5, 5, 5, 5, 5,
4, 4, 5, 5, 5, 5, 5, 5,
4, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5 5, 5, 5, 5, 5, 5, 5, 5
}; };
DECLARE_ALIGNED(16, const int, vp9_coef_bands4x4[16]) = { DECLARE_ALIGNED(16, const int, vp9_coef_bands4x4[16]) = {
0, 1, 2, 3, 3, 3, 4, 4, 0, 1, 2, 3,
4, 4, 5, 5, 5, 5, 5, 5 1, 2, 3, 4,
2, 3, 4, 5,
3, 4, 5, 5
}; };
DECLARE_ALIGNED(16, const uint8_t, vp9_pt_energy_class[MAX_ENTROPY_TOKENS]) = { DECLARE_ALIGNED(16, const uint8_t, vp9_pt_energy_class[MAX_ENTROPY_TOKENS]) = {
......
...@@ -126,17 +126,20 @@ static INLINE void vp9_reset_sb64_tokens_context(MACROBLOCKD* const xd) { ...@@ -126,17 +126,20 @@ static INLINE void vp9_reset_sb64_tokens_context(MACROBLOCKD* const xd) {
vpx_memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) * 4); vpx_memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) * 4);
} }
extern const int vp9_coef_bands[32]; extern const int vp9_coef_bands8x8[64];
extern const int vp9_coef_bands4x4[16]; extern const int vp9_coef_bands4x4[16];
static int get_coef_band(TX_SIZE tx_size, int coef_index) { static int get_coef_band(const int *scan, TX_SIZE tx_size, int coef_index) {
if (tx_size == TX_4X4) { if (tx_size == TX_4X4) {
return vp9_coef_bands4x4[coef_index]; return vp9_coef_bands4x4[scan[coef_index]];
} else { } else {
if (coef_index < 32) const int pos = scan[coef_index];
return vp9_coef_bands[coef_index]; const int sz = 1 << (2 + tx_size);
else const int x = pos & (sz - 1), y = pos >> (2 + tx_size);
if (x >= 8 || y >= 8)
return 5; return 5;
else
return vp9_coef_bands8x8[y * 8 + x];
} }
} }
extern int vp9_get_coef_context(const int *scan, const int *neighbors, extern int vp9_get_coef_context(const int *scan, const int *neighbors,
......
...@@ -65,9 +65,11 @@ static int get_signed(BOOL_DECODER *br, int value_to_sign) { ...@@ -65,9 +65,11 @@ static int get_signed(BOOL_DECODER *br, int value_to_sign) {
#define INCREMENT_COUNT(token) \ #define INCREMENT_COUNT(token) \
do { \ do { \
coef_counts[type][ref][get_coef_band(txfm_size, c)][pt][token]++; \ coef_counts[type][ref][get_coef_band(scan, txfm_size, c)] \
[pt][token]++; \
token_cache[c] = token; \ token_cache[c] = token; \
pt = vp9_get_coef_context(scan, nb, pad, token_cache, c, default_eob); \ pt = vp9_get_coef_context(scan, nb, pad, token_cache, \
c, default_eob); \
} while (0) } while (0)
#if CONFIG_CODE_NONZEROCOUNT #if CONFIG_CODE_NONZEROCOUNT
...@@ -212,10 +214,10 @@ static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd, ...@@ -212,10 +214,10 @@ static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
if (nzc == nzc_expected) if (nzc == nzc_expected)
break; break;
#endif #endif
prob = coef_probs[type][ref][get_coef_band(txfm_size, c)][pt]; prob = coef_probs[type][ref][get_coef_band(scan, txfm_size, c)][pt];
#if CONFIG_CODE_NONZEROCOUNT == 0 #if CONFIG_CODE_NONZEROCOUNT == 0
fc->eob_branch_counts[txfm_size][type][ref] fc->eob_branch_counts[txfm_size][type][ref]
[get_coef_band(txfm_size, c)][pt]++; [get_coef_band(scan, txfm_size, c)][pt]++;
if (!vp9_read(br, prob[EOB_CONTEXT_NODE])) if (!vp9_read(br, prob[EOB_CONTEXT_NODE]))
break; break;
#endif #endif
...@@ -231,7 +233,7 @@ SKIP_START: ...@@ -231,7 +233,7 @@ SKIP_START:
if (!vp9_read(br, prob[ZERO_CONTEXT_NODE])) { if (!vp9_read(br, prob[ZERO_CONTEXT_NODE])) {
INCREMENT_COUNT(ZERO_TOKEN); INCREMENT_COUNT(ZERO_TOKEN);
++c; ++c;
prob = coef_probs[type][ref][get_coef_band(txfm_size, c)][pt]; prob = coef_probs[type][ref][get_coef_band(scan, txfm_size, c)][pt];
goto SKIP_START; goto SKIP_START;
} }
// ONE_CONTEXT_NODE_0_ // ONE_CONTEXT_NODE_0_
...@@ -296,7 +298,8 @@ SKIP_START: ...@@ -296,7 +298,8 @@ SKIP_START:
#if CONFIG_CODE_NONZEROCOUNT == 0 #if CONFIG_CODE_NONZEROCOUNT == 0
if (c < seg_eob) if (c < seg_eob)
coef_counts[type][ref][get_coef_band(txfm_size, c)][pt][DCT_EOB_TOKEN]++; coef_counts[type][ref][get_coef_band(scan, txfm_size, c)]
[pt][DCT_EOB_TOKEN]++;
#endif #endif
A0[aidx] = L0[lidx] = c > 0; A0[aidx] = L0[lidx] = c > 0;
......
...@@ -662,7 +662,7 @@ static void optimize_b(VP9_COMMON *const cm, ...@@ -662,7 +662,7 @@ static void optimize_b(VP9_COMMON *const cm,
t0 = (vp9_dct_value_tokens_ptr + x)->Token; t0 = (vp9_dct_value_tokens_ptr + x)->Token;
/* Consider both possible successor states. */ /* Consider both possible successor states. */
if (next < default_eob) { if (next < default_eob) {
band = get_coef_band(tx_size, i + 1); band = get_coef_band(scan, tx_size, i + 1);
pt = trellis_get_coeff_context(scan, nb, i, t0, token_cache, pt = trellis_get_coeff_context(scan, nb, i, t0, token_cache,
pad, default_eob); pad, default_eob);
rate0 += rate0 +=
...@@ -721,7 +721,7 @@ static void optimize_b(VP9_COMMON *const cm, ...@@ -721,7 +721,7 @@ static void optimize_b(VP9_COMMON *const cm,
t0 = t1 = (vp9_dct_value_tokens_ptr + x)->Token; t0 = t1 = (vp9_dct_value_tokens_ptr + x)->Token;
} }
if (next < default_eob) { if (next < default_eob) {
band = get_coef_band(tx_size, i + 1); band = get_coef_band(scan, tx_size, i + 1);
if (t0 != DCT_EOB_TOKEN) { if (t0 != DCT_EOB_TOKEN) {
pt = trellis_get_coeff_context(scan, nb, i, t0, token_cache, pt = trellis_get_coeff_context(scan, nb, i, t0, token_cache,
pad, default_eob); pad, default_eob);
...@@ -763,7 +763,7 @@ static void optimize_b(VP9_COMMON *const cm, ...@@ -763,7 +763,7 @@ static void optimize_b(VP9_COMMON *const cm,
* add a new trellis node, but we do need to update the costs. * add a new trellis node, but we do need to update the costs.
*/ */
else { else {
band = get_coef_band(tx_size, i + 1); band = get_coef_band(scan, tx_size, i + 1);
t0 = tokens[next][0].token; t0 = tokens[next][0].token;
t1 = tokens[next][1].token; t1 = tokens[next][1].token;
/* Update the cost of each path if we're past the EOB token. */ /* Update the cost of each path if we're past the EOB token. */
...@@ -782,7 +782,7 @@ static void optimize_b(VP9_COMMON *const cm, ...@@ -782,7 +782,7 @@ static void optimize_b(VP9_COMMON *const cm,
} }
/* Now pick the best path through the whole trellis. */ /* Now pick the best path through the whole trellis. */
band = get_coef_band(tx_size, i + 1); band = get_coef_band(scan, tx_size, i + 1);
VP9_COMBINEENTROPYCONTEXTS(pt, *a, *l); VP9_COMBINEENTROPYCONTEXTS(pt, *a, *l);
rate0 = tokens[next][0].rate; rate0 = tokens[next][0].rate;
rate1 = tokens[next][1].rate; rate1 = tokens[next][1].rate;
......
...@@ -565,12 +565,12 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb, ...@@ -565,12 +565,12 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
nzc += (v != 0); nzc += (v != 0);
#endif #endif
token_cache[c] = t; token_cache[c] = t;
cost += token_costs[get_coef_band(tx_size, c)][pt][t]; cost += token_costs[get_coef_band(scan, tx_size, c)][pt][t];
cost += vp9_dct_value_cost_ptr[v]; cost += vp9_dct_value_cost_ptr[v];
#if !CONFIG_CODE_NONZEROCOUNT #if !CONFIG_CODE_NONZEROCOUNT
if (!c || token_cache[c - 1]) if (!c || token_cache[c - 1])
cost += vp9_cost_bit(coef_probs[type][ref] cost += vp9_cost_bit(coef_probs[type][ref]
[get_coef_band(tx_size, c)] [get_coef_band(scan, tx_size, c)]
[pt][0], 1); [pt][0], 1);
#endif #endif
pt = vp9_get_coef_context(scan, nb, pad, token_cache, c, default_eob); pt = vp9_get_coef_context(scan, nb, pad, token_cache, c, default_eob);
...@@ -579,7 +579,8 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb, ...@@ -579,7 +579,8 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
cost += nzc_cost[nzc]; cost += nzc_cost[nzc];
#else #else
if (c < seg_eob) if (c < seg_eob)
cost += mb->token_costs[tx_size][type][ref][get_coef_band(tx_size, c)] cost += mb->token_costs[tx_size][type][ref]
[get_coef_band(scan, tx_size, c)]
[pt][DCT_EOB_TOKEN]; [pt][DCT_EOB_TOKEN];
#endif #endif
} }
......
...@@ -229,7 +229,7 @@ static void tokenize_b(VP9_COMP *cpi, ...@@ -229,7 +229,7 @@ static void tokenize_b(VP9_COMP *cpi,
seg_eob = 0; seg_eob = 0;
do { do {
const int band = get_coef_band(tx_size, c); const int band = get_coef_band(scan, tx_size, c);
int token; int token;
int v = 0; int v = 0;
#if CONFIG_CODE_NONZEROCOUNT #if CONFIG_CODE_NONZEROCOUNT
......
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