summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
authorJim Bankoski <jimbankoski@google.com>2014-12-22 13:36:38 -0800
committerGerrit Code Review <gerrit@gerrit.golo.chromium.org>2014-12-22 13:36:38 -0800
commitfba0ead5430fd09b65fa2f10cd07b1cb07a0c087 (patch)
tree21607d05c78f473e705c4e2b8d266478180073b4 /vp9/encoder
parent6121dd89ff2fbb32dd87f940c0ce89a3864bb0f0 (diff)
parent4b8c6d96ec0ec2cc7c78e8e663ab7329704c92b9 (diff)
downloadlibvpx-fba0ead5430fd09b65fa2f10cd07b1cb07a0c087.tar
libvpx-fba0ead5430fd09b65fa2f10cd07b1cb07a0c087.tar.gz
libvpx-fba0ead5430fd09b65fa2f10cd07b1cb07a0c087.tar.bz2
libvpx-fba0ead5430fd09b65fa2f10cd07b1cb07a0c087.zip
Merge "Tokenization without huge tables."
Diffstat (limited to 'vp9/encoder')
-rw-r--r--vp9/encoder/vp9_encodemb.c11
-rw-r--r--vp9/encoder/vp9_rdopt.c4
-rw-r--r--vp9/encoder/vp9_tokenize.c113
-rw-r--r--vp9/encoder/vp9_tokenize.h41
4 files changed, 82 insertions, 87 deletions
diff --git a/vp9/encoder/vp9_encodemb.c b/vp9/encoder/vp9_encodemb.c
index 9b2165be6..47c485c8c 100644
--- a/vp9/encoder/vp9_encodemb.c
+++ b/vp9/encoder/vp9_encodemb.c
@@ -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];
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index b2d4d380a..ded082f86 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -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 {
diff --git a/vp9/encoder/vp9_tokenize.c b/vp9/encoder/vp9_tokenize.c
index d54520f9f..06bcfc317 100644
--- a/vp9/encoder/vp9_tokenize.c
+++ b/vp9/encoder/vp9_tokenize.c
@@ -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);
}
diff --git a/vp9/encoder/vp9_tokenize.h b/vp9/encoder/vp9_tokenize.h
index 00afb723e..845e139f2 100644
--- a/vp9/encoder/vp9_tokenize.h
+++ b/vp9/encoder/vp9_tokenize.h
@@ -24,24 +24,23 @@ void vp9_tokenize_initialize();
#define EOSB_TOKEN 127 // Not signalled, encoder only
-typedef struct {
- int16_t token;
#if CONFIG_VP9_HIGHBITDEPTH
- int32_t extra;
+ typedef int32_t EXTRABIT;
#else
- int16_t extra;
+ typedef int16_t EXTRABIT;
#endif
+
+
+typedef struct {
+ int16_t token;
+ EXTRABIT extra;
} TOKENVALUE;
typedef struct {
const vp9_prob *context_tree;
-#if CONFIG_VP9_HIGHBITDEPTH
- int32_t extra;
-#else
- int16_t extra;
-#endif
- uint8_t token;
- uint8_t skip_eob_node;
+ EXTRABIT extra;
+ uint8_t token;
+ uint8_t skip_eob_node;
} TOKENEXTRA;
extern const vp9_tree_index vp9_coef_tree[];
@@ -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