ans: Use a subnormal initial state
This saves the cost of encoding one symbol per partition. Currently in practice this is usually the last DCT token sign so it saves one bit. Most of the time these gains aren't realized but occasionally it makes the final state one byte smaller or saves one renormalization. Change-Id: Ibe5dc5d3471f51f932164b32e3bf28fb7b914805
This commit is contained in:
Родитель
e0b7151138
Коммит
3920406821
|
@ -69,7 +69,7 @@ static INLINE int rabs_read(struct AnsDecoder *ans, AnsP8 p0) {
|
|||
ans->symbols_left--;
|
||||
}
|
||||
#endif
|
||||
unsigned state = ans->state;
|
||||
unsigned state = refill_state(ans, ans->state);
|
||||
const unsigned quotient = state / ANS_P8_PRECISION;
|
||||
const unsigned remainder = state % ANS_P8_PRECISION;
|
||||
const int value = remainder >= p0;
|
||||
|
@ -77,7 +77,7 @@ static INLINE int rabs_read(struct AnsDecoder *ans, AnsP8 p0) {
|
|||
state = quotient * (ANS_P8_PRECISION - p0) + remainder - p0;
|
||||
else
|
||||
state = quotient * p0 + remainder;
|
||||
ans->state = refill_state(ans, state);
|
||||
ans->state = state;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -119,11 +119,11 @@ static INLINE int rans_read(struct AnsDecoder *ans, const aom_cdf_prob *tab) {
|
|||
ans->symbols_left--;
|
||||
}
|
||||
#endif
|
||||
ans->state = refill_state(ans, ans->state);
|
||||
quo = ans->state / RANS_PRECISION;
|
||||
rem = ans->state % RANS_PRECISION;
|
||||
fetch_sym(&sym, tab, rem);
|
||||
ans->state = quo * sym.prob + rem - sym.cum_prob;
|
||||
ans->state = refill_state(ans, ans->state);
|
||||
return sym.val;
|
||||
}
|
||||
|
||||
|
@ -193,12 +193,12 @@ static INLINE int ans_read_reinit(struct AnsDecoder *const ans) {
|
|||
}
|
||||
#endif
|
||||
|
||||
static INLINE int ans_read_end(struct AnsDecoder *const ans) {
|
||||
return ans->state == L_BASE;
|
||||
static INLINE int ans_read_end(const struct AnsDecoder *const ans) {
|
||||
return ans->buf_offset == 0 && ans->state < L_BASE;
|
||||
}
|
||||
|
||||
static INLINE int ans_reader_has_error(const struct AnsDecoder *const ans) {
|
||||
return ans->state < L_BASE && ans->buf_offset == 0;
|
||||
return ans->state < L_BASE / RANS_PRECISION;
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
@ -50,7 +50,15 @@ void aom_buf_ans_flush(struct BufAnsCoder *const c) {
|
|||
if (c->offset == 0) return;
|
||||
#endif
|
||||
assert(c->offset > 0);
|
||||
for (offset = c->offset - 1; offset >= 0; --offset) {
|
||||
offset = c->offset - 1;
|
||||
// Code the first symbol such that it brings the state to the smallest normal
|
||||
// state from an initial state that would have been a subnormal/refill state.
|
||||
if (c->buf[offset].method == ANS_METHOD_RANS) {
|
||||
c->ans.state += c->buf[offset].val_start;
|
||||
} else {
|
||||
c->ans.state += c->buf[offset].val_start ? c->buf[offset].prob : 0;
|
||||
}
|
||||
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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче