Commit 790fb132 authored by Ronald S. Bultje's avatar Ronald S. Bultje

Use above/left (instead of previous in scan-order) as token context.

Pearson correlation for above or left is significantly higher than for
previous-in-scan-order (absolute values depend on position in scan, but
in general, we gain about 0.1-0.2 by using either above or left; using
both basically just makes this even better). For eob branch skipping,
we continue to use the previous token in scan order.

This helps about 0.9% on derf after re-training on a limited data set.
Full re-training and results on larger-resolution clips are pending.

Note that this commit breaks trellis, so we can probably get further
gains out of it by fixing trellis at some later point.

Change-Id: Iead68e296fc3a105cca746b5e3da9555d6010cfe
parent 64661660
This diff is collapsed.
......@@ -1886,25 +1886,25 @@ vp9_extra_bit_struct vp9_extra_bits[12] = {
// within the current block.
//
// For now it just returns the previously used context.
int vp9_get_coef_context(int * recent_energy, int token) {
// int token_energy;
// int av_energy;
/*token_energy = ((token != DCT_EOB_TOKEN) ? token : 0);
if (!token_energy) {
if (!(*recent_energy)) {
av_energy = 0;
#define MAX_NEIGHBORS 2
int vp9_get_coef_context(const int *scan, const int *neighbors,
int nb_pad, uint8_t *token_cache, int c, int l) {
int eob = l;
assert(nb_pad == MAX_NEIGHBORS);
if (c == eob - 1) {
return 0;
} else {
int ctx;
c++;
assert(neighbors[MAX_NEIGHBORS * c + 0] >= 0);
if (neighbors[MAX_NEIGHBORS * c + 1] >= 0) {
ctx = (1 + token_cache[neighbors[MAX_NEIGHBORS * c + 0]] +
token_cache[neighbors[MAX_NEIGHBORS * c + 1]]) >> 1;
} else {
av_energy = 1;
ctx = token_cache[neighbors[MAX_NEIGHBORS * c + 0]];
}
} else {
av_energy = ((token_energy + *recent_energy + 1) >> 1) + 1;
if (av_energy > DCT_VAL_CATEGORY6)
av_energy = DCT_VAL_CATEGORY6;
return vp9_pt_energy_class[ctx];
}
*recent_energy = token_energy;*/
return vp9_pt_energy_class[token];
};
void vp9_default_coef_probs(VP9_COMMON *pc) {
......@@ -2063,7 +2063,119 @@ void vp9_adjust_default_coef_probs(VP9_COMMON *cm) {
}
#endif
// Neighborhood 5-tuples for various scans and blocksizes,
// in {top, left, topleft, topright, bottomleft} order
// for each position in raster scan order.
// -1 indicates the neighbor does not exist.
DECLARE_ALIGNED(16, int,
vp9_default_zig_zag1d_4x4_neighbors[16 * MAX_NEIGHBORS]);
DECLARE_ALIGNED(16, int,
vp9_col_scan_4x4_neighbors[16 * MAX_NEIGHBORS]);
DECLARE_ALIGNED(16, int,
vp9_row_scan_4x4_neighbors[16 * MAX_NEIGHBORS]);
DECLARE_ALIGNED(16, int,
vp9_default_zig_zag1d_8x8_neighbors[64 * MAX_NEIGHBORS]);
DECLARE_ALIGNED(16, int,
vp9_default_zig_zag1d_16x16_neighbors[256 * MAX_NEIGHBORS]);
DECLARE_ALIGNED(16, int,
vp9_default_zig_zag1d_32x32_neighbors[1024 * MAX_NEIGHBORS]);
static int find_in_scan(const int *scan, int l, int idx) {
int n, l2 = l * l;
for (n = 0; n < l2; n++) {
int rc = scan[n];
if (rc == idx)
return n;
}
assert(0);
return -1;
}
static void init_scan_neighbors(const int *scan, int l, int *neighbors,
int max_neighbors) {
int l2 = l * l;
int n, i, j;
for (n = 0; n < l2; n++) {
int rc = scan[n];
assert(max_neighbors == MAX_NEIGHBORS);
i = rc / l;
j = rc % l;
if (i > 0 && j > 0) {
// col/row scan is used for adst/dct, and generally means that
// energy decreases to zero much faster in the dimension in
// which ADST is used compared to the direction in which DCT
// is used. Likewise, we find much higher correlation between
// coefficients within the direction in which DCT is used.
// Therefore, if we use ADST/DCT, prefer the DCT neighbor coeff
// as a context. If ADST or DCT is used in both directions, we
// use the combination of the two as a context.
int a = find_in_scan(scan, l, (i - 1) * l + j);
int b = find_in_scan(scan, l, i * l + j - 1);
if (scan == vp9_col_scan_4x4 || scan == vp9_row_scan_4x4) {
neighbors[max_neighbors * n + 0] = MAX(a, b);
neighbors[max_neighbors * n + 1] = -1;
} else {
neighbors[max_neighbors * n + 0] = a;
neighbors[max_neighbors * n + 1] = b;
}
} else if (i > 0) {
neighbors[max_neighbors * n + 0] = find_in_scan(scan, l, (i - 1) * l + j);
neighbors[max_neighbors * n + 1] = -1;
} else if (j > 0) {
neighbors[max_neighbors * n + 0] =
find_in_scan(scan, l, i * l + j - 1);
neighbors[max_neighbors * n + 1] = -1;
} else {
assert(n == 0);
// dc predictor doesn't use previous tokens
neighbors[max_neighbors * n + 0] = -1;
}
assert(neighbors[max_neighbors * n + 0] < n);
}
}
void vp9_init_neighbors() {
init_scan_neighbors(vp9_default_zig_zag1d_4x4, 4,
vp9_default_zig_zag1d_4x4_neighbors, MAX_NEIGHBORS);
init_scan_neighbors(vp9_row_scan_4x4, 4,
vp9_row_scan_4x4_neighbors, MAX_NEIGHBORS);
init_scan_neighbors(vp9_col_scan_4x4, 4,
vp9_col_scan_4x4_neighbors, MAX_NEIGHBORS);
init_scan_neighbors(vp9_default_zig_zag1d_8x8, 8,
vp9_default_zig_zag1d_8x8_neighbors, MAX_NEIGHBORS);
init_scan_neighbors(vp9_default_zig_zag1d_16x16, 16,
vp9_default_zig_zag1d_16x16_neighbors, MAX_NEIGHBORS);
init_scan_neighbors(vp9_default_zig_zag1d_32x32, 32,
vp9_default_zig_zag1d_32x32_neighbors, MAX_NEIGHBORS);
}
const int *vp9_get_coef_neighbors_handle(const int *scan, int *pad) {
if (scan == vp9_default_zig_zag1d_4x4) {
*pad = MAX_NEIGHBORS;
return vp9_default_zig_zag1d_4x4_neighbors;
} else if (scan == vp9_row_scan_4x4) {
*pad = MAX_NEIGHBORS;
return vp9_row_scan_4x4_neighbors;
} else if (scan == vp9_col_scan_4x4) {
*pad = MAX_NEIGHBORS;
return vp9_col_scan_4x4_neighbors;
} else if (scan == vp9_default_zig_zag1d_8x8) {
*pad = MAX_NEIGHBORS;
return vp9_default_zig_zag1d_8x8_neighbors;
} else if (scan == vp9_default_zig_zag1d_16x16) {
*pad = MAX_NEIGHBORS;
return vp9_default_zig_zag1d_16x16_neighbors;
} else if (scan == vp9_default_zig_zag1d_32x32) {
*pad = MAX_NEIGHBORS;
return vp9_default_zig_zag1d_32x32_neighbors;
} else {
assert(0);
return NULL;
}
}
void vp9_coef_tree_initialize() {
vp9_init_neighbors();
init_bit_trees();
vp9_tokens_from_tree(vp9_coef_encodings, vp9_coef_tree);
#if CONFIG_CODE_NONZEROCOUNT
......@@ -3170,6 +3282,9 @@ void vp9_update_nzc_counts(VP9_COMMON *cm,
static void adapt_coef_probs(vp9_coeff_probs *dst_coef_probs,
vp9_coeff_probs *pre_coef_probs,
int block_types, vp9_coeff_count *coef_counts,
unsigned int (*eob_branch_count)[REF_TYPES]
[COEF_BANDS]
[PREV_COEF_CONTEXTS],
int count_sat, int update_factor) {
int t, i, j, k, l, count;
unsigned int branch_ct[ENTROPY_NODES][2];
......@@ -3190,6 +3305,8 @@ static void adapt_coef_probs(vp9_coeff_probs *dst_coef_probs,
vp9_tree_probs_from_distribution(vp9_coef_tree,
coef_probs, branch_ct,
coef_counts[i][j][k][l], 0);
branch_ct[0][1] = eob_branch_count[i][j][k][l] - branch_ct[0][0];
coef_probs[0] = get_binary_prob(branch_ct[0][0], branch_ct[0][1]);
for (t = 0; t < entropy_nodes_adapt; ++t) {
count = branch_ct[t][0] + branch_ct[t][1];
count = count > count_sat ? count_sat : count;
......@@ -3224,15 +3341,19 @@ void vp9_adapt_coef_probs(VP9_COMMON *cm) {
adapt_coef_probs(cm->fc.coef_probs_4x4, cm->fc.pre_coef_probs_4x4,
BLOCK_TYPES, cm->fc.coef_counts_4x4,
cm->fc.eob_branch_counts[TX_4X4],
count_sat, update_factor);
adapt_coef_probs(cm->fc.coef_probs_8x8, cm->fc.pre_coef_probs_8x8,
BLOCK_TYPES, cm->fc.coef_counts_8x8,
cm->fc.eob_branch_counts[TX_8X8],
count_sat, update_factor);
adapt_coef_probs(cm->fc.coef_probs_16x16, cm->fc.pre_coef_probs_16x16,
BLOCK_TYPES, cm->fc.coef_counts_16x16,
cm->fc.eob_branch_counts[TX_16X16],
count_sat, update_factor);
adapt_coef_probs(cm->fc.coef_probs_32x32, cm->fc.pre_coef_probs_32x32,
BLOCK_TYPES, cm->fc.coef_counts_32x32,
cm->fc.eob_branch_counts[TX_32X32],
count_sat, update_factor);
}
......
......@@ -139,7 +139,9 @@ static int get_coef_band(TX_SIZE tx_size, int coef_index) {
return 5;
}
}
extern int vp9_get_coef_context(int * recent_energy, int token);
extern int vp9_get_coef_context(const int *scan, const int *neighbors,
int nb_pad, uint8_t *token_cache, int c, int l);
const int *vp9_get_coef_neighbors_handle(const int *scan, int *pad);
#if CONFIG_MODELCOEFPROB
#define COEFPROB_BITS 8
......
......@@ -114,6 +114,9 @@ typedef struct frame_contexts {
vp9_coeff_count coef_counts_8x8[BLOCK_TYPES];
vp9_coeff_count coef_counts_16x16[BLOCK_TYPES];
vp9_coeff_count coef_counts_32x32[BLOCK_TYPES];
unsigned int eob_branch_counts[TX_SIZE_MAX_SB][BLOCK_TYPES][REF_TYPES]
[COEF_BANDS][PREV_COEF_CONTEXTS];
#if CONFIG_CODE_NONZEROCOUNT
unsigned int nzc_counts_4x4[MAX_NZC_CONTEXTS][REF_TYPES][BLOCK_TYPES]
[NZC4X4_TOKENS];
......
......@@ -1716,6 +1716,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
vp9_zero(pbi->common.fc.coef_counts_8x8);
vp9_zero(pbi->common.fc.coef_counts_16x16);
vp9_zero(pbi->common.fc.coef_counts_32x32);
vp9_zero(pbi->common.fc.eob_branch_counts);
vp9_zero(pbi->common.fc.ymode_counts);
vp9_zero(pbi->common.fc.sb_ymode_counts);
vp9_zero(pbi->common.fc.uv_mode_counts);
......
......@@ -66,7 +66,8 @@ static int get_signed(BOOL_DECODER *br, int value_to_sign) {
#define INCREMENT_COUNT(token) \
do { \
coef_counts[type][ref][get_coef_band(txfm_size, c)][pt][token]++; \
pt = vp9_get_coef_context(&recent_energy, token); \
token_cache[c] = token; \
pt = vp9_get_coef_context(scan, nb, pad, token_cache, c, default_eob); \
} while (0)
#if CONFIG_CODE_NONZEROCOUNT
......@@ -103,8 +104,7 @@ static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
int aidx, lidx;
ENTROPY_CONTEXT above_ec, left_ec;
FRAME_CONTEXT *const fc = &dx->common.fc;
int recent_energy = 0;
int pt, c = 0;
int pt, c = 0, pad, default_eob;
vp9_coeff_probs *coef_probs;
vp9_prob *prob;
vp9_coeff_count *coef_counts;
......@@ -113,7 +113,8 @@ static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
uint16_t nzc = 0;
uint16_t nzc_expected = xd->mode_info_context->mbmi.nzcs[block_idx];
#endif
const int *scan;
const int *scan, *nb;
uint8_t token_cache[1024];
if (xd->mode_info_context->mbmi.sb_type == BLOCK_SIZE_SB64X64) {
aidx = vp9_block2above_sb64[txfm_size][block_idx];
......@@ -145,6 +146,7 @@ static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
left_ec = L0[lidx] != 0;
coef_probs = fc->coef_probs_4x4;
coef_counts = fc->coef_counts_4x4;
default_eob = 16;
break;
}
case TX_8X8:
......@@ -153,6 +155,7 @@ static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
coef_counts = fc->coef_counts_8x8;
above_ec = (A0[aidx] + A0[aidx + 1]) != 0;
left_ec = (L0[lidx] + L0[lidx + 1]) != 0;
default_eob = 64;
break;
case TX_16X16:
scan = vp9_default_zig_zag1d_16x16;
......@@ -167,6 +170,7 @@ static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
above_ec = (A0[aidx] + A0[aidx + 1] + A0[aidx + 2] + A0[aidx + 3]) != 0;
left_ec = (L0[lidx] + L0[lidx + 1] + L0[lidx + 2] + L0[lidx + 3]) != 0;
}
default_eob = 256;
break;
case TX_32X32:
scan = vp9_default_zig_zag1d_32x32;
......@@ -191,10 +195,13 @@ static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
left_ec = (L0[lidx] + L0[lidx + 1] + L0[lidx + 2] + L0[lidx + 3] +
L1[lidx] + L1[lidx + 1] + L1[lidx + 2] + L1[lidx + 3]) != 0;
}
default_eob = 1024;
break;
}
VP9_COMBINEENTROPYCONTEXTS(pt, above_ec, left_ec);
nb = vp9_get_coef_neighbors_handle(scan, &pad);
while (1) {
int val;
const uint8_t *cat6 = cat6_prob;
......@@ -207,6 +214,8 @@ static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd,
#endif
prob = coef_probs[type][ref][get_coef_band(txfm_size, c)][pt];
#if CONFIG_CODE_NONZEROCOUNT == 0
fc->eob_branch_counts[txfm_size][type][ref]
[get_coef_band(txfm_size, c)][pt]++;
if (!vp9_read(br, prob[EOB_CONTEXT_NODE]))
break;
#endif
......
......@@ -1758,6 +1758,9 @@ static void print_prob_tree(vp9_coeff_probs *coef_probs, int block_types) {
static void build_tree_distribution(vp9_coeff_probs *coef_probs,
vp9_coeff_count *coef_counts,
unsigned int (*eob_branch_ct)[REF_TYPES]
[COEF_BANDS]
[PREV_COEF_CONTEXTS],
#ifdef ENTROPY_STATS
VP9_COMP *cpi,
vp9_coeff_accum *context_counters,
......@@ -1779,10 +1782,18 @@ static void build_tree_distribution(vp9_coeff_probs *coef_probs,
coef_probs[i][j][k][l],
coef_branch_ct[i][j][k][l],
coef_counts[i][j][k][l], 0);
coef_branch_ct[i][j][k][l][0][1] = eob_branch_ct[i][j][k][l] -
coef_branch_ct[i][j][k][l][0][0];
coef_probs[i][j][k][l][0] =
get_binary_prob(coef_branch_ct[i][j][k][l][0][0],
coef_branch_ct[i][j][k][l][0][1]);
#ifdef ENTROPY_STATS
if (!cpi->dummy_packing)
for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
context_counters[i][j][k][l][t] += coef_counts[i][j][k][l][t];
if (!cpi->dummy_packing) {
for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
context_counters[i][j][k][l][t] += coef_counts[i][j][k][l][t];
context_counters[i][j][k][l][MAX_ENTROPY_TOKENS] +=
eob_branch_ct[i][j][k][l];
}
#endif
}
}
......@@ -1793,24 +1804,28 @@ static void build_tree_distribution(vp9_coeff_probs *coef_probs,
static void build_coeff_contexts(VP9_COMP *cpi) {
build_tree_distribution(cpi->frame_coef_probs_4x4,
cpi->coef_counts_4x4,
cpi->common.fc.eob_branch_counts[TX_4X4],
#ifdef ENTROPY_STATS
cpi, context_counters_4x4,
#endif
cpi->frame_branch_ct_4x4, BLOCK_TYPES);
build_tree_distribution(cpi->frame_coef_probs_8x8,
cpi->coef_counts_8x8,
cpi->common.fc.eob_branch_counts[TX_8X8],
#ifdef ENTROPY_STATS
cpi, context_counters_8x8,
#endif
cpi->frame_branch_ct_8x8, BLOCK_TYPES);
build_tree_distribution(cpi->frame_coef_probs_16x16,
cpi->coef_counts_16x16,
cpi->common.fc.eob_branch_counts[TX_16X16],
#ifdef ENTROPY_STATS
cpi, context_counters_16x16,
#endif
cpi->frame_branch_ct_16x16, BLOCK_TYPES);
build_tree_distribution(cpi->frame_coef_probs_32x32,
cpi->coef_counts_32x32,
cpi->common.fc.eob_branch_counts[TX_32X32],
#ifdef ENTROPY_STATS
cpi, context_counters_32x32,
#endif
......
......@@ -1276,6 +1276,7 @@ static void encode_frame_internal(VP9_COMP *cpi) {
vp9_zero(cpi->coef_counts_8x8);
vp9_zero(cpi->coef_counts_16x16);
vp9_zero(cpi->coef_counts_32x32);
vp9_zero(cm->fc.eob_branch_counts);
#if CONFIG_CODE_NONZEROCOUNT
vp9_zero(cm->fc.nzc_counts_4x4);
vp9_zero(cm->fc.nzc_counts_8x8);
......
......@@ -528,9 +528,16 @@ static const int plane_rd_mult[4] = {
// This function is a place holder for now but may ultimately need
// to scan previous tokens to work out the correct context.
static int trellis_get_coeff_context(int token) {
int recent_energy = 0;
return vp9_get_coef_context(&recent_energy, token);
static int trellis_get_coeff_context(const int *scan,
const int *nb,
int idx, int token,
uint8_t *token_cache,
int pad, int l) {
int bak = token_cache[idx], pt;
token_cache[idx] = token;
pt = vp9_get_coef_context(scan, nb, pad, token_cache, idx + 1, l);
token_cache[idx] = bak;
return pt;
}
static void optimize_b(VP9_COMMON *const cm,
......@@ -552,9 +559,10 @@ static void optimize_b(VP9_COMMON *const cm,
int rate0, rate1, error0, error1, t0, t1;
int best, band, pt;
int err_mult = plane_rd_mult[type];
int default_eob;
int const *scan;
int default_eob, pad;
int const *scan, *nb;
const int mul = 1 + (tx_size == TX_32X32);
uint8_t token_cache[1024];
#if CONFIG_CODE_NONZEROCOUNT
// TODO(debargha): the dynamic programming approach used in this function
// is not compatible with the true rate cost when nzcs are used. Note
......@@ -631,6 +639,10 @@ static void optimize_b(VP9_COMMON *const cm,
tokens[eob][0].qc = 0;
*(tokens[eob] + 1) = *(tokens[eob] + 0);
next = eob;
for (i = 0; i < eob; i++)
token_cache[i] = vp9_dct_value_tokens_ptr[qcoeff_ptr[scan[i]]].Token;
nb = vp9_get_coef_neighbors_handle(scan, &pad);
for (i = eob; i-- > i0;) {
int base_bits, d2, dx;
#if CONFIG_CODE_NONZEROCOUNT
......@@ -651,7 +663,8 @@ static void optimize_b(VP9_COMMON *const cm,
/* Consider both possible successor states. */
if (next < default_eob) {
band = get_coef_band(tx_size, i + 1);
pt = trellis_get_coeff_context(t0);
pt = trellis_get_coeff_context(scan, nb, i, t0, token_cache,
pad, default_eob);
rate0 +=
mb->token_costs[tx_size][type][ref][band][pt][tokens[next][0].token];
rate1 +=
......@@ -710,12 +723,14 @@ static void optimize_b(VP9_COMMON *const cm,
if (next < default_eob) {
band = get_coef_band(tx_size, i + 1);
if (t0 != DCT_EOB_TOKEN) {
pt = trellis_get_coeff_context(t0);
pt = trellis_get_coeff_context(scan, nb, i, t0, token_cache,
pad, default_eob);
rate0 += mb->token_costs[tx_size][type][ref][band][pt][
tokens[next][0].token];
}
if (t1 != DCT_EOB_TOKEN) {
pt = trellis_get_coeff_context(t1);
pt = trellis_get_coeff_context(scan, nb, i, t1, token_cache,
pad, default_eob);
rate1 += mb->token_costs[tx_size][type][ref][band][pt][
tokens[next][1].token];
}
......
......@@ -156,21 +156,9 @@ static void fill_token_costs(vp9_coeff_count *c,
for (j = 0; j < REF_TYPES; j++)
for (k = 0; k < COEF_BANDS; k++)
for (l = 0; l < PREV_COEF_CONTEXTS; l++) {
#if CONFIG_CODE_NONZEROCOUNT
// All costs are without the EOB node
vp9_cost_tokens_skip((int *)(c[i][j][k][l]),
p[i][j][k][l],
vp9_coef_tree);
#else
if (l == 0 && k > 0)
vp9_cost_tokens_skip((int *)(c[i][j][k][l]),
p[i][j][k][l],
vp9_coef_tree);
else
vp9_cost_tokens((int *)(c[i][j][k][l]),
p[i][j][k][l],
vp9_coef_tree);
#endif
}
}
......@@ -448,8 +436,8 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
int pt;
const int eob = xd->eobs[ib];
int c = 0;
int cost = 0;
const int *scan;
int cost = 0, pad;
const int *scan, *nb;
const int16_t *qcoeff_ptr = xd->qcoeff + ib * 16;
const int ref = mbmi->ref_frame != INTRA_FRAME;
unsigned int (*token_costs)[PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS] =
......@@ -464,9 +452,12 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
int nzc_context = vp9_get_nzc_context(cm, xd, ib);
unsigned int *nzc_cost;
#else
int seg_eob;
const int segment_id = xd->mode_info_context->mbmi.segment_id;
vp9_prob (*coef_probs)[REF_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS]
[ENTROPY_NODES];
#endif
int seg_eob, default_eob;
uint8_t token_cache[1024];
// Check for consistency of tx_size with mode info
if (type == PLANE_TYPE_Y_WITH_DC) {
......@@ -485,8 +476,9 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
#if CONFIG_CODE_NONZEROCOUNT
nzc_cost = mb->nzc_costs_4x4[nzc_context][ref][type];
#else
seg_eob = 16;
coef_probs = cm->fc.coef_probs_4x4;
#endif
seg_eob = 16;
if (tx_type == ADST_DCT) {
scan = vp9_row_scan_4x4;
} else if (tx_type == DCT_ADST) {
......@@ -503,16 +495,18 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
#if CONFIG_CODE_NONZEROCOUNT
nzc_cost = mb->nzc_costs_8x8[nzc_context][ref][type];
#else
seg_eob = 64;
coef_probs = cm->fc.coef_probs_8x8;
#endif
seg_eob = 64;
break;
case TX_16X16:
scan = vp9_default_zig_zag1d_16x16;
#if CONFIG_CODE_NONZEROCOUNT
nzc_cost = mb->nzc_costs_16x16[nzc_context][ref][type];
#else
seg_eob = 256;
coef_probs = cm->fc.coef_probs_16x16;
#endif
seg_eob = 256;
if (type == PLANE_TYPE_UV) {
a_ec = (a[0] + a[1] + a1[0] + a1[1]) != 0;
l_ec = (l[0] + l[1] + l1[0] + l1[1]) != 0;
......@@ -526,8 +520,9 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
#if CONFIG_CODE_NONZEROCOUNT
nzc_cost = mb->nzc_costs_32x32[nzc_context][ref][type];
#else
seg_eob = 1024;
coef_probs = cm->fc.coef_probs_32x32;
#endif
seg_eob = 1024;
if (type == PLANE_TYPE_UV) {
ENTROPY_CONTEXT *a2, *a3, *l2, *l3;
a2 = a1 + sizeof(ENTROPY_CONTEXT_PLANES) / sizeof(ENTROPY_CONTEXT);
......@@ -551,6 +546,8 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
}
VP9_COMBINEENTROPYCONTEXTS(pt, a_ec, l_ec);
nb = vp9_get_coef_neighbors_handle(scan, &pad);
default_eob = seg_eob;
#if CONFIG_CODE_NONZEROCOUNT == 0
if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))
......@@ -558,7 +555,6 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
#endif
{
int recent_energy = 0;
#if CONFIG_CODE_NONZEROCOUNT
int nzc = 0;
#endif
......@@ -568,9 +564,16 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
#if CONFIG_CODE_NONZEROCOUNT
nzc += (v != 0);
#endif
token_cache[c] = t;
cost += token_costs[get_coef_band(tx_size, c)][pt][t];
cost += vp9_dct_value_cost_ptr[v];
pt = vp9_get_coef_context(&recent_energy, t);
#if !CONFIG_CODE_NONZEROCOUNT
if (!c || token_cache[c - 1])
cost += vp9_cost_bit(coef_probs[type][ref]
[get_coef_band(tx_size, c)]
[pt][0], 1);
#endif
pt = vp9_get_coef_context(scan, nb, pad, token_cache, c, default_eob);
}
#if CONFIG_CODE_NONZEROCOUNT
cost += nzc_cost[nzc];
......
......@@ -109,6 +109,8 @@ static void fill_value_tokens() {
vp9_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE;
}
extern const int *vp9_get_coef_neighbors_handle(const int *scan, int *pad);
static void tokenize_b(VP9_COMP *cpi,
MACROBLOCKD *xd,
const int ib,
......@@ -119,18 +121,18 @@ static void tokenize_b(VP9_COMP *cpi,
MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
int pt; /* near block/prev token context index */
int c = 0;
int recent_energy = 0;
const int eob = xd->eobs[ib]; /* one beyond last nonzero coeff */
TOKENEXTRA *t = *tp; /* store tokens starting here */
int16_t *qcoeff_ptr = xd->qcoeff + 16 * ib;
int seg_eob;
int seg_eob, default_eob, pad;
const int segment_id = mbmi->segment_id;
const BLOCK_SIZE_TYPE sb_type = mbmi->sb_type;
const int *scan;
const int *scan, *nb;
vp9_coeff_count *counts;
vp9_coeff_probs *probs;
const int ref = mbmi->ref_frame != INTRA_FRAME;
ENTROPY_CONTEXT *a, *l, *a1, *l1, *a2, *l2, *a3, *l3, a_ec, l_ec;
uint8_t token_cache[1024];
#if CONFIG_CODE_NONZEROCOUNT
int zerosleft, nzc = 0;
if (eob == 0)
......@@ -220,6 +222,8 @@ static void tokenize_b(VP9_COMP *cpi,
}
VP9_COMBINEENTROPYCONTEXTS(pt, a_ec, l_ec);
nb = vp9_get_coef_neighbors_handle(scan, &pad);
default_eob = seg_eob;
if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))
seg_eob = 0;
......@@ -252,17 +256,20 @@ static void tokenize_b(VP9_COMP *cpi,
// Skip zero node if there are no zeros left
t->skip_eob_node = 1 + (zerosleft == 0);
#else
t->skip_eob_node = (pt == 0) && (band > 0);
t->skip_eob_node = (c > 0) && (token_cache[c - 1] == 0);
#endif
assert(vp9_coef_encodings[t->Token].Len - t->skip_eob_node > 0);
if (!dry_run) {
++counts[type][ref][band][pt][token];
if (!t->skip_eob_node)
++cpi->common.fc.eob_branch_counts[tx_size][type][ref][band][pt];
}
#if CONFIG_CODE_NONZEROCOUNT
nzc += (v != 0);
#endif
token_cache[c] = token;