Commit a9598cd6 authored by Alex Converse's avatar Alex Converse

ec_multisymbol: Split off new new_tokenset experiment

The new_tokenset experiment replaces the unconstrained tokenset with a
multisymbol alphabet in an inventive way.

Tested configurations:
new_tokenset + ec_adapt, new_tokenset, ec_multisymbol

Change-Id: I846ab2e51c2a1dc3f2f9904ed8c47a8e98f853c5
parent fb993173
This diff is collapsed.
......@@ -45,7 +45,7 @@ extern "C" {
#define CATEGORY5_TOKEN 9 // 35-66 Extra Bits 5+1
#define CATEGORY6_TOKEN 10 // 67+ Extra Bits 14+1
#define EOB_TOKEN 11 // EOB Extra Bits 0+0
#if CONFIG_EC_MULTISYMBOL
#if CONFIG_NEW_TOKENSET
#define BLOCK_Z_TOKEN 255 // block zero
#define ONE_TOKEN_EOB 1
#define ONE_TOKEN_NEOB 2
......
......@@ -84,11 +84,13 @@ typedef struct frame_contexts {
aom_prob partition_prob[PARTITION_CONTEXTS][PARTITION_TYPES - 1];
#endif
av1_coeff_probs_model coef_probs[TX_SIZES][PLANE_TYPES];
#if CONFIG_EC_MULTISYMBOL
#if CONFIG_NEW_TOKENSET
coeff_cdf_model coef_tail_cdfs[TX_SIZES][PLANE_TYPES];
coeff_cdf_model coef_head_cdfs[TX_SIZES][PLANE_TYPES];
aom_prob blockzero_probs[TX_SIZES][PLANE_TYPES][REF_TYPES][BLOCKZ_CONTEXTS];
#endif // CONFIG_EC_MULTISYMBOL
#elif CONFIG_EC_MULTISYMBOL
coeff_cdf_model coef_cdfs[TX_SIZES][PLANE_TYPES];
#endif // CONFIG_NEW_TOKENSET
aom_prob switchable_interp_prob[SWITCHABLE_FILTER_CONTEXTS]
[SWITCHABLE_FILTERS - 1];
#if CONFIG_ADAPT_SCAN
......
......@@ -2425,11 +2425,15 @@ static void setup_bool_decoder(const uint8_t *data, const uint8_t *data_end,
"Failed to allocate bool decoder %d", 1);
}
#if !CONFIG_PVQ && !CONFIG_EC_ADAPT
#if !CONFIG_PVQ && !(CONFIG_EC_ADAPT && CONFIG_NEW_TOKENSET)
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;
#else
const int node_limit = UNCONSTRAINED_NODES;
#endif
if (aom_read_bit(r, ACCT_STR))
for (i = 0; i < PLANE_TYPES; ++i)
......@@ -4493,7 +4497,7 @@ static int read_compressed_header(AV1Decoder *pbi, const uint8_t *data,
if (cm->tx_mode == TX_MODE_SELECT) read_tx_size_probs(fc, &r);
#if !CONFIG_PVQ
#if !CONFIG_EC_ADAPT
#if !(CONFIG_EC_ADAPT && CONFIG_NEW_TOKENSET)
read_coef_probs(fc, cm->tx_mode, &r);
#endif
......
......@@ -81,22 +81,29 @@ static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
#endif // CONFIG_AOM_QM
int band, c = 0;
const int tx_size_ctx = txsize_sqr_map[tx_size];
#if CONFIG_EC_MULTISYMBOL
#if CONFIG_NEW_TOKENSET
aom_cdf_prob(*coef_head_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
ec_ctx->coef_head_cdfs[tx_size_ctx][type][ref];
aom_cdf_prob(*coef_tail_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
ec_ctx->coef_tail_cdfs[tx_size_ctx][type][ref];
#else
aom_prob(*coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] =
ec_ctx->coef_probs[tx_size_ctx][type][ref];
const aom_prob *prob;
#endif
#if CONFIG_EC_MULTISYMBOL
aom_cdf_prob(*cdf_head)[ENTROPY_TOKENS];
aom_cdf_prob(*cdf_tail)[ENTROPY_TOKENS];
int val = 0;
unsigned int *blockz_count;
#endif
#else
aom_prob(*coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] =
ec_ctx->coef_probs[tx_size_ctx][type][ref];
const aom_prob *prob;
#if CONFIG_EC_ADAPT
aom_cdf_prob(*coef_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
ec_ctx->coef_cdfs[tx_size][type][ref];
aom_cdf_prob(*cdf)[ENTROPY_TOKENS];
#elif CONFIG_EC_MULTISYMBOL
aom_cdf_prob(*coef_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
ec_ctx->coef_cdfs[tx_size_ctx][type][ref];
aom_cdf_prob(*cdf)[ENTROPY_TOKENS];
#endif // CONFIG_EC_ADAPT
#endif // CONFIG_NEW_TOKENSET
unsigned int(*coef_counts)[COEFF_CONTEXTS][UNCONSTRAINED_NODES + 1] = NULL;
unsigned int(*eob_branch_count)[COEFF_CONTEXTS] = NULL;
uint8_t token_cache[MAX_TX_SQUARE];
......@@ -121,7 +128,7 @@ static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
if (counts) {
coef_counts = counts->coef[tx_size_ctx][type][ref];
eob_branch_count = counts->eob_branch[tx_size_ctx][type][ref];
#if CONFIG_EC_MULTISYMBOL
#if CONFIG_NEW_TOKENSET
blockz_count = counts->blockz_count[tx_size_ctx][type][ref][ctx];
#endif
}
......@@ -162,7 +169,7 @@ static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
dq_shift = get_tx_scale(tx_size);
#if CONFIG_EC_MULTISYMBOL
#if CONFIG_NEW_TOKENSET
band = *band_translate++;
while (c < max_eob) {
......@@ -272,7 +279,7 @@ static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
ctx = get_coef_context(nb, token_cache, c);
band = *band_translate++;
#else // CONFIG_EC_MULTISYMBOL
#else // CONFIG_NEW_TOKENSET
while (c < max_eob) {
int val = -1;
band = *band_translate++;
......@@ -303,6 +310,53 @@ 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:
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: {
const int skip_bits = TX_SIZES - 1 - txsize_sqr_up_map[tx_size];
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_EC_MULTISYMBOL
if (!aom_read(r, prob[ONE_CONTEXT_NODE], ACCT_STR)) {
INCREMENT_COUNT(ONE_TOKEN);
token = ONE_TOKEN;
......@@ -353,6 +407,7 @@ static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
}
}
}
#endif // CONFIG_EC_MULTISYMBOL
#if CONFIG_NEW_QUANT
v = av1_dequant_abscoeff_nuq(val, dqv, dqv_val);
v = dq_shift ? ROUND_POWER_OF_TWO(v, dq_shift) : v;
......@@ -378,7 +433,7 @@ static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
++c;
ctx = get_coef_context(nb, token_cache, c);
dqv = dq[1];
#endif // CONFIG_EC_MULTISYMBOL
#endif // CONFIG_NEW_TOKENSET
}
return c;
......
......@@ -762,7 +762,7 @@ static void update_supertx_probs(AV1_COMMON *cm, int probwt, aom_writer *w) {
}
#endif // CONFIG_SUPERTX
#if CONFIG_EC_MULTISYMBOL
#if CONFIG_NEW_TOKENSET
static void pack_mb_tokens(aom_writer *w, const TOKENEXTRA **tp,
const TOKENEXTRA *const stop,
aom_bit_depth_t bit_depth, const TX_SIZE tx_size,
......@@ -862,11 +862,25 @@ static void pack_mb_tokens(aom_writer *w, const TOKENEXTRA **tp,
while (p < stop && p->token != EOSB_TOKEN) {
const int token = p->token;
aom_tree_index index = 0;
#if !CONFIG_EC_MULTISYMBOL
const struct av1_token *const coef_encoding = &av1_coef_encodings[token];
int coef_value = coef_encoding->value;
int coef_length = coef_encoding->len;
#endif // !CONFIG_EC_MULTISYMBOL
const av1_extra_bit *const extra_bits = &extra_bits_table[token];
#if CONFIG_EC_MULTISYMBOL
/* skip one or two nodes */
if (!p->skip_eob_node)
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);
}
}
#else
/* skip one or two nodes */
if (p->skip_eob_node)
coef_length -= p->skip_eob_node;
......@@ -889,6 +903,7 @@ static void pack_mb_tokens(aom_writer *w, const TOKENEXTRA **tp,
}
}
}
#endif // CONFIG_EC_MULTISYMBOL
if (extra_bits->base_val) {
const int bit_string = p->extra;
......@@ -2795,7 +2810,7 @@ static void write_modes(AV1_COMP *const cpi, const TileInfo *const tile,
#endif
}
#if !CONFIG_PVQ && !CONFIG_EC_ADAPT
#if !CONFIG_PVQ && !(CONFIG_EC_ADAPT && CONFIG_NEW_TOKENSET)
static void build_tree_distribution(AV1_COMP *cpi, TX_SIZE tx_size,
av1_coeff_stats *coef_branch_ct,
av1_coeff_probs_model *coef_probs) {
......@@ -2826,14 +2841,18 @@ static void build_tree_distribution(AV1_COMP *cpi, TX_SIZE tx_size,
}
}
#if !CONFIG_EC_ADAPT
#if !(CONFIG_EC_ADAPT && CONFIG_NEW_TOKENSET)
static void update_coef_probs_common(aom_writer *const bc, AV1_COMP *cpi,
TX_SIZE tx_size,
av1_coeff_stats *frame_branch_ct,
av1_coeff_probs_model *new_coef_probs) {
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;
#else
const int entropy_nodes_update = UNCONSTRAINED_NODES;
#endif
int i, j, k, l, t;
int stepsize = cpi->sf.coeff_prob_appx_step;
#if CONFIG_TILE_GROUPS
......@@ -3183,7 +3202,7 @@ static void update_coef_probs_subframe(
}
#endif // CONFIG_ENTROPY
#if !CONFIG_EC_ADAPT
#if !(CONFIG_EC_ADAPT && CONFIG_NEW_TOKENSET)
static void update_coef_probs(AV1_COMP *cpi, aom_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];
......@@ -4550,9 +4569,9 @@ static uint32_t write_compressed_header(AV1_COMP *cpi, uint8_t *data) {
#endif // CONFIG_LOOP_RESTORATION
update_txfm_probs(cm, header_bc, counts);
#if !CONFIG_PVQ
#if !CONFIG_EC_ADAPT
#if !(CONFIG_EC_ADAPT && CONFIG_NEW_TOKENSET)
update_coef_probs(cpi, header_bc);
#endif // CONFIG_EC_ADAPT
#endif // !(CONFIG_EC_ADAPT && CONFIG_NEW_TOKENSET)
#endif // CONFIG_PVQ
#if CONFIG_VAR_TX
update_txfm_partition_probs(cm, header_bc, counts, probwt);
......
......@@ -360,7 +360,7 @@ static void set_entropy_context_b(int plane, int block, int blk_row,
blk_row);
}
#if CONFIG_EC_MULTISYMBOL
#if CONFIG_NEW_TOKENSET
static INLINE void add_token(TOKENEXTRA **t,
aom_cdf_prob (*tail_cdf)[ENTROPY_TOKENS],
aom_cdf_prob (*head_cdf)[ENTROPY_TOKENS],
......@@ -375,18 +375,22 @@ static INLINE void add_token(TOKENEXTRA **t,
#else
static INLINE void add_token(TOKENEXTRA **t, const aom_prob *context_tree,
#if CONFIG_EC_MULTISYMBOL
aom_cdf_prob (*token_cdf)[ENTROPY_TOKENS],
#endif // CONFIG_EC_MULTISYMBOL
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_EC_MULTISYMBOL
(*t)->token_cdf = token_cdf;
#endif // CONFIG_EC_MULTISYMBOL
(*t)->skip_eob_node = skip_eob_node;
(*t)++;
++counts[token];
}
#endif
#if !CONFIG_EC_MULTISYMBOL
static INLINE int get_tx_eob(const struct segmentation *seg, int segment_id,
TX_SIZE tx_size) {
const int eob_max = tx_size_2d[tx_size];
......@@ -455,13 +459,13 @@ static void tokenize_b(int plane, int block, int blk_row, int blk_col,
const int eob = p->eobs[block];
const PLANE_TYPE type = pd->plane_type;
const tran_low_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
#if !CONFIG_EC_MULTISYMBOL
#if !CONFIG_NEW_TOKENSET
#if CONFIG_SUPERTX
const int segment_id = AOMMIN(mbmi->segment_id, mbmi->segment_id_supertx);
#else
const int segment_id = mbmi->segment_id;
#endif // CONFIG_SUEPRTX
#endif
#endif // !CONFIG_NEW_TOKENSET
const int16_t *scan, *nb;
const int block_raster_idx = av1_block_index_to_raster_order(tx_size, block);
const TX_TYPE tx_type = get_tx_type(type, xd, block_raster_idx, tx_size);
......@@ -470,7 +474,7 @@ static void tokenize_b(int plane, int block, int blk_row, int blk_col,
const int ref = is_inter_block(mbmi);
unsigned int(*const counts)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
td->rd_counts.coef_counts[txsize_sqr_map[tx_size]][type][ref];
#if !CONFIG_EC_MULTISYMBOL
#if !CONFIG_NEW_TOKENSET
#if CONFIG_ENTROPY
const aom_prob(*coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] =
cpi->subframe_stats.coef_probs_buf[cpi->common.coef_probs_update_idx]
......@@ -479,13 +483,13 @@ static void tokenize_b(int plane, int block, int blk_row, int blk_col,
aom_prob(*const coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] =
cpi->common.fc->coef_probs[txsize_sqr_map[tx_size]][type][ref];
#endif // CONFIG_ENTROPY
#endif
#endif // !CONFIG_NEW_TOKENSET
#if CONFIG_EC_ADAPT
FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
#elif CONFIG_EC_MULTISYMBOL
FRAME_CONTEXT *ec_ctx = cpi->common.fc;
#endif
#if CONFIG_EC_MULTISYMBOL
#if CONFIG_NEW_TOKENSET
aom_cdf_prob(*const coef_head_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
ec_ctx->coef_head_cdfs[tx_size][type][ref];
aom_cdf_prob(*const coef_tail_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
......@@ -494,6 +498,10 @@ static void tokenize_b(int plane, int block, int blk_row, int blk_col,
td->counts->blockz_count[txsize_sqr_map[tx_size]][type][ref];
int is_eob;
#else
#if CONFIG_EC_MULTISYMBOL
aom_cdf_prob(*const coef_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
ec_ctx->coef_cdfs[tx_size][type][ref];
#endif
int skip_eob = 0;
const int seg_eob = get_tx_eob(&cpi->common.seg, segment_id, tx_size);
#endif
......@@ -509,7 +517,7 @@ static void tokenize_b(int plane, int block, int blk_row, int blk_col,
nb = scan_order->neighbors;
c = 0;
#if CONFIG_EC_MULTISYMBOL
#if CONFIG_NEW_TOKENSET
if (eob == 0)
add_token(&t, &coef_tail_cdfs[band[c]][pt], &coef_head_cdfs[band[c]][pt], 0,
0, BLOCK_Z_TOKEN);
......@@ -548,8 +556,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_EC_MULTISYMBOL
&coef_cdfs[band[c]][pt],
#endif
extra, (uint8_t)token, (uint8_t)skip_eob, counts[band[c]][pt]);
token_cache[scan[c]] = av1_pt_energy_class[token];
++c;
......@@ -557,11 +568,14 @@ static void tokenize_b(int plane, int block, int blk_row, int blk_col,
skip_eob = (token == ZERO_TOKEN);
}
if (c < seg_eob) {
add_token(&t, coef_probs[band[c]][pt], 0, EOB_TOKEN, 0,
counts[band[c]][pt]);
add_token(&t, coef_probs[band[c]][pt],
#if CONFIG_EC_MULTISYMBOL
NULL,
#endif
0, EOB_TOKEN, 0, counts[band[c]][pt]);
++eob_branch[band[c]][pt];
}
#endif
#endif // CONFIG_NEW_TOKENSET
#if CONFIG_COEF_INTERLEAVE
t->token = EOSB_TOKEN;
......
......@@ -35,10 +35,12 @@ typedef struct {
} TOKENVALUE;
typedef struct {
#if CONFIG_EC_MULTISYMBOL
#if CONFIG_NEW_TOKENSET
aom_cdf_prob (*tail_cdf)[ENTROPY_TOKENS];
aom_cdf_prob (*head_cdf)[ENTROPY_TOKENS];
int is_eob;
#elif CONFIG_EC_MULTISYMBOL
aom_cdf_prob (*token_cdf)[ENTROPY_TOKENS];
#endif
const aom_prob *context_tree;
EXTRABIT extra;
......
......@@ -271,6 +271,7 @@ EXPERIMENT_LIST="
supertx
ans
ec_multisymbol
new_tokenset
loop_restoration
ext_partition
ext_partition_types
......@@ -482,6 +483,7 @@ post_process_cmdline() {
# Fix up experiment dependencies
enabled ec_adapt && enable_feature ec_multisymbol
enabled new_tokenset && enable_feature ec_multisymbol
enabled ec_multisymbol && ! enabled ans && soft_enable daala_ec
enabled ec_multisymbol && ! enabled daala_ec && soft_enable ans
enabled daala_ec && enable_feature ec_multisymbol
......
......@@ -93,25 +93,28 @@ def quantize_probs(p, save_first_bin, bits):
return q
def get_quantized_spareto(p, beta, bits):
def get_quantized_spareto(p, beta, bits, first_token):
parray = get_spareto(p, beta)
parray = parray[1:] / (1 - parray[0])
#if CONFIG_EC_MULTISYMBOL, truncate the array again
tarray = parray[1:] / (1 - parray[0])
qarray = quantize_probs(tarray, False, bits)
# CONFIG_NEW_TOKENSET
if first_token > 1:
parray = parray[1:] / (1 - parray[0])
qarray = quantize_probs(parray, first_token == 1, bits)
return qarray.astype(np.int)
def main(bits=15):
def main(bits=15, first_token=1):
beta = 8
for q in range(1, 256):
parray = get_quantized_spareto(q / 256., beta, bits)
parray = get_quantized_spareto(q / 256., beta, bits, first_token)
assert parray.sum() == 2**bits
print '{', ', '.join('%d' % i for i in parray), '},'
if __name__ == '__main__':
if len(sys.argv) > 1:
if len(sys.argv) > 2:
main(int(sys.argv[1]), int(sys.argv[2]))
elif len(sys.argv) > 1:
main(int(sys.argv[1]))
else:
main()
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