Framework changes in nzc to allow more flexibility

The patch adds the flexibility to use standard EOB based coding
on smaller block sizes and nzc based coding on larger blocksizes.
The tx-sizes that use nzc based coding and those that use EOB based
coding are controlled by a function get_nzc_used().
By default, this function uses nzc based coding for 16x16 and 32x32
transform blocks, which seem to bridge the performance gap
substantially.

All sets are now lower by 0.5% to 0.7%, as opposed to ~1.8% before.

Change-Id: I06abed3df57b52d241ea1f51b0d571c71e38fd0b
This commit is contained in:
Deb Mukherjee
2013-03-26 15:23:30 -07:00
parent 9ba8aed179
commit fe9b5143ba
11 changed files with 250 additions and 163 deletions

View File

@@ -149,10 +149,10 @@ const MODE_DEFINITION vp9_mode_order[MAX_MODES] = {
static void fill_token_costs(vp9_coeff_count *c,
vp9_coeff_probs *p,
int block_type_counts) {
TX_SIZE tx_size) {
int i, j, k, l;
for (i = 0; i < block_type_counts; i++)
for (i = 0; i < BLOCK_TYPES; i++)
for (j = 0; j < REF_TYPES; j++)
for (k = 0; k < COEF_BANDS; k++)
for (l = 0; l < PREV_COEF_CONTEXTS; l++) {
@@ -163,26 +163,26 @@ static void fill_token_costs(vp9_coeff_count *c,
}
#if CONFIG_CODE_NONZEROCOUNT
static void fill_nzc_costs(VP9_COMP *cpi, int block_size) {
static void fill_nzc_costs(VP9_COMP *cpi, TX_SIZE tx_size) {
int nzc_context, r, b, nzc, values;
int cost[16];
values = block_size * block_size + 1;
values = (16 << (2 * tx_size)) + 1;
for (nzc_context = 0; nzc_context < MAX_NZC_CONTEXTS; ++nzc_context) {
for (r = 0; r < REF_TYPES; ++r) {
for (b = 0; b < BLOCK_TYPES; ++b) {
unsigned int *nzc_costs;
if (block_size == 4) {
if (tx_size == TX_4X4) {
vp9_cost_tokens(cost,
cpi->common.fc.nzc_probs_4x4[nzc_context][r][b],
vp9_nzc4x4_tree);
nzc_costs = cpi->mb.nzc_costs_4x4[nzc_context][r][b];
} else if (block_size == 8) {
} else if (tx_size == TX_8X8) {
vp9_cost_tokens(cost,
cpi->common.fc.nzc_probs_8x8[nzc_context][r][b],
vp9_nzc8x8_tree);
nzc_costs = cpi->mb.nzc_costs_8x8[nzc_context][r][b];
} else if (block_size == 16) {
} else if (tx_size == TX_16X16) {
vp9_cost_tokens(cost,
cpi->common.fc.nzc_probs_16x16[nzc_context][r][b],
vp9_nzc16x16_tree);
@@ -308,18 +308,18 @@ void vp9_initialize_rd_consts(VP9_COMP *cpi, int qindex) {
}
fill_token_costs(cpi->mb.token_costs[TX_4X4],
cpi->common.fc.coef_probs_4x4, BLOCK_TYPES);
cpi->common.fc.coef_probs_4x4, TX_4X4);
fill_token_costs(cpi->mb.token_costs[TX_8X8],
cpi->common.fc.coef_probs_8x8, BLOCK_TYPES);
cpi->common.fc.coef_probs_8x8, TX_8X8);
fill_token_costs(cpi->mb.token_costs[TX_16X16],
cpi->common.fc.coef_probs_16x16, BLOCK_TYPES);
cpi->common.fc.coef_probs_16x16, TX_16X16);
fill_token_costs(cpi->mb.token_costs[TX_32X32],
cpi->common.fc.coef_probs_32x32, BLOCK_TYPES);
cpi->common.fc.coef_probs_32x32, TX_32X32);
#if CONFIG_CODE_NONZEROCOUNT
fill_nzc_costs(cpi, 4);
fill_nzc_costs(cpi, 8);
fill_nzc_costs(cpi, 16);
fill_nzc_costs(cpi, 32);
fill_nzc_costs(cpi, TX_4X4);
fill_nzc_costs(cpi, TX_8X8);
fill_nzc_costs(cpi, TX_16X16);
fill_nzc_costs(cpi, TX_32X32);
#endif
/*rough estimate for costing*/
@@ -449,13 +449,13 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
sizeof(ENTROPY_CONTEXT_PLANES)/sizeof(ENTROPY_CONTEXT);
#if CONFIG_CODE_NONZEROCOUNT
const int nzc_used = get_nzc_used(tx_size);
int nzc_context = vp9_get_nzc_context(cm, xd, ib);
unsigned int *nzc_cost;
#else
#endif
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];
@@ -475,9 +475,8 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
l_ec = *l;
#if CONFIG_CODE_NONZEROCOUNT
nzc_cost = mb->nzc_costs_4x4[nzc_context][ref][type];
#else
coef_probs = cm->fc.coef_probs_4x4;
#endif
coef_probs = cm->fc.coef_probs_4x4;
seg_eob = 16;
if (tx_type == ADST_DCT) {
scan = vp9_row_scan_4x4;
@@ -504,9 +503,8 @@ 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
coef_probs = cm->fc.coef_probs_8x8;
#endif
coef_probs = cm->fc.coef_probs_8x8;
seg_eob = 64;
break;
}
@@ -524,9 +522,8 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
}
#if CONFIG_CODE_NONZEROCOUNT
nzc_cost = mb->nzc_costs_16x16[nzc_context][ref][type];
#else
coef_probs = cm->fc.coef_probs_16x16;
#endif
coef_probs = cm->fc.coef_probs_16x16;
seg_eob = 256;
if (type == PLANE_TYPE_UV) {
a_ec = (a[0] + a[1] + a1[0] + a1[1]) != 0;
@@ -541,9 +538,8 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
scan = vp9_default_zig_zag1d_32x32;
#if CONFIG_CODE_NONZEROCOUNT
nzc_cost = mb->nzc_costs_32x32[nzc_context][ref][type];
#else
coef_probs = cm->fc.coef_probs_32x32;
#endif
coef_probs = cm->fc.coef_probs_32x32;
seg_eob = 1024;
if (type == PLANE_TYPE_UV) {
ENTROPY_CONTEXT *a2, *a3, *l2, *l3;
@@ -571,10 +567,11 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
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))
seg_eob = 0;
#if CONFIG_CODE_NONZEROCOUNT
if (!nzc_used)
#endif
if (vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))
seg_eob = 0;
{
#if CONFIG_CODE_NONZEROCOUNT
@@ -598,13 +595,14 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb,
pt = vp9_get_coef_context(scan, nb, pad, token_cache, c, default_eob);
}
#if CONFIG_CODE_NONZEROCOUNT
cost += nzc_cost[nzc];
#else
if (c < seg_eob)
cost += mb->token_costs[tx_size][type][ref]
[get_coef_band(scan, tx_size, c)]
[pt][DCT_EOB_TOKEN];
if (nzc_used)
cost += nzc_cost[nzc];
else
#endif
if (c < seg_eob)
cost += mb->token_costs[tx_size][type][ref]
[get_coef_band(scan, tx_size, c)]
[pt][DCT_EOB_TOKEN];
}
// is eob first coefficient;