Commit 0ccefe21 authored by Thomas Davies's avatar Thomas Davies

EC_MULTISYMBOL: merge ZERO_TOKEN into coding scheme.

Zero, one, and two or more coded as one symbol (head).
Remaining tokens coded as a tail symbol.

The pareto CDF distribution is adjusted to cover tokens from
two onwards.

Change-Id: I98b33fab6b9f52690f6ad618ac55e725a97be056
parent 23a61117
This diff is collapsed.
......@@ -183,6 +183,7 @@ static INLINE const uint8_t *get_band_translate(TX_SIZE tx_size) {
#define PIVOT_NODE 2 // which node is pivot
#define MODEL_NODES (ENTROPY_NODES - UNCONSTRAINED_NODES)
#define TAIL_NODES (MODEL_NODES + 1)
extern const aom_tree_index av1_coef_con_tree[TREE_SIZE(ENTROPY_TOKENS)];
extern const aom_prob av1_pareto8_full[COEFF_PROB_MODELS][MODEL_NODES];
......@@ -200,6 +201,8 @@ typedef aom_cdf_prob coeff_cdf_model[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS]
[ENTROPY_TOKENS];
extern const aom_cdf_prob av1_pareto8_token_probs[COEFF_PROB_MODELS]
[ENTROPY_TOKENS - 2];
extern const aom_cdf_prob av1_pareto8_tail_cdfs[COEFF_PROB_MODELS]
[ENTROPY_TOKENS - 3];
struct frame_contexts;
void av1_coef_pareto_cdfs(struct frame_contexts *fc);
#endif // CONFIG_EC_MULTISYMBOL
......
......@@ -85,7 +85,8 @@ typedef struct frame_contexts {
#endif
av1_coeff_probs_model coef_probs[TX_SIZES][PLANE_TYPES];
#if CONFIG_EC_MULTISYMBOL
coeff_cdf_model coef_cdfs[TX_SIZES][PLANE_TYPES];
coeff_cdf_model coef_tail_cdfs[TX_SIZES][PLANE_TYPES];
coeff_cdf_model coef_head_cdfs[TX_SIZES][PLANE_TYPES];
#endif // CONFIG_EC_MULTISYMBOL
aom_prob switchable_interp_prob[SWITCHABLE_FILTER_CONTEXTS]
[SWITCHABLE_FILTERS - 1];
......
......@@ -2395,7 +2395,7 @@ static void read_coef_probs_common(av1_coeff_probs_model *coef_probs,
aom_reader *r) {
int i, j, k, l, m;
#if CONFIG_EC_ADAPT
const int node_limit = UNCONSTRAINED_NODES - 1;
const int node_limit = UNCONSTRAINED_NODES - 2;
#else
const int node_limit = UNCONSTRAINED_NODES;
#endif
......
......@@ -81,14 +81,20 @@ static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
fc->coef_probs[tx_size_ctx][type][ref];
const aom_prob *prob;
#if CONFIG_EC_ADAPT
aom_cdf_prob(*coef_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
xd->tile_ctx->coef_cdfs[tx_size][type][ref];
aom_cdf_prob(*cdf)[ENTROPY_TOKENS];
aom_cdf_prob(*coef_head_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
xd->tile_ctx->coef_head_cdfs[tx_size][type][ref];
aom_cdf_prob(*coef_tail_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
xd->tile_ctx->coef_tail_cdfs[tx_size][type][ref];
#elif CONFIG_EC_MULTISYMBOL
aom_cdf_prob(*coef_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
fc->coef_cdfs[tx_size_ctx][type][ref];
aom_cdf_prob(*cdf)[ENTROPY_TOKENS];
#endif // CONFIG_EC_MULTISYMBOL
aom_cdf_prob(*coef_head_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
fc->coef_head_cdfs[tx_size_ctx][type][ref];
aom_cdf_prob(*coef_tail_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
fc->coef_tail_cdfs[tx_size_ctx][type][ref];
#endif
#if CONFIG_EC_MULTISYMBOL
aom_cdf_prob(*cdf_head)[ENTROPY_TOKENS];
aom_cdf_prob(*cdf_tail)[ENTROPY_TOKENS];
#endif
unsigned int(*coef_counts)[COEFF_CONTEXTS][UNCONSTRAINED_NODES + 1] = NULL;
unsigned int(*eob_branch_count)[COEFF_CONTEXTS];
uint8_t token_cache[MAX_TX_SQUARE];
......@@ -165,7 +171,13 @@ static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
dqv_val = &dq_val[band][0];
#endif // CONFIG_NEW_QUANT
while (!aom_read(r, prob[ZERO_CONTEXT_NODE], ACCT_STR)) {
#if CONFIG_EC_MULTISYMBOL
cdf_head = &coef_head_cdfs[band][ctx];
cdf_tail = &coef_tail_cdfs[band][ctx];
token = aom_read_symbol(r, *cdf_head, 3, ACCT_STR);
if (token > ONE_TOKEN)
token += aom_read_symbol(r, *cdf_tail, CATEGORY6_TOKEN + 1 - 2, ACCT_STR);
while (!token) {
INCREMENT_COUNT(ZERO_TOKEN);
dqv = dq[1];
token_cache[scan[c]] = 0;
......@@ -173,7 +185,12 @@ static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
if (c >= max_eob) return c; // zero tokens at the end (no eob token)
ctx = get_coef_context(nb, token_cache, c);
band = *band_translate++;
prob = coef_probs[band][ctx];
cdf_head = &coef_head_cdfs[band][ctx];
cdf_tail = &coef_tail_cdfs[band][ctx];
token = aom_read_symbol(r, *cdf_head, 3, ACCT_STR);
if (token > ONE_TOKEN)
token +=
aom_read_symbol(r, *cdf_tail, CATEGORY6_TOKEN + 1 - 2, ACCT_STR);
#if CONFIG_NEW_QUANT
dqv_val = &dq_val[band][0];
#endif // CONFIG_NEW_QUANT
......@@ -181,11 +198,8 @@ static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
*max_scan_line = AOMMAX(*max_scan_line, scan[c]);
#if CONFIG_EC_MULTISYMBOL
cdf = &coef_cdfs[band][ctx];
token = ONE_TOKEN +
aom_read_symbol(r, *cdf, CATEGORY6_TOKEN - ONE_TOKEN + 1, ACCT_STR);
INCREMENT_COUNT(ONE_TOKEN + (token > ONE_TOKEN));
switch (token) {
case ONE_TOKEN:
case TWO_TOKEN:
......@@ -228,6 +242,23 @@ static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
} break;
}
#else // CONFIG_EC_MULTISYMBOL
while (!aom_read(r, prob[ZERO_CONTEXT_NODE], ACCT_STR)) {
INCREMENT_COUNT(ZERO_TOKEN);
dqv = dq[1];
token_cache[scan[c]] = 0;
++c;
if (c >= max_eob) return c; // zero tokens at the end (no eob token)
ctx = get_coef_context(nb, token_cache, c);
band = *band_translate++;
prob = coef_probs[band][ctx];
#if CONFIG_NEW_QUANT
dqv_val = &dq_val[band][0];
#endif // CONFIG_NEW_QUANT
}
*max_scan_line = AOMMAX(*max_scan_line, scan[c]);
if (!aom_read(r, prob[ONE_CONTEXT_NODE], ACCT_STR)) {
INCREMENT_COUNT(ONE_TOKEN);
token = ONE_TOKEN;
......
......@@ -797,11 +797,10 @@ static void pack_mb_tokens(aom_writer *w, const TOKENEXTRA **tp,
aom_write_record(w, token != EOB_TOKEN, p->context_tree[0], token_stats);
if (token != EOB_TOKEN) {
aom_write_record(w, token != ZERO_TOKEN, p->context_tree[1], token_stats);
if (token != ZERO_TOKEN) {
aom_write_symbol(w, token - ONE_TOKEN, *p->token_cdf,
CATEGORY6_TOKEN - ONE_TOKEN + 1);
aom_write_symbol(w, AOMMIN(token, TWO_TOKEN), *p->head_cdf, 3);
if (token > ONE_TOKEN) {
aom_write_symbol(w, token - TWO_TOKEN, *p->tail_cdf,
CATEGORY6_TOKEN + 1 - 2);
}
}
#else
......@@ -2740,7 +2739,7 @@ static void update_coef_probs_common(aom_writer *const bc, AV1_COMP *cpi,
av1_coeff_probs_model *old_coef_probs = cpi->common.fc->coef_probs[tx_size];
const aom_prob upd = DIFF_UPDATE_PROB;
#if CONFIG_EC_ADAPT
const int entropy_nodes_update = UNCONSTRAINED_NODES - 1;
const int entropy_nodes_update = UNCONSTRAINED_NODES - 2;
#else
const int entropy_nodes_update = UNCONSTRAINED_NODES;
#endif
......
......@@ -362,7 +362,8 @@ static void set_entropy_context_b(int plane, int block, int blk_row,
static INLINE void add_token(TOKENEXTRA **t, const aom_prob *context_tree,
#if CONFIG_EC_MULTISYMBOL
aom_cdf_prob (*token_cdf)[ENTROPY_TOKENS],
aom_cdf_prob (*tail_cdf)[ENTROPY_TOKENS],
aom_cdf_prob (*head_cdf)[ENTROPY_TOKENS],
#endif // CONFIG_EC_MULTISYMBOL
int32_t extra, uint8_t token,
uint8_t skip_eob_node, unsigned int *counts) {
......@@ -370,7 +371,8 @@ static INLINE void add_token(TOKENEXTRA **t, const aom_prob *context_tree,
(*t)->extra = extra;
(*t)->context_tree = context_tree;
#if CONFIG_EC_MULTISYMBOL
(*t)->token_cdf = token_cdf;
(*t)->tail_cdf = tail_cdf;
(*t)->head_cdf = head_cdf;
#endif // CONFIG_EC_MULTISYMBOL
(*t)->skip_eob_node = skip_eob_node;
(*t)++;
......@@ -467,11 +469,15 @@ static void tokenize_b(int plane, int block, int blk_row, int blk_col,
#endif // CONFIG_ENTROPY
#if CONFIG_EC_ADAPT // use per-tile context
aom_cdf_prob(*const coef_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
xd->tile_ctx->coef_cdfs[tx_size][type][ref];
aom_cdf_prob(*const coef_head_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
xd->tile_ctx->coef_head_cdfs[tx_size][type][ref];
aom_cdf_prob(*const coef_tail_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
xd->tile_ctx->coef_tail_cdfs[tx_size][type][ref];
#elif CONFIG_EC_MULTISYMBOL
aom_cdf_prob(*const coef_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
cpi->common.fc->coef_cdfs[tx_size][type][ref];
aom_cdf_prob(*const coef_head_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
cpi->common.fc->coef_head_cdfs[tx_size][type][ref];
aom_cdf_prob(*const coef_tail_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
cpi->common.fc->coef_tail_cdfs[tx_size][type][ref];
#endif
unsigned int(*const eob_branch)[COEFF_CONTEXTS] =
td->counts->eob_branch[txsize_sqr_map[tx_size]][type][ref];
......@@ -495,7 +501,7 @@ static void tokenize_b(int plane, int block, int blk_row, int blk_col,
add_token(&t, coef_probs[band[c]][pt],
#if CONFIG_EC_MULTISYMBOL
&coef_cdfs[band[c]][pt],
&coef_tail_cdfs[band[c]][pt], &coef_head_cdfs[band[c]][pt],
#endif
extra, (uint8_t)token, (uint8_t)skip_eob, counts[band[c]][pt]);
......@@ -508,7 +514,7 @@ static void tokenize_b(int plane, int block, int blk_row, int blk_col,
assert(!skip_eob); // The last token must be non-zero.
add_token(&t, coef_probs[band[c]][pt],
#if CONFIG_EC_MULTISYMBOL
NULL,
NULL, NULL,
#endif
0, EOB_TOKEN, 0, counts[band[c]][pt]);
++eob_branch[band[c]][pt];
......
......@@ -37,7 +37,8 @@ typedef struct {
typedef struct {
const aom_prob *context_tree;
#if CONFIG_EC_MULTISYMBOL
aom_cdf_prob (*token_cdf)[ENTROPY_TOKENS];
aom_cdf_prob (*tail_cdf)[ENTROPY_TOKENS];
aom_cdf_prob (*head_cdf)[ENTROPY_TOKENS];
#endif
EXTRABIT extra;
uint8_t token;
......
......@@ -96,11 +96,13 @@ def quantize_probs(p, save_first_bin, bits):
def get_quantized_spareto(p, beta, bits):
parray = get_spareto(p, beta)
parray = parray[1:] / (1 - parray[0])
qarray = quantize_probs(parray, True, bits)
#if CONFIG_EC_MULTISYMBOL, truncate the array again
tarray = parray[1:] / (1 - parray[0])
qarray = quantize_probs(tarray, False, bits)
return qarray.astype(np.int)
def main(bits=8):
def main(bits=15):
beta = 8
for q in range(1, 256):
parray = get_quantized_spareto(q / 256., beta, bits)
......
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