Commit b0be6411 authored by Alex Converse's avatar Alex Converse

ans: Use a fixed N-symbol window

Accept a small compression loss is in exchange for a fixed sized encoder
side buffering requirement.

subset1:
rans_base@2016-12-02T22:55:56.809Z -> rans_nsym@2016-12-02T22:58:19.859Z

    PSNR | PSNR Cb | PSNR Cr | PSNR HVS |   SSIM | MS SSIM | CIEDE 2000
  0.0304 |  0.0303 |  0.0305 |   0.0317 | 0.0312 |  0.0309 |     0.0301

Change-Id: I09dd143e4f1638b97dc9bba7023efa837a7d48c7
parent b878d817
......@@ -23,7 +23,8 @@
extern "C" {
#endif // __cplusplus
#define ANS_REVERSE 0
#define ANS_MAX_SYMBOLS (1 << 24)
#define ANS_REVERSE 1
typedef uint8_t AnsP8;
#define ANS_P8_PRECISION 256u
......
......@@ -32,11 +32,16 @@ struct AnsDecoder {
const uint8_t *buf;
int buf_offset;
uint32_t state;
#if ANS_MAX_SYMBOLS
int symbols_left;
#endif
#if CONFIG_ACCOUNTING
Accounting *accounting;
#endif
};
static INLINE int ans_read_reinit(struct AnsDecoder *const ans);
static INLINE unsigned refill_state(struct AnsDecoder *const ans,
unsigned state) {
#if ANS_REVERSE
......@@ -55,7 +60,14 @@ static INLINE int uabs_read(struct AnsDecoder *ans, AnsP8 p0) {
AnsP8 p = ANS_P8_PRECISION - p0;
int s;
unsigned xp, sp;
unsigned state = ans->state;
unsigned state;
#if ANS_MAX_SYMBOLS
if (ans->symbols_left-- == 0) {
ans_read_reinit(ans);
ans->symbols_left--;
}
#endif
state = ans->state;
sp = state * p;
xp = sp / ANS_P8_PRECISION;
s = (sp & 0xFF) >= p0;
......@@ -69,7 +81,14 @@ static INLINE int uabs_read(struct AnsDecoder *ans, AnsP8 p0) {
static INLINE int uabs_read_bit(struct AnsDecoder *ans) {
int s;
unsigned state = ans->state;
unsigned state;
#if ANS_MAX_SYMBOLS
if (ans->symbols_left-- == 0) {
ans_read_reinit(ans);
ans->symbols_left--;
}
#endif
state = ans->state;
s = (int)(state & 1);
state >>= 1;
ans->state = refill_state(ans, state);
......@@ -100,6 +119,12 @@ static INLINE int rans_read(struct AnsDecoder *ans, const aom_cdf_prob *tab) {
unsigned rem;
unsigned quo;
struct rans_dec_sym sym;
#if ANS_MAX_SYMBOLS
if (ans->symbols_left-- == 0) {
ans_read_reinit(ans);
ans->symbols_left--;
}
#endif
quo = ans->state / RANS_PRECISION;
rem = ans->state % RANS_PRECISION;
fetch_sym(&sym, tab, rem);
......@@ -150,9 +175,18 @@ static INLINE int ans_read_init(struct AnsDecoder *const ans,
#endif
ans->state += L_BASE;
if (ans->state >= L_BASE * IO_BASE) return 1;
#if ANS_MAX_SYMBOLS
ans->symbols_left = ANS_MAX_SYMBOLS;
#endif
return 0;
}
#if ANS_REVERSE
static INLINE int ans_read_reinit(struct AnsDecoder *const ans) {
return ans_read_init(ans, ans->buf + ans->buf_offset, -ans->buf_offset);
}
#endif
static INLINE int ans_read_end(struct AnsDecoder *const ans) {
return ans->state == L_BASE;
}
......
......@@ -89,6 +89,9 @@ static INLINE int ans_write_end(struct AnsCoder *const ans) {
ans->buf[i] = ans->buf[ans_size - 1 - i];
ans->buf[ans_size - 1 - i] = tmp;
}
ans->buf += ans_size;
ans->buf_offset = 0;
ans->state = L_BASE;
}
#endif
return ans_size;
......
......@@ -43,6 +43,10 @@ void aom_buf_ans_grow(struct BufAnsCoder *c) {
void aom_buf_ans_flush(struct BufAnsCoder *const c) {
int offset;
#if ANS_MAX_SYMBOLS
if (c->offset == 0) return;
#endif
assert(c->offset > 0);
for (offset = c->offset - 1; offset >= 0; --offset) {
if (c->buf[offset].method == ANS_METHOD_RANS) {
struct rans_sym sym;
......
......@@ -71,6 +71,9 @@ static INLINE void buf_uabs_write(struct BufAnsCoder *const c, uint8_t val,
c->buf[c->offset].val_start = val;
c->buf[c->offset].prob = prob;
++c->offset;
#if ANS_MAX_SYMBOLS
if (c->offset == ANS_MAX_SYMBOLS) aom_buf_ans_flush(c);
#endif
}
static INLINE void buf_rans_write(struct BufAnsCoder *const c,
......@@ -83,6 +86,9 @@ static INLINE void buf_rans_write(struct BufAnsCoder *const c,
c->buf[c->offset].val_start = sym->cum_prob;
c->buf[c->offset].prob = sym->prob;
++c->offset;
#if ANS_MAX_SYMBOLS
if (c->offset == ANS_MAX_SYMBOLS) aom_buf_ans_flush(c);
#endif
}
static INLINE void buf_uabs_write_bit(struct BufAnsCoder *c, int bit) {
......
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