Commit 8c687d2f authored by Alex Converse's avatar Alex Converse
Browse files

ans: Cleanup rans writing routines

* Replace struct rans_sym parameter with values. It only had two entries.
* Document functions.
* Use longer variable names.

TODO: Refactor the unit tests.

Change-Id: Idad65117dab565786697015ef07070e1c308d963
parent 39204068
......@@ -124,24 +124,20 @@ static INLINE void rabs_write(struct AnsCoder *ans, int value, AnsP8 p0) {
ans->state = quotient * ANS_P8_PRECISION + remainder + (value ? p0 : 0);
}
struct rans_sym {
aom_cdf_prob prob;
aom_cdf_prob cum_prob; // not-inclusive
};
// rANS with normalization
// sym->prob takes the place of l_s from the paper
// ANS_P10_PRECISION is m
static INLINE void rans_write(struct AnsCoder *ans,
const struct rans_sym *const sym) {
const aom_cdf_prob p = sym->prob;
unsigned quot, rem;
while (ans->state >= L_BASE / RANS_PRECISION * IO_BASE * p) {
// Encode one symbol using rANS.
// cum_prob: The cumulative probability before this symbol (the offset of
// the symbol in the symbol cycle)
// prob: The probability of this symbol (l_s from the paper)
// RANS_PRECISION takes the place of m from the paper.
static INLINE void rans_write(struct AnsCoder *ans, aom_cdf_prob cum_prob,
aom_cdf_prob prob) {
unsigned quotient, remainder;
while (ans->state >= L_BASE / RANS_PRECISION * IO_BASE * prob) {
ans->buf[ans->buf_offset++] = ans->state % IO_BASE;
ans->state /= IO_BASE;
}
ANS_DIVREM(quot, rem, ans->state, p);
ans->state = quot * RANS_PRECISION + rem + sym->cum_prob;
ANS_DIVREM(quotient, remainder, ans->state, prob);
ans->state = quotient * RANS_PRECISION + remainder + cum_prob;
}
#undef ANS_DIV8
......
......@@ -186,12 +186,11 @@ static INLINE void aom_write_tree_record(aom_writer *w,
static INLINE void aom_write_cdf(aom_writer *w, int symb,
const aom_cdf_prob *cdf, int nsymbs) {
#if CONFIG_ANS
struct rans_sym s;
(void)nsymbs;
assert(cdf);
s.cum_prob = symb > 0 ? cdf[symb - 1] : 0;
s.prob = cdf[symb] - s.cum_prob;
buf_rans_write(w, &s);
const aom_cdf_prob cum_prob = symb > 0 ? cdf[symb - 1] : 0;
const aom_cdf_prob prob = cdf[symb] - cum_prob;
buf_rans_write(w, cum_prob, prob);
#elif CONFIG_DAALA_EC
daala_write_symbol(w, symb, cdf, nsymbs);
#else
......
......@@ -60,10 +60,7 @@ void aom_buf_ans_flush(struct BufAnsCoder *const c) {
}
for (offset = offset - 1; offset >= 0; --offset) {
if (c->buf[offset].method == ANS_METHOD_RANS) {
struct rans_sym sym;
sym.prob = c->buf[offset].prob;
sym.cum_prob = c->buf[offset].val_start;
rans_write(&c->ans, &sym);
rans_write(&c->ans, c->buf[offset].val_start, c->buf[offset].prob);
} else {
rabs_write(&c->ans, (uint8_t)c->buf[offset].val_start,
(AnsP8)c->buf[offset].prob);
......
......@@ -88,8 +88,13 @@ static INLINE void buf_rabs_write(struct BufAnsCoder *const c, uint8_t val,
#endif
}
// Buffer one symbol for encoding using rANS.
// cum_prob: The cumulative probability before this symbol (the offset of
// the symbol in the symbol cycle)
// prob: The probability of this symbol (l_s from the paper)
// RANS_PRECISION takes the place of m from the paper.
static INLINE void buf_rans_write(struct BufAnsCoder *const c,
const struct rans_sym *const sym) {
aom_cdf_prob cum_prob, aom_cdf_prob prob) {
assert(c->offset <= c->size);
#if !ANS_MAX_SYMBOLS
if (c->offset == c->size) {
......@@ -97,8 +102,8 @@ static INLINE void buf_rans_write(struct BufAnsCoder *const c,
}
#endif
c->buf[c->offset].method = ANS_METHOD_RANS;
c->buf[c->offset].val_start = sym->cum_prob;
c->buf[c->offset].prob = sym->prob;
c->buf[c->offset].val_start = cum_prob;
c->buf[c->offset].prob = prob;
++c->offset;
#if ANS_MAX_SYMBOLS
if (c->offset == c->size) aom_buf_ans_flush(c);
......
......@@ -87,6 +87,11 @@ const aom_cdf_prob spareto65[] = { 8320, 6018, 4402, 3254, 4259,
const int kRansSymbols =
static_cast<int>(sizeof(spareto65) / sizeof(spareto65[0]));
struct rans_sym {
aom_cdf_prob prob;
aom_cdf_prob cum_prob; // not-inclusive
};
std::vector<int> ans_encode_build_vals(rans_sym *const tab, int iters) {
aom_cdf_prob sum = 0;
for (int i = 0; i < kRansSymbols; ++i) {
......@@ -128,7 +133,7 @@ bool check_rans(const std::vector<int> &sym_vec, const rans_sym *const tab,
std::clock_t start = std::clock();
for (std::vector<int>::const_iterator it = sym_vec.begin();
it != sym_vec.end(); ++it) {
buf_rans_write(&a, &tab[*it]);
buf_rans_write(&a, tab[*it].cum_prob, tab[*it].prob);
}
aom_buf_ans_flush(&a);
std::clock_t enc_time = std::clock() - start;
......
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