Merge "Tokenization without huge tables."

This commit is contained in:
Jim Bankoski 2014-12-22 13:36:38 -08:00 committed by Gerrit Code Review
commit fba0ead543
4 changed files with 83 additions and 88 deletions

View File

@ -149,7 +149,6 @@ static int optimize_b(MACROBLOCK *mb, int plane, int block,
int64_t rd_cost0, rd_cost1;
int rate0, rate1, error0, error1, t0, t1;
int best, band, pt, i, final_eob;
const TOKENVALUE *dct_value_tokens;
const int16_t *dct_value_cost;
assert((!type && !plane) || (type && plane));
@ -169,22 +168,18 @@ static int optimize_b(MACROBLOCK *mb, int plane, int block,
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->bd == 12) {
dct_value_tokens = vp9_dct_value_tokens_high12_ptr;
dct_value_cost = vp9_dct_value_cost_high12_ptr;
} else if (xd->bd == 10) {
dct_value_tokens = vp9_dct_value_tokens_high10_ptr;
dct_value_cost = vp9_dct_value_cost_high10_ptr;
} else {
dct_value_tokens = vp9_dct_value_tokens_ptr;
dct_value_cost = vp9_dct_value_cost_ptr;
}
#else
dct_value_tokens = vp9_dct_value_tokens_ptr;
dct_value_cost = vp9_dct_value_cost_ptr;
#endif
for (i = 0; i < eob; i++)
token_cache[scan[i]] =
vp9_pt_energy_class[dct_value_tokens[qcoeff[scan[i]]].token];
vp9_pt_energy_class[vp9_get_token(qcoeff[scan[i]])];
for (i = eob; i-- > 0;) {
int base_bits, d2, dx;
@ -198,7 +193,7 @@ static int optimize_b(MACROBLOCK *mb, int plane, int block,
/* Evaluate the first possibility for this state. */
rate0 = tokens[next][0].rate;
rate1 = tokens[next][1].rate;
t0 = (dct_value_tokens + x)->token;
t0 = vp9_get_token(x);
/* Consider both possible successor states. */
if (next < default_eob) {
band = band_translate[i + 1];
@ -250,7 +245,7 @@ static int optimize_b(MACROBLOCK *mb, int plane, int block,
t0 = tokens[next][0].token == EOB_TOKEN ? EOB_TOKEN : ZERO_TOKEN;
t1 = tokens[next][1].token == EOB_TOKEN ? EOB_TOKEN : ZERO_TOKEN;
} else {
t0 = t1 = (dct_value_tokens + x)->token;
t0 = t1 = vp9_get_token(x);
}
if (next < default_eob) {
band = band_translate[i + 1];

View File

@ -373,7 +373,7 @@ static INLINE int cost_coeffs(MACROBLOCK *x,
// dc token
int v = qcoeff[0];
int prev_t = vp9_dct_value_tokens_ptr[v].token;
int prev_t = vp9_get_token(v);
cost = (*token_costs)[0][pt][prev_t] + vp9_dct_value_cost_ptr[v];
token_cache[0] = vp9_pt_energy_class[prev_t];
++token_costs;
@ -384,7 +384,7 @@ static INLINE int cost_coeffs(MACROBLOCK *x,
int t;
v = qcoeff[rc];
t = vp9_dct_value_tokens_ptr[v].token;
t = vp9_get_token(v);
if (use_fast_coef_costing) {
cost += (*token_costs)[!prev_t][!prev_t][t] + vp9_dct_value_cost_ptr[v];
} else {

View File

@ -23,23 +23,46 @@
#include "vp9/encoder/vp9_encoder.h"
#include "vp9/encoder/vp9_tokenize.h"
static TOKENVALUE dct_value_tokens[DCT_MAX_VALUE * 2];
const TOKENVALUE *vp9_dct_value_tokens_ptr;
static int16_t dct_value_cost[DCT_MAX_VALUE * 2];
const int16_t *vp9_dct_value_cost_ptr;
const int16_t *vp9_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE;
#if CONFIG_VP9_HIGHBITDEPTH
static TOKENVALUE dct_value_tokens_high10[DCT_MAX_VALUE_HIGH10 * 2];
const TOKENVALUE *vp9_dct_value_tokens_high10_ptr;
static int16_t dct_value_cost_high10[DCT_MAX_VALUE_HIGH10 * 2];
const int16_t *vp9_dct_value_cost_high10_ptr;
const int16_t *vp9_dct_value_cost_high10_ptr =
dct_value_cost_high10 + DCT_MAX_VALUE_HIGH10;
static TOKENVALUE dct_value_tokens_high12[DCT_MAX_VALUE_HIGH12 * 2];
const TOKENVALUE *vp9_dct_value_tokens_high12_ptr;
static int16_t dct_value_cost_high12[DCT_MAX_VALUE_HIGH12 * 2];
const int16_t *vp9_dct_value_cost_high12_ptr;
const int16_t *vp9_dct_value_cost_high12_ptr =
dct_value_cost_high12 + DCT_MAX_VALUE_HIGH12;
#endif
static const TOKENVALUE dct_cat_lt_10_value_tokens[] = {
{9, 63}, {9, 61}, {9, 59}, {9, 57}, {9, 55}, {9, 53}, {9, 51}, {9, 49},
{9, 47}, {9, 45}, {9, 43}, {9, 41}, {9, 39}, {9, 37}, {9, 35}, {9, 33},
{9, 31}, {9, 29}, {9, 27}, {9, 25}, {9, 23}, {9, 21}, {9, 19}, {9, 17},
{9, 15}, {9, 13}, {9, 11}, {9, 9}, {9, 7}, {9, 5}, {9, 3}, {9, 1},
{8, 31}, {8, 29}, {8, 27}, {8, 25}, {8, 23}, {8, 21},
{8, 19}, {8, 17}, {8, 15}, {8, 13}, {8, 11}, {8, 9},
{8, 7}, {8, 5}, {8, 3}, {8, 1},
{7, 15}, {7, 13}, {7, 11}, {7, 9}, {7, 7}, {7, 5}, {7, 3}, {7, 1},
{6, 7}, {6, 5}, {6, 3}, {6, 1}, {5, 3}, {5, 1},
{4, 1}, {3, 1}, {2, 1}, {1, 1}, {0, 0},
{1, 0}, {2, 0}, {3, 0}, {4, 0},
{5, 0}, {5, 2}, {6, 0}, {6, 2}, {6, 4}, {6, 6},
{7, 0}, {7, 2}, {7, 4}, {7, 6}, {7, 8}, {7, 10}, {7, 12}, {7, 14},
{8, 0}, {8, 2}, {8, 4}, {8, 6}, {8, 8}, {8, 10}, {8, 12},
{8, 14}, {8, 16}, {8, 18}, {8, 20}, {8, 22}, {8, 24},
{8, 26}, {8, 28}, {8, 30}, {9, 0}, {9, 2},
{9, 4}, {9, 6}, {9, 8}, {9, 10}, {9, 12}, {9, 14}, {9, 16},
{9, 18}, {9, 20}, {9, 22}, {9, 24}, {9, 26}, {9, 28},
{9, 30}, {9, 32}, {9, 34}, {9, 36}, {9, 38}, {9, 40},
{9, 42}, {9, 44}, {9, 46}, {9, 48}, {9, 50}, {9, 52},
{9, 54}, {9, 56}, {9, 58}, {9, 60}, {9, 62}
};
const TOKENVALUE *vp9_dct_cat_lt_10_value_tokens = dct_cat_lt_10_value_tokens +
(sizeof(dct_cat_lt_10_value_tokens) / sizeof(*dct_cat_lt_10_value_tokens))
/ 2;
// Array indices are identical to previously-existing CONTEXT_NODE indices
const vp9_tree_index vp9_coef_tree[TREE_SIZE(ENTROPY_TOKENS)] = {
-EOB_TOKEN, 2, // 0 = EOB
@ -158,39 +181,21 @@ void vp9_coef_tree_initialize() {
vp9_tokens_from_tree(vp9_coef_encodings, vp9_coef_tree);
}
static void tokenize_init_one(TOKENVALUE *t, const vp9_extra_bit *const e,
static void tokenize_init_one(const vp9_extra_bit *const e,
int16_t *value_cost, int max_value) {
int i = -max_value;
int sign = 1;
TOKENVALUE t;
do {
if (!i)
sign = 0;
{
const int a = sign ? -i : i;
int eb = sign;
if (a > 4) {
int j = 4;
while (++j < 11 && e[j].base_val <= a) {}
t[i].token = --j;
eb |= (a - e[j].base_val) << 1;
} else {
t[i].token = a;
}
t[i].extra = eb;
}
vp9_get_token_extra(i, &t.token, &t.extra);
// initialize the cost for extra bits for all possible coefficient value.
{
int cost = 0;
const vp9_extra_bit *p = &e[t[i].token];
const vp9_extra_bit *p = &e[t.token];
if (p->base_val) {
const int extra = t[i].extra;
const int extra = t.extra;
const int length = p->len;
if (length)
@ -204,26 +209,14 @@ static void tokenize_init_one(TOKENVALUE *t, const vp9_extra_bit *const e,
}
void vp9_tokenize_initialize() {
vp9_dct_value_tokens_ptr = dct_value_tokens + DCT_MAX_VALUE;
vp9_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE;
tokenize_init_one(dct_value_tokens + DCT_MAX_VALUE, vp9_extra_bits,
tokenize_init_one(vp9_extra_bits,
dct_value_cost + DCT_MAX_VALUE, DCT_MAX_VALUE);
#if CONFIG_VP9_HIGHBITDEPTH
vp9_dct_value_tokens_high10_ptr = dct_value_tokens_high10 +
DCT_MAX_VALUE_HIGH10;
vp9_dct_value_cost_high10_ptr = dct_value_cost_high10 + DCT_MAX_VALUE_HIGH10;
tokenize_init_one(dct_value_tokens_high10 + DCT_MAX_VALUE_HIGH10,
vp9_extra_bits_high10,
tokenize_init_one(vp9_extra_bits_high10,
dct_value_cost_high10 + DCT_MAX_VALUE_HIGH10,
DCT_MAX_VALUE_HIGH10);
vp9_dct_value_tokens_high12_ptr = dct_value_tokens_high12 +
DCT_MAX_VALUE_HIGH12;
vp9_dct_value_cost_high12_ptr = dct_value_cost_high12 + DCT_MAX_VALUE_HIGH12;
tokenize_init_one(dct_value_tokens_high12 + DCT_MAX_VALUE_HIGH12,
vp9_extra_bits_high12,
tokenize_init_one(vp9_extra_bits_high12,
dct_value_cost_high12 + DCT_MAX_VALUE_HIGH12,
DCT_MAX_VALUE_HIGH12);
#endif
@ -309,8 +302,8 @@ static void tokenize_b(int plane, int block, BLOCK_SIZE plane_bsize,
td->counts->eob_branch[tx_size][type][ref];
const uint8_t *const band = get_band_translate(tx_size);
const int seg_eob = get_tx_eob(&cpi->common.seg, segment_id, tx_size);
const TOKENVALUE *dct_value_tokens;
int16_t token;
EXTRABIT extra;
int aoff, loff;
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &aoff, &loff);
@ -320,17 +313,6 @@ static void tokenize_b(int plane, int block, BLOCK_SIZE plane_bsize,
scan = so->scan;
nb = so->neighbors;
c = 0;
#if CONFIG_VP9_HIGHBITDEPTH
if (cpi->common.profile >= PROFILE_2) {
dct_value_tokens = (cpi->common.bit_depth == VPX_BITS_10 ?
vp9_dct_value_tokens_high10_ptr :
vp9_dct_value_tokens_high12_ptr);
} else {
dct_value_tokens = vp9_dct_value_tokens_ptr;
}
#else
dct_value_tokens = vp9_dct_value_tokens_ptr;
#endif
while (c < eob) {
int v = 0;
@ -349,14 +331,13 @@ static void tokenize_b(int plane, int block, BLOCK_SIZE plane_bsize,
v = qcoeff[scan[c]];
}
add_token(&t, coef_probs[band[c]][pt],
dct_value_tokens[v].extra,
(uint8_t)dct_value_tokens[v].token,
(uint8_t)skip_eob,
counts[band[c]][pt]);
vp9_get_token_extra(v, &token, &extra);
add_token(&t, coef_probs[band[c]][pt], extra, (uint8_t)token,
(uint8_t)skip_eob, counts[band[c]][pt]);
eob_branch[band[c]][pt] += !skip_eob;
token_cache[scan[c]] = vp9_pt_energy_class[dct_value_tokens[v].token];
token_cache[scan[c]] = vp9_pt_energy_class[token];
++c;
pt = get_coef_context(nb, token_cache, c);
}

View File

@ -24,22 +24,21 @@ void vp9_tokenize_initialize();
#define EOSB_TOKEN 127 // Not signalled, encoder only
#if CONFIG_VP9_HIGHBITDEPTH
typedef int32_t EXTRABIT;
#else
typedef int16_t EXTRABIT;
#endif
typedef struct {
int16_t token;
#if CONFIG_VP9_HIGHBITDEPTH
int32_t extra;
#else
int16_t extra;
#endif
EXTRABIT extra;
} TOKENVALUE;
typedef struct {
const vp9_prob *context_tree;
#if CONFIG_VP9_HIGHBITDEPTH
int32_t extra;
#else
int16_t extra;
#endif
EXTRABIT extra;
uint8_t token;
uint8_t skip_eob_node;
} TOKENEXTRA;
@ -63,6 +62,7 @@ extern const int16_t *vp9_dct_value_cost_ptr;
* fields are not.
*/
extern const TOKENVALUE *vp9_dct_value_tokens_ptr;
extern const TOKENVALUE *vp9_dct_cat_lt_10_value_tokens;
#if CONFIG_VP9_HIGHBITDEPTH
extern const int16_t *vp9_dct_value_cost_high10_ptr;
extern const TOKENVALUE *vp9_dct_value_tokens_high10_ptr;
@ -70,6 +70,25 @@ extern const int16_t *vp9_dct_value_cost_high12_ptr;
extern const TOKENVALUE *vp9_dct_value_tokens_high12_ptr;
#endif // CONFIG_VP9_HIGHBITDEPTH
static INLINE void vp9_get_token_extra(int v, int16_t *token, EXTRABIT *extra) {
if (v >= CAT6_MIN_VAL || v <= -CAT6_MIN_VAL) {
*token = CATEGORY6_TOKEN;
if (v >= CAT6_MIN_VAL)
*extra = 2 * v - 2 * CAT6_MIN_VAL;
else
*extra = -2 * v - 2 * CAT6_MIN_VAL + 1;
return;
}
*token = vp9_dct_cat_lt_10_value_tokens[v].token;
*extra = vp9_dct_cat_lt_10_value_tokens[v].extra;
}
static INLINE int16_t vp9_get_token(int v) {
if (v >= CAT6_MIN_VAL || v <= -CAT6_MIN_VAL)
return 10;
return vp9_dct_cat_lt_10_value_tokens[v].token;
}
#ifdef __cplusplus
} // extern "C"
#endif