Commit 362888b9 authored by Alex Converse's avatar Alex Converse

Use rANS to code constrained token set.

For now this is in its own experiment for benchmarking purposes, but it
will eventually be folded into the main ANS experiment.

Change-Id: Icdb54b6ca3c0191ba717d6d10aaaffb11e2bebea
parent baa6815e
......@@ -125,7 +125,10 @@ static INLINE int aom_read_tree(aom_reader *r, const aom_tree_index *tree,
static INLINE int aom_read_tree_cdf(aom_reader *r, const uint16_t *cdf,
int nsymbs) {
#if CONFIG_DAALA_EC
#if CONFIG_RANS
(void)nsymbs;
return rans_read(r, cdf);
#elif CONFIG_DAALA_EC
return daala_read_tree_cdf(r, cdf, nsymbs);
#else
(void)r;
......
......@@ -100,7 +100,14 @@ static INLINE void aom_write_tree(aom_writer *w, const aom_tree_index *tree,
static INLINE void aom_write_tree_cdf(aom_writer *w, int symb,
const uint16_t *cdf, int nsymbs) {
#if CONFIG_DAALA_EC
#if CONFIG_RANS
(void)nsymbs;
struct rans_sym s;
assert(cdf);
s.cum_prob = cdf[symb];
s.prob = cdf[symb + 1] - s.cum_prob;
buf_rans_write(w, &s);
#elif CONFIG_DAALA_EC
daala_write_tree_cdf(w, symb, cdf, nsymbs);
#else
(void)w;
......
This diff is collapsed.
......@@ -12,7 +12,11 @@
#ifndef AV1_COMMON_ENTROPY_H_
#define AV1_COMMON_ENTROPY_H_
#include "./aom_config.h"
#include "aom/aom_integer.h"
#if CONFIG_RANS
#include "aom_dsp/ans.h"
#endif // CONFIG_RANS
#include "aom_dsp/prob.h"
#include "av1/common/common.h"
......@@ -173,6 +177,14 @@ typedef unsigned int av1_coeff_count_model
void av1_model_to_full_probs(const aom_prob *model, aom_prob *full);
#if CONFIG_RANS
typedef rans_lut coeff_cdf_model[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS];
extern const AnsP10
av1_pareto8_token_probs[COEFF_PROB_MODELS][ENTROPY_TOKENS - 2];
struct frame_contexts;
void av1_coef_pareto_cdfs(struct frame_contexts *fc);
#endif // CONFIG_RANS
typedef char ENTROPY_CONTEXT;
static INLINE int combine_entropy_contexts(ENTROPY_CONTEXT a,
......
......@@ -54,6 +54,9 @@ typedef struct frame_contexts {
aom_prob uv_mode_prob[INTRA_MODES][INTRA_MODES - 1];
aom_prob partition_prob[PARTITION_CONTEXTS][PARTITION_TYPES - 1];
av1_coeff_probs_model coef_probs[TX_SIZES][PLANE_TYPES];
#if CONFIG_RANS
coeff_cdf_model coef_cdfs[TX_SIZES][PLANE_TYPES];
#endif // CONFIG_RANS
aom_prob
switchable_interp_prob[SWITCHABLE_FILTER_CONTEXTS][SWITCHABLE_FILTERS -
1];
......
......@@ -708,6 +708,9 @@ static void read_coef_probs(FRAME_CONTEXT *fc, TX_MODE tx_mode, aom_reader *r) {
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_RANS
av1_coef_pareto_cdfs(fc);
#endif // CONFIG_RANS
}
static void setup_segmentation(AV1_COMMON *const cm,
......
......@@ -67,6 +67,11 @@ static int decode_coefs(const MACROBLOCKD *xd, PLANE_TYPE type,
const aom_prob(*coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] =
fc->coef_probs[tx_size][type][ref];
const aom_prob *prob;
#if CONFIG_RANS
const rans_lut(*coef_cdfs)[COEFF_CONTEXTS] =
fc->coef_cdfs[tx_size][type][ref];
const rans_lut *cdf;
#endif // CONFIG_RANS
unsigned int(*coef_counts)[COEFF_CONTEXTS][UNCONSTRAINED_NODES + 1];
unsigned int(*eob_branch_count)[COEFF_CONTEXTS];
uint8_t token_cache[32 * 32];
......@@ -141,6 +146,58 @@ static int decode_coefs(const MACROBLOCKD *xd, PLANE_TYPE type,
prob = coef_probs[band][ctx];
}
#if CONFIG_RANS
cdf = &coef_cdfs[band][ctx];
token =
ONE_TOKEN + aom_read_tree_cdf(r, *cdf, CATEGORY6_TOKEN - ONE_TOKEN + 1);
INCREMENT_COUNT(ONE_TOKEN + (token > ONE_TOKEN));
switch (token) {
case ONE_TOKEN:
case TWO_TOKEN:
case THREE_TOKEN:
case FOUR_TOKEN: val = token; break;
case CATEGORY1_TOKEN:
val = CAT1_MIN_VAL + read_coeff(cat1_prob, 1, r);
break;
case CATEGORY2_TOKEN:
val = CAT2_MIN_VAL + read_coeff(cat2_prob, 2, r);
break;
case CATEGORY3_TOKEN:
val = CAT3_MIN_VAL + read_coeff(cat3_prob, 3, r);
break;
case CATEGORY4_TOKEN:
val = CAT4_MIN_VAL + read_coeff(cat4_prob, 4, r);
break;
case CATEGORY5_TOKEN:
val = CAT5_MIN_VAL + read_coeff(cat5_prob, 5, r);
break;
case CATEGORY6_TOKEN: {
#if CONFIG_MISC_FIXES
const int skip_bits = TX_SIZES - 1 - tx_size;
#else
const int skip_bits = 0;
#endif
const uint8_t *cat6p = cat6_prob + skip_bits;
#if CONFIG_AOM_HIGHBITDEPTH
switch (xd->bd) {
case AOM_BITS_8:
val = CAT6_MIN_VAL + read_coeff(cat6p, 14 - skip_bits, r);
break;
case AOM_BITS_10:
val = CAT6_MIN_VAL + read_coeff(cat6p, 16 - skip_bits, r);
break;
case AOM_BITS_12:
val = CAT6_MIN_VAL + read_coeff(cat6p, 18 - skip_bits, r);
break;
default: assert(0); return -1;
}
#else
val = CAT6_MIN_VAL + read_coeff(cat6p, 14 - skip_bits, r);
#endif
break;
}
}
#else // CONFIG_RANS
if (!aom_read(r, prob[ONE_CONTEXT_NODE])) {
INCREMENT_COUNT(ONE_TOKEN);
token = ONE_TOKEN;
......@@ -195,6 +252,7 @@ static int decode_coefs(const MACROBLOCKD *xd, PLANE_TYPE type,
}
}
}
#endif // CONFIG_RANS
#if CONFIG_AOM_QM
dqv = ((iqmatrix[scan[c]] * (int)dqv) + (1 << (AOM_QM_BITS - 1))) >>
AOM_QM_BITS;
......
......@@ -303,10 +303,12 @@ static void pack_mb_tokens(aom_writer *w, TOKENEXTRA **tp,
while (p < stop && p->token != EOSB_TOKEN) {
const int t = p->token;
#if !CONFIG_RANS
const struct av1_token *const a = &av1_coef_encodings[t];
int i = 0;
int v = a->value;
int n = a->len;
#endif // !CONFIG_RANS
#if CONFIG_AOM_HIGHBITDEPTH
const av1_extra_bit *b;
if (bit_depth == AOM_BITS_12)
......@@ -320,6 +322,17 @@ static void pack_mb_tokens(aom_writer *w, TOKENEXTRA **tp,
(void)bit_depth;
#endif // CONFIG_AOM_HIGHBITDEPTH
#if CONFIG_RANS
if (!p->skip_eob_node) aom_write(w, t != EOB_TOKEN, p->context_tree[0]);
if (t != EOB_TOKEN) {
aom_write(w, t != ZERO_TOKEN, p->context_tree[1]);
if (t != ZERO_TOKEN) {
aom_write_tree_cdf(w, t - ONE_TOKEN, *p->token_cdf,
CATEGORY6_TOKEN - ONE_TOKEN + 1);
}
}
#else
/* skip one or two nodes */
if (p->skip_eob_node) {
n -= p->skip_eob_node;
......@@ -345,6 +358,7 @@ static void pack_mb_tokens(aom_writer *w, TOKENEXTRA **tp,
} else {
aom_write_tree_bits(w, av1_coef_tree, p->context_tree, v, n, i);
}
#endif // CONFIG_RANS
if (b->base_val) {
const int e = p->extra, l = b->len;
......@@ -941,7 +955,7 @@ static void update_coef_probs_common(aom_writer *const bc, AV1_COMP *cpi,
/* Is coef updated at all */
if (update[1] == 0 || savings < 0) {
aom_write_bit(bc, 0);
return;
break;
}
aom_write_bit(bc, 1);
for (i = 0; i < PLANE_TYPES; ++i) {
......@@ -974,7 +988,7 @@ static void update_coef_probs_common(aom_writer *const bc, AV1_COMP *cpi,
}
}
}
return;
break;
}
case ONE_LOOP_REDUCED: {
......@@ -1027,10 +1041,13 @@ static void update_coef_probs_common(aom_writer *const bc, AV1_COMP *cpi,
if (updates == 0) {
aom_write_bit(bc, 0); // no updates
}
return;
break;
}
default: assert(0);
}
#if CONFIG_RANS
av1_coef_pareto_cdfs(cpi->common.fc);
#endif // CONFIG_RANS
}
static void update_coef_probs(AV1_COMP *cpi, aom_writer *w) {
......
......@@ -348,11 +348,17 @@ 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_RANS
const rans_lut *token_cdf,
#endif // CONFIG_RANS
int32_t extra, uint8_t token,
uint8_t skip_eob_node, unsigned int *counts) {
(*t)->token = token;
(*t)->extra = extra;
(*t)->context_tree = context_tree;
#if CONFIG_RANS
(*t)->token_cdf = token_cdf;
#endif // CONFIG_RANS
(*t)->skip_eob_node = skip_eob_node;
(*t)++;
++counts[token];
......@@ -360,10 +366,16 @@ static INLINE void add_token(TOKENEXTRA **t, const aom_prob *context_tree,
static INLINE void add_token_no_extra(TOKENEXTRA **t,
const aom_prob *context_tree,
#if CONFIG_RANS
const rans_lut *token_cdf,
#endif // CONFIG_RANS
uint8_t token, uint8_t skip_eob_node,
unsigned int *counts) {
(*t)->token = token;
(*t)->context_tree = context_tree;
#if CONFIG_RANS
(*t)->token_cdf = token_cdf;
#endif // CONFIG_RANS
(*t)->skip_eob_node = skip_eob_node;
(*t)++;
++counts[token];
......@@ -402,6 +414,10 @@ static void tokenize_b(int plane, int block, int blk_row, int blk_col,
td->rd_counts.coef_counts[tx_size][type][ref];
aom_prob (*const coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] =
cpi->common.fc->coef_probs[tx_size][type][ref];
#if CONFIG_RANS
rans_lut (*const coef_cdfs)[COEFF_CONTEXTS] =
cpi->common.fc->coef_cdfs[tx_size][type][ref];
#endif
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);
......@@ -421,8 +437,11 @@ static void tokenize_b(int plane, int block, int blk_row, int blk_col,
v = qcoeff[scan[c]];
while (!v) {
add_token_no_extra(&t, coef_probs[band[c]][pt], ZERO_TOKEN, skip_eob,
counts[band[c]][pt]);
add_token_no_extra(&t, coef_probs[band[c]][pt],
#if CONFIG_RANS
(const rans_lut *)&coef_cdfs[band[c]][pt],
#endif
ZERO_TOKEN, skip_eob, counts[band[c]][pt]);
eob_branch[band[c]][pt] += !skip_eob;
skip_eob = 1;
......@@ -434,8 +453,11 @@ static void tokenize_b(int plane, int block, int blk_row, int blk_col,
av1_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_RANS
(const rans_lut *)&coef_cdfs[band[c]][pt],
#endif
extra, (uint8_t)token, (uint8_t)skip_eob, counts[band[c]][pt]);
eob_branch[band[c]][pt] += !skip_eob;
token_cache[scan[c]] = av1_pt_energy_class[token];
......@@ -443,8 +465,11 @@ static void tokenize_b(int plane, int block, int blk_row, int blk_col,
pt = get_coef_context(nb, token_cache, c);
}
if (c < seg_eob) {
add_token_no_extra(&t, coef_probs[band[c]][pt], EOB_TOKEN, 0,
counts[band[c]][pt]);
add_token_no_extra(&t, coef_probs[band[c]][pt],
#if CONFIG_RANS
NULL,
#endif
EOB_TOKEN, 0, counts[band[c]][pt]);
++eob_branch[band[c]][pt];
}
......
......@@ -36,6 +36,9 @@ typedef struct {
typedef struct {
const aom_prob *context_tree;
#if CONFIG_RANS
const rans_lut *token_cdf;
#endif
EXTRABIT extra;
uint8_t token;
uint8_t skip_eob_node;
......
......@@ -262,6 +262,7 @@ EXPERIMENT_LIST="
ext_compound
supertx
ans
rans
daala_ec
parallel_deblocking
"
......
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