Commit 3120dbdd by Ronald S. Bultje

### 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%.

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!