Commit 6ca36460 authored by Alex Converse's avatar Alex Converse

Store ANS token CDFs in the FRAME_CONTEXT rather than in a global table.

This will facilitate bringing the zero node into the token set while
allowing its probability to vary independently.

Change-Id: I57b44c0fce44debb8e612021e44713b229d1b3cf
parent ab759be8
......@@ -675,15 +675,6 @@ const vpx_prob vp10_pareto8_token_probs[COEFF_PROB_MODELS]
{247, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{247, 1, 1, 1, 1, 1, 1, 1, 1, 1},
};
void vp10_build_pareto8_cdf_tab(
const vpx_prob token_probs[COEFF_PROB_MODELS][ENTROPY_TOKENS - 2],
rans_dec_lut cdf_tab[COEFF_PROB_MODELS]) {
int p;
for (p = 0; p < COEFF_PROB_MODELS; ++p) {
rans_build_cdf_from_pdf(token_probs[p], cdf_tab[p]);
}
}
#endif // CONFIG_ANS
#if CONFIG_ENTROPY
......@@ -2807,6 +2798,24 @@ void vp10_model_to_full_probs(const vpx_prob *model, vpx_prob *full) {
extend_to_full_distribution(&full[UNCONSTRAINED_NODES], model[PIVOT_NODE]);
}
#if CONFIG_ANS
void vp10_coef_pareto_cdfs(FRAME_CONTEXT *fc) {
TX_SIZE t;
int i, j, k, l;
for (t = TX_4X4; t <= TX_32X32; ++t)
for (i = 0; i < PLANE_TYPES; ++i)
for (j = 0; j < REF_TYPES; ++j)
for (k = 0; k < COEF_BANDS; ++k)
for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) {
const vpx_prob *const tree_probs = fc->coef_probs[t][i][j][k][l];
vpx_prob pivot = tree_probs[PIVOT_NODE];
assert(pivot != 0);
rans_build_cdf_from_pdf(vp10_pareto8_token_probs[pivot - 1],
fc->coef_cdfs[t][i][j][k][l]);
}
}
#endif // CONFIG_ANS
void vp10_default_coef_probs(VP10_COMMON *cm) {
#if CONFIG_ENTROPY
const int index =
......@@ -2819,6 +2828,9 @@ void vp10_default_coef_probs(VP10_COMMON *cm) {
vp10_copy(cm->fc->coef_probs[TX_16X16], default_coef_probs_16x16);
vp10_copy(cm->fc->coef_probs[TX_32X32], default_coef_probs_32x32);
#endif // CONFIG_ENTROPY
#if CONFIG_ANS
vp10_coef_pareto_cdfs(cm->fc);
#endif // CONFIG_ANS
}
#define COEF_COUNT_SAT 24
......@@ -2888,6 +2900,9 @@ void vp10_adapt_coef_probs(VP10_COMMON *cm) {
#endif // CONFIG_ENTROPY
for (t = TX_4X4; t <= TX_32X32; t++)
adapt_coef_probs(cm, t, count_sat, update_factor);
#if CONFIG_ANS
vp10_coef_pareto_cdfs(cm->fc);
#endif
}
#if CONFIG_ENTROPY
......
......@@ -179,9 +179,7 @@ extern const vpx_prob vp10_pareto8_full[COEFF_PROB_MODELS][MODEL_NODES];
extern const vpx_prob
vp10_pareto8_token_probs[COEFF_PROB_MODELS][ENTROPY_TOKENS - 2];
void vp10_build_pareto8_cdf_tab(
const vpx_prob token_probs[COEFF_PROB_MODELS][ENTROPY_TOKENS - 2],
rans_dec_lut cdf_tab[COEFF_PROB_MODELS]);
typedef rans_dec_lut coeff_cdf_model[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS];
#endif // CONFIG_ANS
typedef vpx_prob vp10_coeff_probs_model[REF_TYPES][COEF_BANDS]
......@@ -229,6 +227,10 @@ static INLINE int get_entropy_context(TX_SIZE tx_size, const ENTROPY_CONTEXT *a,
return combine_entropy_contexts(above_ec, left_ec);
}
#if CONFIG_ANS
struct frame_contexts;
void vp10_coef_pareto_cdfs(struct frame_contexts *fc);
#endif // CONFIG_ANS
#ifdef __cplusplus
} // extern "C"
#endif
......
......@@ -53,6 +53,9 @@ typedef struct frame_contexts {
vpx_prob partition_prob[PARTITION_CONTEXTS][PARTITION_TYPES - 1];
#endif
vp10_coeff_probs_model coef_probs[TX_SIZES][PLANE_TYPES];
#if CONFIG_ANS
coeff_cdf_model coef_cdfs[TX_SIZES][PLANE_TYPES];
#endif
vpx_prob switchable_interp_prob[SWITCHABLE_FILTER_CONTEXTS]
[SWITCHABLE_FILTERS - 1];
......
......@@ -340,9 +340,6 @@ typedef struct VP10Common {
// - this is intentionally not placed in FRAME_CONTEXT since it's reset upon
// each keyframe and not used afterwards
vpx_prob kf_y_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1];
#if CONFIG_ANS
rans_dec_lut token_tab[COEFF_PROB_MODELS];
#endif // CONFIG_ANS
BLOCK_SIZE sb_size; // Size of the superblock used for this frame
int mib_size; // Size of the superblock in units of MI blocks
......
......@@ -259,7 +259,6 @@ static void inverse_transform_block(MACROBLOCKD* xd, int plane,
static void predict_and_reconstruct_intra_block(MACROBLOCKD *const xd,
#if CONFIG_ANS
const rans_dec_lut *const token_tab,
struct AnsDecoder *const r,
#else
vp10_reader *r,
......@@ -287,9 +286,6 @@ static void predict_and_reconstruct_intra_block(MACROBLOCKD *const xd,
TX_TYPE tx_type = get_tx_type(plane_type, xd, block_idx, tx_size);
const scan_order *sc = get_scan(tx_size, tx_type, 0);
const int eob = vp10_decode_block_tokens(xd,
#if CONFIG_ANS
token_tab,
#endif // CONFIG_ANS
plane, sc, col, row, tx_size,
tx_type, r, mbmi->segment_id);
inverse_transform_block(xd, plane, tx_type, tx_size,
......@@ -357,7 +353,6 @@ static void decode_reconstruct_tx(MACROBLOCKD *const xd, vp10_reader *r,
#if !CONFIG_VAR_TX || CONFIG_SUPERTX
static int reconstruct_inter_block(MACROBLOCKD *const xd,
#if CONFIG_ANS
const rans_dec_lut *const token_tab,
struct AnsDecoder *const r,
#else
vp10_reader *r,
......@@ -370,9 +365,6 @@ static int reconstruct_inter_block(MACROBLOCKD *const xd,
TX_TYPE tx_type = get_tx_type(plane_type, xd, block_idx, tx_size);
const scan_order *sc = get_scan(tx_size, tx_type, 1);
const int eob = vp10_decode_block_tokens(xd,
#if CONFIG_ANS
token_tab,
#endif
plane, sc, col, row,
tx_size, tx_type, r,
mbmi->segment_id);
......@@ -1878,9 +1870,6 @@ static void decode_block(VP10Decoder *const pbi, MACROBLOCKD *const xd,
for (row = 0; row < max_blocks_high; row += step)
for (col = 0; col < max_blocks_wide; col += step)
predict_and_reconstruct_intra_block(xd,
#if CONFIG_ANS
cm->token_tab,
#endif
r,
mbmi, plane,
row, col, tx_size);
......@@ -1981,9 +1970,6 @@ static void decode_block(VP10Decoder *const pbi, MACROBLOCKD *const xd,
for (row = 0; row < max_blocks_high; row += step)
for (col = 0; col < max_blocks_wide; col += step)
eobtotal += reconstruct_inter_block(xd,
#if CONFIG_ANS
cm->token_tab,
#endif
r,
mbmi, plane, row, col,
tx_size);
......@@ -2381,9 +2367,6 @@ static void decode_partition(VP10Decoder *const pbi, MACROBLOCKD *const xd,
for (row = 0; row < max_blocks_high; row += step)
for (col = 0; col < max_blocks_wide; col += step)
eobtotal += reconstruct_inter_block(xd,
#if CONFIG_ANS
cm->token_tab,
#endif
r,
mbmi, i, row, col,
tx_size);
......@@ -2495,6 +2478,9 @@ static void read_coef_probs(FRAME_CONTEXT *fc, TX_MODE tx_mode,
TX_SIZE tx_size;
for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
read_coef_probs_common(fc->coef_probs[tx_size], r);
#if CONFIG_ANS
vp10_coef_pareto_cdfs(fc);
#endif // CONFIG_ANS
}
static void setup_segmentation(VP10_COMMON *const cm,
......
......@@ -122,9 +122,6 @@ VP10Decoder *vp10_decoder_create(BufferPool *const pool) {
#if CONFIG_LOOP_RESTORATION
vp10_loop_restoration_precal();
#endif // CONFIG_LOOP_RESTORATION
#if CONFIG_ANS
vp10_build_pareto8_cdf_tab(vp10_pareto8_token_probs, cm->token_tab);
#endif // CONFIG_ANS
cm->error.setjmp = 0;
......
......@@ -220,7 +220,6 @@ static INLINE int read_coeff(const vpx_prob *const probs, int n,
}
static int decode_coefs_ans(const MACROBLOCKD *const xd,
const rans_dec_lut *const token_tab,
PLANE_TYPE type,
tran_low_t *dqcoeff, TX_SIZE tx_size,
TX_TYPE tx_type,
......@@ -234,7 +233,10 @@ static int decode_coefs_ans(const MACROBLOCKD *const xd,
int band, c = 0;
const vpx_prob (*coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] =
fc->coef_probs[tx_size][type][ref];
const rans_dec_lut(*coef_cdfs)[COEFF_CONTEXTS] =
fc->coef_cdfs[tx_size][type][ref];
const vpx_prob *prob;
const rans_dec_lut *cdf;
unsigned int (*coef_counts)[COEFF_CONTEXTS][UNCONSTRAINED_NODES + 1];
unsigned int (*eob_branch_count)[COEFF_CONTEXTS];
uint8_t token_cache[MAX_TX_SQUARE];
......@@ -312,8 +314,9 @@ static int decode_coefs_ans(const MACROBLOCKD *const xd,
band = *band_translate++;
prob = coef_probs[band][ctx];
}
cdf = &coef_cdfs[band][ctx];
token = ONE_TOKEN + rans_read(ans, token_tab[prob[PIVOT_NODE] - 1]);
token = ONE_TOKEN + rans_read(ans, *cdf);
INCREMENT_COUNT(ONE_TOKEN + (token > ONE_TOKEN));
switch (token) {
case ONE_TOKEN:
......@@ -458,9 +461,6 @@ void vp10_decode_palette_tokens(MACROBLOCKD *const xd, int plane,
}
int vp10_decode_block_tokens(MACROBLOCKD *const xd,
#if CONFIG_ANS
const rans_dec_lut *const token_tab,
#endif // CONFIG_ANS
int plane, const scan_order *sc,
int x, int y,
TX_SIZE tx_size,
......@@ -480,7 +480,7 @@ int vp10_decode_block_tokens(MACROBLOCKD *const xd,
pd->dqcoeff, tx_size, tx_type,
dequant, ctx, sc->scan, sc->neighbors, r);
#else
const int eob = decode_coefs_ans(xd, token_tab, pd->plane_type,
const int eob = decode_coefs_ans(xd, pd->plane_type,
pd->dqcoeff, tx_size, tx_type,
dequant, ctx, sc->scan, sc->neighbors, r);
#endif // !CONFIG_ANS
......
......@@ -23,9 +23,6 @@ extern "C" {
void vp10_decode_palette_tokens(MACROBLOCKD *const xd, int plane,
vp10_reader *r);
int vp10_decode_block_tokens(MACROBLOCKD *const xd,
#if CONFIG_ANS
const rans_dec_lut *const token_tab,
#endif // CONFIG_ANS
int plane, const scan_order *sc,
int x, int y,
TX_SIZE tx_size,
......
......@@ -676,7 +676,6 @@ static void pack_mb_tokens(vp10_writer *w,
// This function serializes the tokens in forward order using a buffered ans
// coder.
static void pack_mb_tokens_ans(struct BufAnsCoder *ans,
const rans_dec_lut token_tab[COEFF_PROB_MODELS],
const TOKENEXTRA **tp,
const TOKENEXTRA *const stop,
vpx_bit_depth_t bit_depth,
......@@ -711,8 +710,7 @@ static void pack_mb_tokens_ans(struct BufAnsCoder *ans,
if (t != ZERO_TOKEN) {
struct rans_sym s;
const rans_dec_lut *token_cdf =
&token_tab[p->context_tree[PIVOT_NODE] - 1];
const rans_dec_lut *token_cdf = p->token_cdf;
s.cum_prob = (*token_cdf)[t - ONE_TOKEN];
s.prob = (*token_cdf)[t - ONE_TOKEN + 1] - s.cum_prob;
buf_rans_write(ans, &s);
......@@ -1587,8 +1585,7 @@ static void write_modes_b(VP10_COMP *cpi, const TileInfo *const tile,
for (row = 0; row < num_4x4_h; row += bw)
for (col = 0; col < num_4x4_w; col += bw)
#if CONFIG_ANS
pack_mb_tokens_ans(w, cm->token_tab, tok, tok_end, cm->bit_depth,
tx);
pack_mb_tokens_ans(w, tok, tok_end, cm->bit_depth, tx);
#else
pack_mb_tokens(w, tok, tok_end, cm->bit_depth, tx);
#endif // CONFIG_ANS
......@@ -1597,7 +1594,7 @@ static void write_modes_b(VP10_COMP *cpi, const TileInfo *const tile,
TX_SIZE tx = plane ? get_uv_tx_size(&m->mbmi, &xd->plane[plane])
: m->mbmi.tx_size;
#if CONFIG_ANS
pack_mb_tokens_ans(w, cm->token_tab, tok, tok_end, cm->bit_depth, tx);
pack_mb_tokens_ans(w, tok, tok_end, cm->bit_depth, tx);
#else
pack_mb_tokens(w, tok, tok_end, cm->bit_depth, tx);
#endif // CONFIG_ANS
......@@ -1805,8 +1802,7 @@ static void write_modes_sb(VP10_COMP *const cpi,
for (row = 0; row < num_4x4_h; row += bw)
for (col = 0; col < num_4x4_w; col += bw)
#if CONFIG_ANS
pack_mb_tokens_ans(w, cm->token_tab, tok, tok_end, cm->bit_depth,
tx);
pack_mb_tokens_ans(w, tok, tok_end, cm->bit_depth, tx);
#else
pack_mb_tokens(w, tok, tok_end, cm->bit_depth, tx);
#endif
......@@ -2244,6 +2240,9 @@ static void update_coef_probs(VP10_COMP *cpi, vp10_writer* w) {
const TX_MODE tx_mode = cpi->common.tx_mode;
const TX_SIZE max_tx_size = tx_mode_to_biggest_tx_size[tx_mode];
TX_SIZE tx_size;
#if CONFIG_ANS
int update = 0;
#endif // CONFIG_ANS
#if CONFIG_ENTROPY
VP10_COMMON *cm = &cpi->common;
SUBFRAME_STATS *subframe_stats = &cpi->subframe_stats;
......@@ -2296,12 +2295,18 @@ static void update_coef_probs(VP10_COMP *cpi, vp10_writer* w) {
update_coef_probs_subframe(w, cpi, tx_size, branch_ct,
frame_coef_probs);
#if CONFIG_ANS
update = 1;
#endif // CONFIG_ANS
} else {
#endif // CONFIG_ENTROPY
build_tree_distribution(cpi, tx_size, frame_branch_ct,
frame_coef_probs);
update_coef_probs_common(w, cpi, tx_size, frame_branch_ct,
frame_coef_probs);
#if CONFIG_ANS
update = 1;
#endif // CONFIG_ANS
#if CONFIG_ENTROPY
}
#endif // CONFIG_ENTROPY
......@@ -2326,6 +2331,9 @@ static void update_coef_probs(VP10_COMP *cpi, vp10_writer* w) {
vp10_copy(cm->counts.eob_branch, eob_counts_copy);
}
#endif // CONFIG_ENTROPY
#if CONFIG_ANS
if (update) vp10_coef_pareto_cdfs(cpi->common.fc);
#endif // CONFIG_ANS
}
#if CONFIG_LOOP_RESTORATION
......
......@@ -2485,9 +2485,6 @@ VP10_COMP *vp10_create_compressor(VP10EncoderConfig *oxcf,
#if CONFIG_LOOP_RESTORATION
vp10_loop_restoration_precal();
#endif // CONFIG_LOOP_RESTORATION
#if CONFIG_ANS
vp10_build_pareto8_cdf_tab(vp10_pareto8_token_probs, cm->token_tab);
#endif // CONFIG_ANS
cm->error.setjmp = 0;
......
......@@ -363,12 +363,17 @@ static void set_entropy_context_b(int plane, int block,
}
static INLINE void add_token(TOKENEXTRA **t, const vpx_prob *context_tree,
#if CONFIG_ANS
const rans_dec_lut *token_cdf,
#endif // CONFIG_ANS
int32_t extra, uint8_t token,
uint8_t skip_eob_node,
unsigned int *counts) {
uint8_t skip_eob_node, unsigned int *counts) {
(*t)->token = token;
(*t)->extra = extra;
(*t)->context_tree = context_tree;
#if CONFIG_ANS
(*t)->token_cdf = token_cdf;
#endif // CONFIG_ANS
(*t)->skip_eob_node = skip_eob_node;
(*t)++;
++counts[token];
......@@ -463,6 +468,10 @@ static void tokenize_b(int plane, int block, int blk_row, int blk_col,
vpx_prob (*const coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] =
cpi->common.fc->coef_probs[tx_size][type][ref];
#endif // CONFIG_ENTROPY
#if CONFIG_ANS
rans_dec_lut(*const coef_cdfs)[COEFF_CONTEXTS] =
cpi->common.fc->coef_cdfs[tx_size][type][ref];
#endif // CONFIG_ANS
unsigned int (*const eob_branch)[COEFF_CONTEXTS] =
td->counts->eob_branch[tx_size][type][ref];
const uint8_t *const band = get_band_translate(tx_size);
......@@ -495,8 +504,11 @@ static void tokenize_b(int plane, int block, int blk_row, int blk_col,
vp10_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]);
add_token(&t, coef_probs[band[c]][pt],
#if CONFIG_ANS
&coef_cdfs[band[c]][pt],
#endif // CONFIG_ANS
extra, (uint8_t)token, (uint8_t)skip_eob, counts[band[c]][pt]);
eob_branch[band[c]][pt] += !skip_eob;
token_cache[scan[c]] = vp10_pt_energy_class[token];
......
......@@ -36,6 +36,9 @@ typedef struct {
typedef struct {
const vpx_prob *context_tree;
#if CONFIG_ANS
const rans_dec_lut *token_cdf;
#endif // CONFIG_ANS
EXTRABIT extra;
uint8_t token;
uint8_t skip_eob_node;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment