Commit ead52876 authored by Timothy B. Terriberry's avatar Timothy B. Terriberry Committed by Tim Terriberry
Browse files

daala_ec: Convert the decoder to use iCDFs

This only changes the internal coding engine. We convert CDFs into
iCDFs at the "bool" reader <-> daala_ec boundary.

Decoder output should not change.

Change-Id: I483dfe3e5588d2038c3c7ec4cd5ba62d6699b920
parent 881f109b
...@@ -57,7 +57,7 @@ static INLINE int aom_daala_read(daala_reader *r, int prob) { ...@@ -57,7 +57,7 @@ static INLINE int aom_daala_read(daala_reader *r, int prob) {
}*/ }*/
#endif #endif
bit = od_ec_decode_bool_q15(&r->ec, p); bit = od_ec_decode_bool_q15(&r->ec, OD_ICDF(p));
#if CONFIG_BITSTREAM_DEBUG #if CONFIG_BITSTREAM_DEBUG
{ {
...@@ -108,7 +108,17 @@ static INLINE int aom_daala_reader_has_error(daala_reader *r) { ...@@ -108,7 +108,17 @@ static INLINE int aom_daala_reader_has_error(daala_reader *r) {
static INLINE int daala_read_symbol(daala_reader *r, const aom_cdf_prob *cdf, static INLINE int daala_read_symbol(daala_reader *r, const aom_cdf_prob *cdf,
int nsymbs) { int nsymbs) {
int symb = od_ec_decode_cdf_q15(&r->ec, cdf, nsymbs); int symb;
#if CONFIG_EC_SMALLMUL
{
aom_cdf_prob icdf[16];
int i;
for (i = 0; i < nsymbs; i++) icdf[i] = OD_ICDF(cdf[i]);
symb = od_ec_decode_cdf_q15(&r->ec, icdf, nsymbs);
}
#else
symb = od_ec_decode_cdf_q15(&r->ec, cdf, nsymbs);
#endif
#if CONFIG_BITSTREAM_DEBUG #if CONFIG_BITSTREAM_DEBUG
{ {
......
...@@ -148,24 +148,25 @@ void od_ec_dec_init(od_ec_dec *dec, const unsigned char *buf, ...@@ -148,24 +148,25 @@ void od_ec_dec_init(od_ec_dec *dec, const unsigned char *buf,
od_ec_dec_refill(dec); od_ec_dec_refill(dec);
} }
/*Decode a bit that has an fz probability of being a zero in Q15. /*Decode a single binary value.
fz: The probability that the bit is zero, scaled by 32768. {EC_SMALLMUL} f: The probability that the bit is one, scaled by 32768.
{else} f: The probability that the bit is zero, scaled by 32768.
Return: The value decoded (0 or 1).*/ Return: The value decoded (0 or 1).*/
int od_ec_decode_bool_q15(od_ec_dec *dec, unsigned fz) { int od_ec_decode_bool_q15(od_ec_dec *dec, unsigned f) {
od_ec_window dif; od_ec_window dif;
od_ec_window vw; od_ec_window vw;
unsigned r; unsigned r;
unsigned r_new; unsigned r_new;
unsigned v; unsigned v;
int ret; int ret;
OD_ASSERT(0 < fz); OD_ASSERT(0 < f);
OD_ASSERT(fz < 32768U); OD_ASSERT(f < 32768U);
dif = dec->dif; dif = dec->dif;
r = dec->rng; r = dec->rng;
OD_ASSERT(dif >> (OD_EC_WINDOW_SIZE - 16) < r); OD_ASSERT(dif >> (OD_EC_WINDOW_SIZE - 16) < r);
OD_ASSERT(32768U <= r); OD_ASSERT(32768U <= r);
#if CONFIG_EC_SMALLMUL #if CONFIG_EC_SMALLMUL
v = (r >> 8) * (uint32_t)(32768U - fz) >> 7; v = (r >> 8) * (uint32_t)f >> 7;
vw = (od_ec_window)v << (OD_EC_WINDOW_SIZE - 16); vw = (od_ec_window)v << (OD_EC_WINDOW_SIZE - 16);
ret = 1; ret = 1;
r_new = v; r_new = v;
...@@ -175,7 +176,7 @@ int od_ec_decode_bool_q15(od_ec_dec *dec, unsigned fz) { ...@@ -175,7 +176,7 @@ int od_ec_decode_bool_q15(od_ec_dec *dec, unsigned fz) {
ret = 0; ret = 0;
} }
#else #else
v = fz * (uint32_t)r >> 15; v = f * (uint32_t)r >> 15;
vw = (od_ec_window)v << (OD_EC_WINDOW_SIZE - 16); vw = (od_ec_window)v << (OD_EC_WINDOW_SIZE - 16);
ret = 0; ret = 0;
r_new = v; r_new = v;
...@@ -193,6 +194,7 @@ int od_ec_decode_bool_q15(od_ec_dec *dec, unsigned fz) { ...@@ -193,6 +194,7 @@ int od_ec_decode_bool_q15(od_ec_dec *dec, unsigned fz) {
[s > 0 ? cdf[s - 1] : 0, cdf[s]). [s > 0 ? cdf[s - 1] : 0, cdf[s]).
The values must be monotonically non-increasing, and cdf[nsyms - 1] The values must be monotonically non-increasing, and cdf[nsyms - 1]
must be 32768. must be 32768.
{EC_SMALLMUL}: The CDF contains 32768 minus those values.
nsyms: The number of symbols in the alphabet. nsyms: The number of symbols in the alphabet.
This should be at most 16. This should be at most 16.
Return: The decoded symbol s.*/ Return: The decoded symbol s.*/
...@@ -207,7 +209,7 @@ int od_ec_decode_cdf_q15(od_ec_dec *dec, const uint16_t *cdf, int nsyms) { ...@@ -207,7 +209,7 @@ int od_ec_decode_cdf_q15(od_ec_dec *dec, const uint16_t *cdf, int nsyms) {
dif = dec->dif; dif = dec->dif;
r = dec->rng; r = dec->rng;
OD_ASSERT(dif >> (OD_EC_WINDOW_SIZE - 16) < r); OD_ASSERT(dif >> (OD_EC_WINDOW_SIZE - 16) < r);
OD_ASSERT(cdf[nsyms - 1] == 32768U); OD_ASSERT(cdf[nsyms - 1] == OD_ICDF(32768U));
OD_ASSERT(32768U <= r); OD_ASSERT(32768U <= r);
#if CONFIG_EC_SMALLMUL #if CONFIG_EC_SMALLMUL
c = (unsigned)(dif >> (OD_EC_WINDOW_SIZE - 16)); c = (unsigned)(dif >> (OD_EC_WINDOW_SIZE - 16));
...@@ -215,7 +217,7 @@ int od_ec_decode_cdf_q15(od_ec_dec *dec, const uint16_t *cdf, int nsyms) { ...@@ -215,7 +217,7 @@ int od_ec_decode_cdf_q15(od_ec_dec *dec, const uint16_t *cdf, int nsyms) {
ret = -1; ret = -1;
do { do {
u = v; u = v;
v = (r >> 8) * (uint32_t)(32768U - cdf[++ret]) >> 7; v = (r >> 8) * (uint32_t)cdf[++ret] >> 7;
} while (c < v); } while (c < v);
OD_ASSERT(v < u); OD_ASSERT(v < u);
OD_ASSERT(u <= r); OD_ASSERT(u <= r);
......
...@@ -70,7 +70,7 @@ struct od_ec_dec { ...@@ -70,7 +70,7 @@ struct od_ec_dec {
void od_ec_dec_init(od_ec_dec *dec, const unsigned char *buf, uint32_t storage) void od_ec_dec_init(od_ec_dec *dec, const unsigned char *buf, uint32_t storage)
OD_ARG_NONNULL(1) OD_ARG_NONNULL(2); OD_ARG_NONNULL(1) OD_ARG_NONNULL(2);
OD_WARN_UNUSED_RESULT int od_ec_decode_bool_q15(od_ec_dec *dec, unsigned fz) OD_WARN_UNUSED_RESULT int od_ec_decode_bool_q15(od_ec_dec *dec, unsigned f)
OD_ARG_NONNULL(1); OD_ARG_NONNULL(1);
OD_WARN_UNUSED_RESULT int od_ec_decode_cdf_q15(od_ec_dec *dec, OD_WARN_UNUSED_RESULT int od_ec_decode_cdf_q15(od_ec_dec *dec,
const uint16_t *cdf, int nsyms) const uint16_t *cdf, int nsyms)
......
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