Refactor the entropy coder.
This unifies the byte buffer, encoder, and decoder into a single
struct.
The common encoder and decoder functions (such as ec_tell()) can
operate on either one, simplifying code which uses both.
The precision argument to ec_tell() has been removed.
It now comes in two precisions:
ec_tell() gives 1 bit precision in two operations, and
ec_tell_frac() gives 1/8th bit precision in... somewhat more.
ec_{enc|dec}_bit_prob() were removed (they are no longer needed).
Some of the byte buffer access functions were made static and
removed from the cross-module API.
All of the code in rangeenc.c and rangedec.c was merged into
entenc.c and entdec.c, respectively, as we are no longer
considering alternative backends.
rangeenc.c and rangede.c have been removed entirely.
This passes make check, after disabling the modes that we removed
support for in cf5d3a8c
.
This commit is contained in:
parent
ef986e4421
commit
a093f4df74
19 changed files with 671 additions and 887 deletions
|
@ -16,8 +16,7 @@ lib_LTLIBRARIES = libcelt@LIBCELT_SUFFIX@.la
|
||||||
# Sources for compilation in the library
|
# Sources for compilation in the library
|
||||||
libcelt@LIBCELT_SUFFIX@_la_SOURCES = bands.c celt.c cwrs.c ecintrin.h entcode.c \
|
libcelt@LIBCELT_SUFFIX@_la_SOURCES = bands.c celt.c cwrs.c ecintrin.h entcode.c \
|
||||||
entdec.c entenc.c header.c kiss_fft.c laplace.c mathops.c mdct.c \
|
entdec.c entenc.c header.c kiss_fft.c laplace.c mathops.c mdct.c \
|
||||||
modes.c pitch.c plc.c quant_bands.c rangedec.c rangeenc.c rate.c \
|
modes.c pitch.c plc.c quant_bands.c rate.c vq.c
|
||||||
vq.c
|
|
||||||
|
|
||||||
libcelt@LIBCELT_SUFFIX@_la_LDFLAGS = \
|
libcelt@LIBCELT_SUFFIX@_la_LDFLAGS = \
|
||||||
-version-info @CELT_LT_CURRENT@:@CELT_LT_REVISION@:@CELT_LT_AGE@ \
|
-version-info @CELT_LT_CURRENT@:@CELT_LT_REVISION@:@CELT_LT_AGE@ \
|
||||||
|
|
|
@ -636,7 +636,7 @@ static int compute_qn(int N, int b, int offset, int pulse_cap, int stereo)
|
||||||
in two and transmit the energy difference with the two half-bands. It
|
in two and transmit the energy difference with the two half-bands. It
|
||||||
can be called recursively so bands can end up being split in 8 parts. */
|
can be called recursively so bands can end up being split in 8 parts. */
|
||||||
static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_norm *Y,
|
static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_norm *Y,
|
||||||
int N, int b, int spread, int B, int intensity, int tf_change, celt_norm *lowband, int resynth, void *ec,
|
int N, int b, int spread, int B, int intensity, int tf_change, celt_norm *lowband, int resynth, ec_ctx *ec,
|
||||||
celt_int32 *remaining_bits, int LM, celt_norm *lowband_out, const celt_ener *bandE, int level,
|
celt_int32 *remaining_bits, int LM, celt_norm *lowband_out, const celt_ener *bandE, int level,
|
||||||
celt_uint32 *seed, celt_word16 gain, celt_norm *lowband_scratch, int fill)
|
celt_uint32 *seed, celt_word16 gain, celt_norm *lowband_scratch, int fill)
|
||||||
{
|
{
|
||||||
|
@ -675,9 +675,9 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
|
||||||
if (encode)
|
if (encode)
|
||||||
{
|
{
|
||||||
sign = x[0]<0;
|
sign = x[0]<0;
|
||||||
ec_enc_bits((ec_enc*)ec, sign, 1);
|
ec_enc_bits(ec, sign, 1);
|
||||||
} else {
|
} else {
|
||||||
sign = ec_dec_bits((ec_dec*)ec, 1);
|
sign = ec_dec_bits(ec, 1);
|
||||||
}
|
}
|
||||||
*remaining_bits -= 1<<BITRES;
|
*remaining_bits -= 1<<BITRES;
|
||||||
b-=1<<BITRES;
|
b-=1<<BITRES;
|
||||||
|
@ -787,7 +787,7 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
|
||||||
2) they are orthogonal. */
|
2) they are orthogonal. */
|
||||||
itheta = stereo_itheta(X, Y, stereo, N);
|
itheta = stereo_itheta(X, Y, stereo, N);
|
||||||
}
|
}
|
||||||
tell = encode ? ec_enc_tell(ec, BITRES) : ec_dec_tell(ec, BITRES);
|
tell = ec_tell_frac(ec);
|
||||||
if (qn!=1)
|
if (qn!=1)
|
||||||
{
|
{
|
||||||
if (encode)
|
if (encode)
|
||||||
|
@ -804,7 +804,7 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
|
||||||
/* Use a probability of p0 up to itheta=8192 and then use 1 after */
|
/* Use a probability of p0 up to itheta=8192 and then use 1 after */
|
||||||
if (encode)
|
if (encode)
|
||||||
{
|
{
|
||||||
ec_encode((ec_enc*)ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft);
|
ec_encode(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft);
|
||||||
} else {
|
} else {
|
||||||
int fs;
|
int fs;
|
||||||
fs=ec_decode(ec,ft);
|
fs=ec_decode(ec,ft);
|
||||||
|
@ -818,9 +818,9 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
|
||||||
} else if (B0>1 || stereo) {
|
} else if (B0>1 || stereo) {
|
||||||
/* Uniform pdf */
|
/* Uniform pdf */
|
||||||
if (encode)
|
if (encode)
|
||||||
ec_enc_uint((ec_enc*)ec, itheta, qn+1);
|
ec_enc_uint(ec, itheta, qn+1);
|
||||||
else
|
else
|
||||||
itheta = ec_dec_uint((ec_dec*)ec, qn+1);
|
itheta = ec_dec_uint(ec, qn+1);
|
||||||
} else {
|
} else {
|
||||||
int fs=1, ft;
|
int fs=1, ft;
|
||||||
ft = ((qn>>1)+1)*((qn>>1)+1);
|
ft = ((qn>>1)+1)*((qn>>1)+1);
|
||||||
|
@ -832,12 +832,12 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
|
||||||
fl = itheta <= (qn>>1) ? itheta*(itheta + 1)>>1 :
|
fl = itheta <= (qn>>1) ? itheta*(itheta + 1)>>1 :
|
||||||
ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1);
|
ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1);
|
||||||
|
|
||||||
ec_encode((ec_enc*)ec, fl, fl+fs, ft);
|
ec_encode(ec, fl, fl+fs, ft);
|
||||||
} else {
|
} else {
|
||||||
/* Triangular pdf */
|
/* Triangular pdf */
|
||||||
int fl=0;
|
int fl=0;
|
||||||
int fm;
|
int fm;
|
||||||
fm = ec_decode((ec_dec*)ec, ft);
|
fm = ec_decode(ec, ft);
|
||||||
|
|
||||||
if (fm < ((qn>>1)*((qn>>1) + 1)>>1))
|
if (fm < ((qn>>1)*((qn>>1) + 1)>>1))
|
||||||
{
|
{
|
||||||
|
@ -853,7 +853,7 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
|
||||||
fl = ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1);
|
fl = ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ec_dec_update((ec_dec*)ec, fl, fl+fs, ft);
|
ec_dec_update(ec, fl, fl+fs, ft);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
itheta = (celt_int32)itheta*16384/qn;
|
itheta = (celt_int32)itheta*16384/qn;
|
||||||
|
@ -888,8 +888,7 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
|
||||||
inv = 0;
|
inv = 0;
|
||||||
itheta = 0;
|
itheta = 0;
|
||||||
}
|
}
|
||||||
qalloc = (encode ? ec_enc_tell(ec, BITRES) : ec_dec_tell(ec, BITRES))
|
qalloc = ec_tell_frac(ec) - tell;
|
||||||
- tell;
|
|
||||||
b -= qalloc;
|
b -= qalloc;
|
||||||
|
|
||||||
orig_fill = fill;
|
orig_fill = fill;
|
||||||
|
@ -946,9 +945,9 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
|
||||||
{
|
{
|
||||||
/* Here we only need to encode a sign for the side */
|
/* Here we only need to encode a sign for the side */
|
||||||
sign = x2[0]*y2[1] - x2[1]*y2[0] < 0;
|
sign = x2[0]*y2[1] - x2[1]*y2[0] < 0;
|
||||||
ec_enc_bits((ec_enc*)ec, sign, 1);
|
ec_enc_bits(ec, sign, 1);
|
||||||
} else {
|
} else {
|
||||||
sign = ec_dec_bits((ec_dec*)ec, 1);
|
sign = ec_dec_bits(ec, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sign = 1-2*sign;
|
sign = 1-2*sign;
|
||||||
|
@ -1059,9 +1058,9 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
|
||||||
|
|
||||||
/* Finally do the actual quantization */
|
/* Finally do the actual quantization */
|
||||||
if (encode)
|
if (encode)
|
||||||
cm = alg_quant(X, N, K, spread, B, resynth, (ec_enc*)ec, gain);
|
cm = alg_quant(X, N, K, spread, B, resynth, ec, gain);
|
||||||
else
|
else
|
||||||
cm = alg_unquant(X, N, K, spread, B, (ec_dec*)ec, gain);
|
cm = alg_unquant(X, N, K, spread, B, ec, gain);
|
||||||
} else {
|
} else {
|
||||||
/* If there's no pulse, fill the band anyway */
|
/* If there's no pulse, fill the band anyway */
|
||||||
int j;
|
int j;
|
||||||
|
@ -1160,7 +1159,7 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
|
||||||
void quant_all_bands(int encode, const CELTMode *m, int start, int end,
|
void quant_all_bands(int encode, const CELTMode *m, int start, int end,
|
||||||
celt_norm *_X, celt_norm *_Y, unsigned char *collapse_masks, const celt_ener *bandE, int *pulses,
|
celt_norm *_X, celt_norm *_Y, unsigned char *collapse_masks, const celt_ener *bandE, int *pulses,
|
||||||
int shortBlocks, int spread, int dual_stereo, int intensity, int *tf_res, int resynth,
|
int shortBlocks, int spread, int dual_stereo, int intensity, int *tf_res, int resynth,
|
||||||
celt_int32 total_bits, celt_int32 balance, void *ec, int LM, int codedBands, ec_uint32 *seed)
|
celt_int32 total_bits, celt_int32 balance, ec_ctx *ec, int LM, int codedBands, ec_uint32 *seed)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
celt_int32 remaining_bits;
|
celt_int32 remaining_bits;
|
||||||
|
@ -1201,10 +1200,7 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
|
||||||
else
|
else
|
||||||
Y = NULL;
|
Y = NULL;
|
||||||
N = M*eBands[i+1]-M*eBands[i];
|
N = M*eBands[i+1]-M*eBands[i];
|
||||||
if (encode)
|
tell = ec_tell_frac(ec);
|
||||||
tell = ec_enc_tell((ec_enc*)ec, BITRES);
|
|
||||||
else
|
|
||||||
tell = ec_dec_tell((ec_dec*)ec, BITRES);
|
|
||||||
|
|
||||||
/* Compute how many bits we want to allocate to this band */
|
/* Compute how many bits we want to allocate to this band */
|
||||||
if (i != start)
|
if (i != start)
|
||||||
|
|
|
@ -88,7 +88,7 @@ void haar1(celt_norm *X, int N0, int stride);
|
||||||
void quant_all_bands(int encode, const CELTMode *m, int start, int end,
|
void quant_all_bands(int encode, const CELTMode *m, int start, int end,
|
||||||
celt_norm * X, celt_norm * Y, unsigned char *collapse_masks, const celt_ener *bandE, int *pulses,
|
celt_norm * X, celt_norm * Y, unsigned char *collapse_masks, const celt_ener *bandE, int *pulses,
|
||||||
int time_domain, int fold, int dual_stereo, int intensity, int *tf_res, int resynth,
|
int time_domain, int fold, int dual_stereo, int intensity, int *tf_res, int resynth,
|
||||||
celt_int32 total_bits, celt_int32 balance, void *enc, int M, int codedBands, ec_uint32 *seed);
|
celt_int32 total_bits, celt_int32 balance, ec_ctx *ec, int M, int codedBands, ec_uint32 *seed);
|
||||||
|
|
||||||
|
|
||||||
void stereo_decision(const CELTMode *m, celt_norm * restrict X, int *stereo_mode, int len, int M);
|
void stereo_decision(const CELTMode *m, celt_norm * restrict X, int *stereo_mode, int len, int M);
|
||||||
|
|
|
@ -691,8 +691,8 @@ static void tf_encode(int start, int end, int isTransient, int *tf_res, int LM,
|
||||||
int logp;
|
int logp;
|
||||||
ec_uint32 budget;
|
ec_uint32 budget;
|
||||||
ec_uint32 tell;
|
ec_uint32 tell;
|
||||||
budget = enc->buf->storage*8;
|
budget = enc->storage*8;
|
||||||
tell = ec_enc_tell(enc, 0);
|
tell = ec_tell(enc);
|
||||||
logp = isTransient ? 2 : 4;
|
logp = isTransient ? 2 : 4;
|
||||||
/* Reserve space to code the tf_select decision. */
|
/* Reserve space to code the tf_select decision. */
|
||||||
tf_select_rsv = LM>0 && tell+logp+1 <= budget;
|
tf_select_rsv = LM>0 && tell+logp+1 <= budget;
|
||||||
|
@ -703,7 +703,7 @@ static void tf_encode(int start, int end, int isTransient, int *tf_res, int LM,
|
||||||
if (tell+logp<=budget)
|
if (tell+logp<=budget)
|
||||||
{
|
{
|
||||||
ec_enc_bit_logp(enc, tf_res[i] ^ curr, logp);
|
ec_enc_bit_logp(enc, tf_res[i] ^ curr, logp);
|
||||||
tell = ec_enc_tell(enc, 0);
|
tell = ec_tell(enc);
|
||||||
curr = tf_res[i];
|
curr = tf_res[i];
|
||||||
tf_changed |= curr;
|
tf_changed |= curr;
|
||||||
}
|
}
|
||||||
|
@ -732,8 +732,8 @@ static void tf_decode(int start, int end, int isTransient, int *tf_res, int LM,
|
||||||
ec_uint32 budget;
|
ec_uint32 budget;
|
||||||
ec_uint32 tell;
|
ec_uint32 tell;
|
||||||
|
|
||||||
budget = dec->buf->storage*8;
|
budget = dec->storage*8;
|
||||||
tell = ec_dec_tell(dec, 0);
|
tell = ec_tell(dec);
|
||||||
logp = isTransient ? 2 : 4;
|
logp = isTransient ? 2 : 4;
|
||||||
tf_select_rsv = LM>0 && tell+logp+1<=budget;
|
tf_select_rsv = LM>0 && tell+logp+1<=budget;
|
||||||
budget -= tf_select_rsv;
|
budget -= tf_select_rsv;
|
||||||
|
@ -743,7 +743,7 @@ static void tf_decode(int start, int end, int isTransient, int *tf_res, int LM,
|
||||||
if (tell+logp<=budget)
|
if (tell+logp<=budget)
|
||||||
{
|
{
|
||||||
curr ^= ec_dec_bit_logp(dec, logp);
|
curr ^= ec_dec_bit_logp(dec, logp);
|
||||||
tell = ec_dec_tell(dec, 0);
|
tell = ec_tell(dec);
|
||||||
tf_changed |= curr;
|
tf_changed |= curr;
|
||||||
}
|
}
|
||||||
tf_res[i] = curr;
|
tf_res[i] = curr;
|
||||||
|
@ -871,7 +871,6 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
#endif
|
#endif
|
||||||
int i, c, N;
|
int i, c, N;
|
||||||
int bits;
|
int bits;
|
||||||
ec_byte_buffer buf;
|
|
||||||
ec_enc _enc;
|
ec_enc _enc;
|
||||||
VARDECL(celt_sig, in);
|
VARDECL(celt_sig, in);
|
||||||
VARDECL(celt_sig, freq);
|
VARDECL(celt_sig, freq);
|
||||||
|
@ -944,7 +943,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
tell=1;
|
tell=1;
|
||||||
nbFilledBytes=0;
|
nbFilledBytes=0;
|
||||||
} else {
|
} else {
|
||||||
tell=ec_enc_tell(enc, 0);
|
tell=ec_tell(enc);
|
||||||
nbFilledBytes=(tell+4)>>3;
|
nbFilledBytes=(tell+4)>>3;
|
||||||
}
|
}
|
||||||
nbAvailableBytes = nbCompressedBytes - nbFilledBytes;
|
nbAvailableBytes = nbCompressedBytes - nbFilledBytes;
|
||||||
|
@ -966,8 +965,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
|
|
||||||
if (enc==NULL)
|
if (enc==NULL)
|
||||||
{
|
{
|
||||||
ec_byte_writeinit_buffer(&buf, compressed, nbCompressedBytes);
|
ec_enc_init(&_enc, compressed, nbCompressedBytes);
|
||||||
ec_enc_init(&_enc,&buf);
|
|
||||||
enc = &_enc;
|
enc = &_enc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -993,7 +991,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
{
|
{
|
||||||
nbCompressedBytes = nbFilledBytes+max_allowed;
|
nbCompressedBytes = nbFilledBytes+max_allowed;
|
||||||
nbAvailableBytes = max_allowed;
|
nbAvailableBytes = max_allowed;
|
||||||
ec_byte_shrink(enc->buf, nbCompressedBytes);
|
ec_enc_shrink(enc, nbCompressedBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1058,12 +1056,12 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
effectiveBytes=nbCompressedBytes=IMIN(nbCompressedBytes, nbFilledBytes+2);
|
effectiveBytes=nbCompressedBytes=IMIN(nbCompressedBytes, nbFilledBytes+2);
|
||||||
total_bits=nbCompressedBytes*8;
|
total_bits=nbCompressedBytes*8;
|
||||||
nbAvailableBytes=2;
|
nbAvailableBytes=2;
|
||||||
ec_byte_shrink(enc->buf, nbCompressedBytes);
|
ec_enc_shrink(enc, nbCompressedBytes);
|
||||||
}
|
}
|
||||||
/* Pretend we've filled all the remaining bits with zeros
|
/* Pretend we've filled all the remaining bits with zeros
|
||||||
(that's what the initialiser did anyway) */
|
(that's what the initialiser did anyway) */
|
||||||
tell = nbCompressedBytes*8;
|
tell = nbCompressedBytes*8;
|
||||||
enc->nbits_total+=tell-ec_enc_tell(enc,0);
|
enc->nbits_total+=tell-ec_tell(enc);
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_POSTFILTER
|
#ifdef ENABLE_POSTFILTER
|
||||||
if (nbAvailableBytes>12*C && st->start==0 && !silence && !st->disable_pf && st->complexity >= 5)
|
if (nbAvailableBytes>12*C && st->start==0 && !silence && !st->disable_pf && st->complexity >= 5)
|
||||||
|
@ -1131,7 +1129,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
ec_enc_bits(enc, pitch_index-(16<<octave), 4+octave);
|
ec_enc_bits(enc, pitch_index-(16<<octave), 4+octave);
|
||||||
pitch_index -= 1;
|
pitch_index -= 1;
|
||||||
ec_enc_bits(enc, qg, 3);
|
ec_enc_bits(enc, qg, 3);
|
||||||
if (ec_enc_tell(enc, 0)+2<=total_bits)
|
if (ec_tell(enc)+2<=total_bits)
|
||||||
ec_enc_icdf(enc, prefilter_tapset, tapset_icdf, 2);
|
ec_enc_icdf(enc, prefilter_tapset, tapset_icdf, 2);
|
||||||
else
|
else
|
||||||
prefilter_tapset = 0;
|
prefilter_tapset = 0;
|
||||||
|
@ -1177,7 +1175,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
|
|
||||||
isTransient = 0;
|
isTransient = 0;
|
||||||
shortBlocks = 0;
|
shortBlocks = 0;
|
||||||
if (LM>0 && ec_enc_tell(enc, 0)+3<=total_bits)
|
if (LM>0 && ec_tell(enc)+3<=total_bits)
|
||||||
{
|
{
|
||||||
if (st->complexity > 1)
|
if (st->complexity > 1)
|
||||||
{
|
{
|
||||||
|
@ -1235,7 +1233,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
tf_encode(st->start, st->end, isTransient, tf_res, LM, tf_select, enc);
|
tf_encode(st->start, st->end, isTransient, tf_res, LM, tf_select, enc);
|
||||||
|
|
||||||
st->spread_decision = SPREAD_NORMAL;
|
st->spread_decision = SPREAD_NORMAL;
|
||||||
if (ec_enc_tell(enc, 0)+4<=total_bits)
|
if (ec_tell(enc)+4<=total_bits)
|
||||||
{
|
{
|
||||||
if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C)
|
if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C)
|
||||||
{
|
{
|
||||||
|
@ -1284,7 +1282,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
dynalloc_logp = 6;
|
dynalloc_logp = 6;
|
||||||
total_bits<<=BITRES;
|
total_bits<<=BITRES;
|
||||||
total_boost = 0;
|
total_boost = 0;
|
||||||
tell = ec_enc_tell(enc, BITRES);
|
tell = ec_tell_frac(enc);
|
||||||
for (i=st->start;i<st->end;i++)
|
for (i=st->start;i<st->end;i++)
|
||||||
{
|
{
|
||||||
int width, quanta;
|
int width, quanta;
|
||||||
|
@ -1303,7 +1301,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
int flag;
|
int flag;
|
||||||
flag = j<offsets[i];
|
flag = j<offsets[i];
|
||||||
ec_enc_bit_logp(enc, flag, dynalloc_loop_logp);
|
ec_enc_bit_logp(enc, flag, dynalloc_loop_logp);
|
||||||
tell = ec_enc_tell(enc, BITRES);
|
tell = ec_tell_frac(enc);
|
||||||
if (!flag)
|
if (!flag)
|
||||||
break;
|
break;
|
||||||
boost += quanta;
|
boost += quanta;
|
||||||
|
@ -1321,7 +1319,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
alloc_trim = alloc_trim_analysis(st->mode, X, bandLogE,
|
alloc_trim = alloc_trim_analysis(st->mode, X, bandLogE,
|
||||||
st->mode->nbEBands, LM, C, N);
|
st->mode->nbEBands, LM, C, N);
|
||||||
ec_enc_icdf(enc, alloc_trim, trim_icdf, 7);
|
ec_enc_icdf(enc, alloc_trim, trim_icdf, 7);
|
||||||
tell = ec_enc_tell(enc, BITRES);
|
tell = ec_tell_frac(enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Variable bitrate */
|
/* Variable bitrate */
|
||||||
|
@ -1396,7 +1394,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
}
|
}
|
||||||
nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes);
|
nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes);
|
||||||
/* This moves the raw bits to take into account the new compressed size */
|
/* This moves the raw bits to take into account the new compressed size */
|
||||||
ec_byte_shrink(enc->buf, nbCompressedBytes);
|
ec_enc_shrink(enc, nbCompressedBytes);
|
||||||
}
|
}
|
||||||
if (C==2)
|
if (C==2)
|
||||||
{
|
{
|
||||||
|
@ -1434,7 +1432,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
ALLOC(fine_priority, st->mode->nbEBands, int);
|
ALLOC(fine_priority, st->mode->nbEBands, int);
|
||||||
|
|
||||||
/* bits = packet size - where we are - safety*/
|
/* bits = packet size - where we are - safety*/
|
||||||
bits = (nbCompressedBytes*8<<BITRES) - ec_enc_tell(enc, BITRES) - 1;
|
bits = (nbCompressedBytes*8<<BITRES) - ec_tell_frac(enc) - 1;
|
||||||
anti_collapse_rsv = isTransient&&LM>=2&&bits>=(LM+2<<BITRES) ? (1<<BITRES) : 0;
|
anti_collapse_rsv = isTransient&&LM>=2&&bits>=(LM+2<<BITRES) ? (1<<BITRES) : 0;
|
||||||
bits -= anti_collapse_rsv;
|
bits -= anti_collapse_rsv;
|
||||||
codedBands = compute_allocation(st->mode, st->start, st->end, offsets, cap,
|
codedBands = compute_allocation(st->mode, st->start, st->end, offsets, cap,
|
||||||
|
@ -1466,7 +1464,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
anti_collapse_on = st->consec_transient<2;
|
anti_collapse_on = st->consec_transient<2;
|
||||||
ec_enc_bits(enc, anti_collapse_on, 1);
|
ec_enc_bits(enc, anti_collapse_on, 1);
|
||||||
}
|
}
|
||||||
quant_energy_finalise(st->mode, st->start, st->end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_enc_tell(enc, 0), enc, C);
|
quant_energy_finalise(st->mode, st->start, st->end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_tell(enc), enc, C);
|
||||||
|
|
||||||
if (silence)
|
if (silence)
|
||||||
{
|
{
|
||||||
|
@ -1594,7 +1592,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
ec_enc_done(enc);
|
ec_enc_done(enc);
|
||||||
|
|
||||||
RESTORE_STACK;
|
RESTORE_STACK;
|
||||||
if (ec_enc_get_error(enc))
|
if (ec_get_error(enc))
|
||||||
return CELT_CORRUPTED_DATA;
|
return CELT_CORRUPTED_DATA;
|
||||||
else
|
else
|
||||||
return nbCompressedBytes;
|
return nbCompressedBytes;
|
||||||
|
@ -2135,7 +2133,6 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
int spread_decision;
|
int spread_decision;
|
||||||
int bits;
|
int bits;
|
||||||
ec_dec _dec;
|
ec_dec _dec;
|
||||||
ec_byte_buffer buf;
|
|
||||||
VARDECL(celt_sig, freq);
|
VARDECL(celt_sig, freq);
|
||||||
VARDECL(celt_norm, X);
|
VARDECL(celt_norm, X);
|
||||||
VARDECL(celt_ener, bandE);
|
VARDECL(celt_ener, bandE);
|
||||||
|
@ -2230,8 +2227,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
|
|
||||||
if (dec == NULL)
|
if (dec == NULL)
|
||||||
{
|
{
|
||||||
ec_byte_readinit(&buf,(unsigned char*)data,len);
|
ec_dec_init(&_dec,(unsigned char*)data,len);
|
||||||
ec_dec_init(&_dec,&buf);
|
|
||||||
dec = &_dec;
|
dec = &_dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2246,7 +2242,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
}
|
}
|
||||||
|
|
||||||
total_bits = len*8;
|
total_bits = len*8;
|
||||||
tell = ec_dec_tell(dec, 0);
|
tell = ec_tell(dec);
|
||||||
|
|
||||||
if (tell==1)
|
if (tell==1)
|
||||||
silence = ec_dec_bit_logp(dec, 15);
|
silence = ec_dec_bit_logp(dec, 15);
|
||||||
|
@ -2256,7 +2252,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
{
|
{
|
||||||
/* Pretend we've read all the remaining bits */
|
/* Pretend we've read all the remaining bits */
|
||||||
tell = len*8;
|
tell = len*8;
|
||||||
dec->nbits_total+=tell-ec_dec_tell(dec,0);
|
dec->nbits_total+=tell-ec_tell(dec);
|
||||||
}
|
}
|
||||||
|
|
||||||
postfilter_gain = 0;
|
postfilter_gain = 0;
|
||||||
|
@ -2271,7 +2267,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
octave = ec_dec_uint(dec, 6);
|
octave = ec_dec_uint(dec, 6);
|
||||||
postfilter_pitch = (16<<octave)+ec_dec_bits(dec, 4+octave)-1;
|
postfilter_pitch = (16<<octave)+ec_dec_bits(dec, 4+octave)-1;
|
||||||
qg = ec_dec_bits(dec, 3);
|
qg = ec_dec_bits(dec, 3);
|
||||||
if (ec_dec_tell(dec, 0)+2<=total_bits)
|
if (ec_tell(dec)+2<=total_bits)
|
||||||
postfilter_tapset = ec_dec_icdf(dec, tapset_icdf, 2);
|
postfilter_tapset = ec_dec_icdf(dec, tapset_icdf, 2);
|
||||||
postfilter_gain = QCONST16(.09375f,15)*(qg+1);
|
postfilter_gain = QCONST16(.09375f,15)*(qg+1);
|
||||||
#else /* ENABLE_POSTFILTER */
|
#else /* ENABLE_POSTFILTER */
|
||||||
|
@ -2279,13 +2275,13 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
return CELT_CORRUPTED_DATA;
|
return CELT_CORRUPTED_DATA;
|
||||||
#endif /* ENABLE_POSTFILTER */
|
#endif /* ENABLE_POSTFILTER */
|
||||||
}
|
}
|
||||||
tell = ec_dec_tell(dec, 0);
|
tell = ec_tell(dec);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LM > 0 && tell+3 <= total_bits)
|
if (LM > 0 && tell+3 <= total_bits)
|
||||||
{
|
{
|
||||||
isTransient = ec_dec_bit_logp(dec, 3);
|
isTransient = ec_dec_bit_logp(dec, 3);
|
||||||
tell = ec_dec_tell(dec, 0);
|
tell = ec_tell(dec);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
isTransient = 0;
|
isTransient = 0;
|
||||||
|
@ -2304,7 +2300,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
ALLOC(tf_res, st->mode->nbEBands, int);
|
ALLOC(tf_res, st->mode->nbEBands, int);
|
||||||
tf_decode(st->start, st->end, isTransient, tf_res, LM, dec);
|
tf_decode(st->start, st->end, isTransient, tf_res, LM, dec);
|
||||||
|
|
||||||
tell = ec_dec_tell(dec, 0);
|
tell = ec_tell(dec);
|
||||||
spread_decision = SPREAD_NORMAL;
|
spread_decision = SPREAD_NORMAL;
|
||||||
if (tell+4 <= total_bits)
|
if (tell+4 <= total_bits)
|
||||||
spread_decision = ec_dec_icdf(dec, spread_icdf, 5);
|
spread_decision = ec_dec_icdf(dec, spread_icdf, 5);
|
||||||
|
@ -2318,7 +2314,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
|
|
||||||
dynalloc_logp = 6;
|
dynalloc_logp = 6;
|
||||||
total_bits<<=BITRES;
|
total_bits<<=BITRES;
|
||||||
tell = ec_dec_tell(dec, BITRES);
|
tell = ec_tell_frac(dec);
|
||||||
for (i=st->start;i<st->end;i++)
|
for (i=st->start;i<st->end;i++)
|
||||||
{
|
{
|
||||||
int width, quanta;
|
int width, quanta;
|
||||||
|
@ -2334,7 +2330,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
{
|
{
|
||||||
int flag;
|
int flag;
|
||||||
flag = ec_dec_bit_logp(dec, dynalloc_loop_logp);
|
flag = ec_dec_bit_logp(dec, dynalloc_loop_logp);
|
||||||
tell = ec_dec_tell(dec, BITRES);
|
tell = ec_tell_frac(dec);
|
||||||
if (!flag)
|
if (!flag)
|
||||||
break;
|
break;
|
||||||
boost += quanta;
|
boost += quanta;
|
||||||
|
@ -2351,7 +2347,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
alloc_trim = tell+(6<<BITRES) <= total_bits ?
|
alloc_trim = tell+(6<<BITRES) <= total_bits ?
|
||||||
ec_dec_icdf(dec, trim_icdf, 7) : 5;
|
ec_dec_icdf(dec, trim_icdf, 7) : 5;
|
||||||
|
|
||||||
bits = (len*8<<BITRES) - ec_dec_tell(dec, BITRES) - 1;
|
bits = (len*8<<BITRES) - ec_tell_frac(dec) - 1;
|
||||||
anti_collapse_rsv = isTransient&&LM>=2&&bits>=(LM+2<<BITRES) ? (1<<BITRES) : 0;
|
anti_collapse_rsv = isTransient&&LM>=2&&bits>=(LM+2<<BITRES) ? (1<<BITRES) : 0;
|
||||||
bits -= anti_collapse_rsv;
|
bits -= anti_collapse_rsv;
|
||||||
codedBands = compute_allocation(st->mode, st->start, st->end, offsets, cap,
|
codedBands = compute_allocation(st->mode, st->start, st->end, offsets, cap,
|
||||||
|
@ -2372,7 +2368,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
}
|
}
|
||||||
|
|
||||||
unquant_energy_finalise(st->mode, st->start, st->end, oldBandE,
|
unquant_energy_finalise(st->mode, st->start, st->end, oldBandE,
|
||||||
fine_quant, fine_priority, len*8-ec_dec_tell(dec, 0), dec, C);
|
fine_quant, fine_priority, len*8-ec_tell(dec), dec, C);
|
||||||
|
|
||||||
if (anti_collapse_on)
|
if (anti_collapse_on)
|
||||||
anti_collapse(st->mode, X, collapse_masks, LM, C, CC, N,
|
anti_collapse(st->mode, X, collapse_masks, LM, C, CC, N,
|
||||||
|
@ -2476,7 +2472,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
deemphasis(out_syn, pcm, N, CC, st->downsample, st->mode->preemph, st->preemph_memD);
|
deemphasis(out_syn, pcm, N, CC, st->downsample, st->mode->preemph, st->preemph_memD);
|
||||||
st->loss_count = 0;
|
st->loss_count = 0;
|
||||||
RESTORE_STACK;
|
RESTORE_STACK;
|
||||||
if (ec_dec_tell(dec,0) > 8*len || ec_dec_get_error(dec))
|
if (ec_tell(dec) > 8*len || ec_get_error(dec))
|
||||||
return CELT_CORRUPTED_DATA;
|
return CELT_CORRUPTED_DATA;
|
||||||
else
|
else
|
||||||
return CELT_OK;
|
return CELT_OK;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2001-2008 Timothy B. Terriberry
|
/* Copyright (c) 2001-2011 Timothy B. Terriberry
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -37,14 +37,8 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(EC_CLZ)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int ec_ilog(ec_uint32 _v){
|
int ec_ilog(ec_uint32 _v){
|
||||||
#if defined(EC_CLZ)
|
|
||||||
return EC_CLZ0-EC_CLZ(_v);
|
|
||||||
#else
|
|
||||||
/*On a Pentium M, this branchless version tested as the fastest on
|
/*On a Pentium M, this branchless version tested as the fastest on
|
||||||
1,000,000,000 random 32-bit integers, edging out a similar version with
|
1,000,000,000 random 32-bit integers, edging out a similar version with
|
||||||
branches, and a 256-entry LUT version.*/
|
branches, and a 256-entry LUT version.*/
|
||||||
|
@ -65,6 +59,36 @@ int ec_ilog(ec_uint32 _v){
|
||||||
ret|=m;
|
ret|=m;
|
||||||
ret+=!!(_v&0x2);
|
ret+=!!(_v&0x2);
|
||||||
return ret;
|
return ret;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
ec_uint32 ec_tell_frac(ec_ctx *_this){
|
||||||
|
ec_uint32 nbits;
|
||||||
|
ec_uint32 r;
|
||||||
|
int l;
|
||||||
|
int i;
|
||||||
|
/*To handle the non-integral number of bits still left in the encoder/decoder
|
||||||
|
state, we compute the worst-case number of bits of val that must be
|
||||||
|
encoded to ensure that the value is inside the range for any possible
|
||||||
|
subsequent bits.
|
||||||
|
The computation here is independent of val itself (the decoder does not
|
||||||
|
even track that value), even though the real number of bits used after
|
||||||
|
ec_enc_done() may be 1 smaller if rng is a power of two and the
|
||||||
|
corresponding trailing bits of val are all zeros.
|
||||||
|
If we did try to track that special case, then coding a value with a
|
||||||
|
probability of 1/(1<<n) might sometimes appear to use more than n bits.
|
||||||
|
This may help explain the surprising result that a newly initialized
|
||||||
|
encoder or decoder claims to have used 1 bit.*/
|
||||||
|
nbits=_this->nbits_total<<BITRES;
|
||||||
|
l=EC_ILOG(_this->rng);
|
||||||
|
r=_this->rng>>l-16;
|
||||||
|
for(i=BITRES;i-->0;){
|
||||||
|
int b;
|
||||||
|
r=r*r>>15;
|
||||||
|
b=(int)(r>>16);
|
||||||
|
l=l<<1|b;
|
||||||
|
r>>=b;
|
||||||
|
}
|
||||||
|
return nbits-l;
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2001-2008 Timothy B. Terriberry
|
/* Copyright (c) 2001-2011 Timothy B. Terriberry
|
||||||
Copyright (c) 2008-2009 Xiph.Org Foundation */
|
Copyright (c) 2008-2009 Xiph.Org Foundation */
|
||||||
/*
|
/*
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -42,7 +42,9 @@
|
||||||
typedef celt_int32 ec_int32;
|
typedef celt_int32 ec_int32;
|
||||||
typedef celt_uint32 ec_uint32;
|
typedef celt_uint32 ec_uint32;
|
||||||
typedef size_t ec_window;
|
typedef size_t ec_window;
|
||||||
typedef struct ec_byte_buffer ec_byte_buffer;
|
typedef struct ec_ctx ec_ctx;
|
||||||
|
typedef struct ec_ctx ec_enc;
|
||||||
|
typedef struct ec_ctx ec_dec;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,40 +54,82 @@ typedef struct ec_byte_buffer ec_byte_buffer;
|
||||||
/*The number of bits to use for the range-coded part of unsigned integers.*/
|
/*The number of bits to use for the range-coded part of unsigned integers.*/
|
||||||
# define EC_UINT_BITS (8)
|
# define EC_UINT_BITS (8)
|
||||||
|
|
||||||
|
/*The resolution of fractional-precision bit usage measurements, i.e.,
|
||||||
|
3 => 1/8th bits.*/
|
||||||
|
# define BITRES 3
|
||||||
|
|
||||||
|
|
||||||
/*Simple libogg1-style buffer.*/
|
|
||||||
struct ec_byte_buffer{
|
/*The entropy encoder/decoder context.
|
||||||
|
We use the same structure for both, so that common functions like ec_tell()
|
||||||
|
can be used on either one.*/
|
||||||
|
struct ec_ctx{
|
||||||
|
/*Buffered input/output.*/
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
ec_uint32 offs;
|
/*The size of the buffer.*/
|
||||||
ec_uint32 end_offs;
|
|
||||||
ec_uint32 storage;
|
ec_uint32 storage;
|
||||||
|
/*The offset at which the last byte containing raw bits was read/written.*/
|
||||||
|
ec_uint32 end_offs;
|
||||||
|
/*Bits that will be read from/written at the end.*/
|
||||||
|
ec_window end_window;
|
||||||
|
/*Number of valid bits in end_window.*/
|
||||||
|
int nend_bits;
|
||||||
|
/*The total number of whole bits read/written.
|
||||||
|
This does not include partial bits currently in the range coder.*/
|
||||||
|
int nbits_total;
|
||||||
|
/*The offset at which the next range coder byte will be read/written.*/
|
||||||
|
ec_uint32 offs;
|
||||||
|
/*The number of values in the current range.*/
|
||||||
|
ec_uint32 rng;
|
||||||
|
/*In the decoder: the difference between the top of the current range and
|
||||||
|
the input value, minus one.
|
||||||
|
In the encoder: the low end of the current range.*/
|
||||||
|
ec_uint32 val;
|
||||||
|
/*In the decoder: the saved normalization factor from ec_decode().
|
||||||
|
In the encoder: the number of oustanding carry propagating symbols.*/
|
||||||
|
ec_uint32 ext;
|
||||||
|
/*A buffered input/output symbol, awaiting carry propagation.*/
|
||||||
|
int rem;
|
||||||
|
/*Nonzero if an error occurred.*/
|
||||||
|
int error;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*Encoding functions.*/
|
|
||||||
void ec_byte_writeinit_buffer(ec_byte_buffer *_b, unsigned char *_buf, ec_uint32 _size);
|
|
||||||
void ec_byte_shrink(ec_byte_buffer *_b, ec_uint32 _size);
|
|
||||||
int ec_byte_write(ec_byte_buffer *_b,unsigned _value);
|
|
||||||
int ec_byte_write_at_end(ec_byte_buffer *_b,unsigned _value);
|
|
||||||
int ec_byte_write_done(ec_byte_buffer *_b,int _start_bits_available,
|
|
||||||
unsigned _end_byte,int _end_bits_used);
|
|
||||||
/*Decoding functions.*/
|
|
||||||
void ec_byte_readinit(ec_byte_buffer *_b,unsigned char *_buf,ec_uint32 _bytes);
|
|
||||||
int ec_byte_read(ec_byte_buffer *_b);
|
|
||||||
int ec_byte_read_from_end(ec_byte_buffer *_b);
|
|
||||||
/*Shared functions.*/
|
/*Shared functions.*/
|
||||||
static inline void ec_byte_reset(ec_byte_buffer *_b){
|
static inline void ec_reset(ec_ctx *_this){
|
||||||
_b->offs=_b->end_offs=0;
|
_this->offs=_this->end_offs=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline ec_uint32 ec_byte_bytes(ec_byte_buffer *_b){
|
static inline ec_uint32 ec_range_bytes(ec_ctx *_this){
|
||||||
return _b->offs;
|
return _this->offs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned char *ec_byte_get_buffer(ec_byte_buffer *_b){
|
static inline unsigned char *ec_get_buffer(ec_ctx *_this){
|
||||||
return _b->buf;
|
return _this->buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int ec_get_error(ec_ctx *_this){
|
||||||
|
return _this->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Returns the number of bits "used" by the encoded or decoded symbols so far.
|
||||||
|
This same number can be computed in either the encoder or the decoder, and is
|
||||||
|
suitable for making coding decisions.
|
||||||
|
Return: The number of bits.
|
||||||
|
This will always be slightly larger than the exact value (e.g., all
|
||||||
|
rounding error is in the positive direction).*/
|
||||||
|
static inline int ec_tell(ec_ctx *_this){
|
||||||
|
return _this->nbits_total-EC_ILOG(_this->rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Returns the number of bits "used" by the encoded or decoded symbols so far.
|
||||||
|
This same number can be computed in either the encoder or the decoder, and is
|
||||||
|
suitable for making coding decisions.
|
||||||
|
Return: The number of bits scaled by 2**BITRES.
|
||||||
|
This will always be slightly larger than the exact value (e.g., all
|
||||||
|
rounding error is in the positive direction).*/
|
||||||
|
ec_uint32 ec_tell_frac(ec_ctx *_this);
|
||||||
|
|
||||||
int ec_ilog(ec_uint32 _v);
|
int ec_ilog(ec_uint32 _v);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
198
libcelt/entdec.c
198
libcelt/entdec.c
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2001-2008 Timothy B. Terriberry
|
/* Copyright (c) 2001-2011 Timothy B. Terriberry
|
||||||
Copyright (c) 2008-2009 Xiph.Org Foundation */
|
Copyright (c) 2008-2009 Xiph.Org Foundation */
|
||||||
/*
|
/*
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -34,22 +34,178 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "entdec.h"
|
|
||||||
#include "os_support.h"
|
#include "os_support.h"
|
||||||
#include "arch.h"
|
#include "arch.h"
|
||||||
|
#include "entdec.h"
|
||||||
|
#include "mfrngcod.h"
|
||||||
|
|
||||||
void ec_byte_readinit(ec_byte_buffer *_b,unsigned char *_buf,ec_uint32 _bytes){
|
|
||||||
_b->buf=_buf;
|
|
||||||
_b->offs=_b->end_offs=0;
|
/*A range decoder.
|
||||||
_b->storage=_bytes;
|
This is an entropy decoder based upon \cite{Mar79}, which is itself a
|
||||||
|
rediscovery of the FIFO arithmetic code introduced by \cite{Pas76}.
|
||||||
|
It is very similar to arithmetic encoding, except that encoding is done with
|
||||||
|
digits in any base, instead of with bits, and so it is faster when using
|
||||||
|
larger bases (i.e.: a byte).
|
||||||
|
The author claims an average waste of $\frac{1}{2}\log_b(2b)$ bits, where $b$
|
||||||
|
is the base, longer than the theoretical optimum, but to my knowledge there
|
||||||
|
is no published justification for this claim.
|
||||||
|
This only seems true when using near-infinite precision arithmetic so that
|
||||||
|
the process is carried out with no rounding errors.
|
||||||
|
|
||||||
|
IBM (the author's employer) never sought to patent the idea, and to my
|
||||||
|
knowledge the algorithm is unencumbered by any patents, though its
|
||||||
|
performance is very competitive with proprietary arithmetic coding.
|
||||||
|
The two are based on very similar ideas, however.
|
||||||
|
An excellent description of implementation details is available at
|
||||||
|
http://www.arturocampos.com/ac_range.html
|
||||||
|
A recent work \cite{MNW98} which proposes several changes to arithmetic
|
||||||
|
encoding for efficiency actually re-discovers many of the principles
|
||||||
|
behind range encoding, and presents a good theoretical analysis of them.
|
||||||
|
|
||||||
|
End of stream is handled by writing out the smallest number of bits that
|
||||||
|
ensures that the stream will be correctly decoded regardless of the value of
|
||||||
|
any subsequent bits.
|
||||||
|
ec_tell() can be used to determine how many bits were needed to decode
|
||||||
|
all the symbols thus far; other data can be packed in the remaining bits of
|
||||||
|
the input buffer.
|
||||||
|
@PHDTHESIS{Pas76,
|
||||||
|
author="Richard Clark Pasco",
|
||||||
|
title="Source coding algorithms for fast data compression",
|
||||||
|
school="Dept. of Electrical Engineering, Stanford University",
|
||||||
|
address="Stanford, CA",
|
||||||
|
month=May,
|
||||||
|
year=1976
|
||||||
|
}
|
||||||
|
@INPROCEEDINGS{Mar79,
|
||||||
|
author="Martin, G.N.N.",
|
||||||
|
title="Range encoding: an algorithm for removing redundancy from a digitised
|
||||||
|
message",
|
||||||
|
booktitle="Video & Data Recording Conference",
|
||||||
|
year=1979,
|
||||||
|
address="Southampton",
|
||||||
|
month=Jul
|
||||||
|
}
|
||||||
|
@ARTICLE{MNW98,
|
||||||
|
author="Alistair Moffat and Radford Neal and Ian H. Witten",
|
||||||
|
title="Arithmetic Coding Revisited",
|
||||||
|
journal="{ACM} Transactions on Information Systems",
|
||||||
|
year=1998,
|
||||||
|
volume=16,
|
||||||
|
number=3,
|
||||||
|
pages="256--294",
|
||||||
|
month=Jul,
|
||||||
|
URL="http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf"
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int ec_read_byte(ec_dec *_this){
|
||||||
|
return _this->offs<_this->storage?_this->buf[_this->offs++]:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ec_byte_read(ec_byte_buffer *_b){
|
static int ec_read_byte_from_end(ec_dec *_this){
|
||||||
return _b->offs<_b->storage?_b->buf[_b->offs++]:0;
|
return _this->end_offs<_this->storage?
|
||||||
|
_this->buf[_this->storage-++(_this->end_offs)]:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ec_byte_read_from_end(ec_byte_buffer *_b){
|
|
||||||
return _b->end_offs<_b->storage?_b->buf[_b->storage-++(_b->end_offs)]:0;
|
/*Normalizes the contents of val and rng so that rng lies entirely in the
|
||||||
|
high-order symbol.*/
|
||||||
|
static void ec_dec_normalize(ec_dec *_this){
|
||||||
|
/*If the range is too small, rescale it and input some bits.*/
|
||||||
|
while(_this->rng<=EC_CODE_BOT){
|
||||||
|
int sym;
|
||||||
|
_this->nbits_total+=EC_SYM_BITS;
|
||||||
|
_this->rng<<=EC_SYM_BITS;
|
||||||
|
/*Use up the remaining bits from our last symbol.*/
|
||||||
|
sym=_this->rem;
|
||||||
|
/*Read the next value from the input.*/
|
||||||
|
_this->rem=ec_read_byte(_this);
|
||||||
|
/*Take the rest of the bits we need from this new symbol.*/
|
||||||
|
sym=(sym<<EC_SYM_BITS|_this->rem)>>EC_SYM_BITS-EC_CODE_EXTRA;
|
||||||
|
/*And subtract them from val, capped to be less than EC_CODE_TOP.*/
|
||||||
|
_this->val=(_this->val<<EC_SYM_BITS)+(EC_SYM_MAX&~sym)&EC_CODE_TOP-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ec_dec_init(ec_dec *_this,unsigned char *_buf,ec_uint32 _storage){
|
||||||
|
_this->buf=_buf;
|
||||||
|
_this->storage=_storage;
|
||||||
|
_this->end_offs=0;
|
||||||
|
_this->end_window=0;
|
||||||
|
_this->nend_bits=0;
|
||||||
|
_this->offs=0;
|
||||||
|
_this->rng=1U<<EC_CODE_EXTRA;
|
||||||
|
_this->rem=ec_read_byte(_this);
|
||||||
|
_this->val=_this->rng-1-(_this->rem>>EC_SYM_BITS-EC_CODE_EXTRA);
|
||||||
|
_this->error=0;
|
||||||
|
/*Normalize the interval.*/
|
||||||
|
ec_dec_normalize(_this);
|
||||||
|
/*This is the offset from which ec_tell() will subtract partial bits.
|
||||||
|
This must be after the initial ec_dec_normalize(), or you will have to
|
||||||
|
compensate for the bits that are read there.*/
|
||||||
|
_this->nbits_total=EC_CODE_BITS+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned ec_decode(ec_dec *_this,unsigned _ft){
|
||||||
|
unsigned s;
|
||||||
|
_this->ext=_this->rng/_ft;
|
||||||
|
s=(unsigned)(_this->val/_this->ext);
|
||||||
|
return _ft-EC_MINI(s+1,_ft);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned ec_decode_bin(ec_dec *_this,unsigned _bits){
|
||||||
|
unsigned s;
|
||||||
|
_this->ext=_this->rng>>_bits;
|
||||||
|
s=(unsigned)(_this->val/_this->ext);
|
||||||
|
return (1<<_bits)-EC_MINI(s+1,1<<_bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft){
|
||||||
|
ec_uint32 s;
|
||||||
|
s=IMUL32(_this->ext,_ft-_fh);
|
||||||
|
_this->val-=s;
|
||||||
|
_this->rng=_fl>0?IMUL32(_this->ext,_fh-_fl):_this->rng-s;
|
||||||
|
ec_dec_normalize(_this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*The probability of having a "one" is 1/(1<<_logp).*/
|
||||||
|
int ec_dec_bit_logp(ec_dec *_this,unsigned _logp){
|
||||||
|
ec_uint32 r;
|
||||||
|
ec_uint32 d;
|
||||||
|
ec_uint32 s;
|
||||||
|
int ret;
|
||||||
|
r=_this->rng;
|
||||||
|
d=_this->val;
|
||||||
|
s=r>>_logp;
|
||||||
|
ret=d<s;
|
||||||
|
if(!ret)_this->val=d-s;
|
||||||
|
_this->rng=ret?s:r-s;
|
||||||
|
ec_dec_normalize(_this);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb){
|
||||||
|
ec_uint32 r;
|
||||||
|
ec_uint32 d;
|
||||||
|
ec_uint32 s;
|
||||||
|
ec_uint32 t;
|
||||||
|
int ret;
|
||||||
|
s=_this->rng;
|
||||||
|
d=_this->val;
|
||||||
|
r=s>>_ftb;
|
||||||
|
ret=-1;
|
||||||
|
do{
|
||||||
|
t=s;
|
||||||
|
s=IMUL32(r,_icdf[++ret]);
|
||||||
|
}
|
||||||
|
while(d<s);
|
||||||
|
_this->val=d-s;
|
||||||
|
_this->rng=t-s;
|
||||||
|
ec_dec_normalize(_this);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ec_uint32 ec_dec_uint(ec_dec *_this,ec_uint32 _ft){
|
ec_uint32 ec_dec_uint(ec_dec *_this,ec_uint32 _ft){
|
||||||
|
@ -79,6 +235,24 @@ ec_uint32 ec_dec_uint(ec_dec *_this,ec_uint32 _ft){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ec_dec_get_error(ec_dec *_this){
|
ec_uint32 ec_dec_bits(ec_dec *_this,unsigned _bits){
|
||||||
return _this->error;
|
ec_window window;
|
||||||
|
int available;
|
||||||
|
ec_uint32 ret;
|
||||||
|
window=_this->end_window;
|
||||||
|
available=_this->nend_bits;
|
||||||
|
if(available<_bits){
|
||||||
|
do{
|
||||||
|
window|=(ec_window)ec_read_byte_from_end(_this)<<available;
|
||||||
|
available+=EC_SYM_BITS;
|
||||||
|
}
|
||||||
|
while(available<=EC_WINDOW_SIZE-EC_SYM_BITS);
|
||||||
|
}
|
||||||
|
ret=(ec_uint32)window&((ec_uint32)1<<_bits)-1;
|
||||||
|
window>>=_bits;
|
||||||
|
available-=_bits;
|
||||||
|
_this->end_window=window;
|
||||||
|
_this->nend_bits=available;
|
||||||
|
_this->nbits_total+=_bits;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2001-2008 Timothy B. Terriberry
|
/* Copyright (c) 2001-2011 Timothy B. Terriberry
|
||||||
Copyright (c) 2008-2009 Xiph.Org Foundation */
|
Copyright (c) 2008-2009 Xiph.Org Foundation */
|
||||||
/*
|
/*
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -36,38 +36,11 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct ec_dec ec_dec;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*The entropy decoder.*/
|
|
||||||
struct ec_dec{
|
|
||||||
/*The buffer to decode.*/
|
|
||||||
ec_byte_buffer *buf;
|
|
||||||
/*The remainder of a buffered input symbol.*/
|
|
||||||
int rem;
|
|
||||||
/*The number of values in the current range.*/
|
|
||||||
ec_uint32 rng;
|
|
||||||
/*The difference between the top of the current range and the input value,
|
|
||||||
minus one.*/
|
|
||||||
ec_uint32 dif;
|
|
||||||
/*Normalization factor.*/
|
|
||||||
ec_uint32 nrm;
|
|
||||||
/*Bits that were written at the end.*/
|
|
||||||
ec_window end_window;
|
|
||||||
/*Number of valid bits in end_window.*/
|
|
||||||
int nend_bits;
|
|
||||||
/*The total number of whole bits read.*/
|
|
||||||
int nbits_total;
|
|
||||||
/*Nonzero if an error occurred.*/
|
|
||||||
int error;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*Initializes the decoder.
|
/*Initializes the decoder.
|
||||||
_buf: The input buffer to use.
|
_buf: The input buffer to use.
|
||||||
Return: 0 on success, or a negative value on error.*/
|
Return: 0 on success, or a negative value on error.*/
|
||||||
void ec_dec_init(ec_dec *_this,ec_byte_buffer *_buf);
|
void ec_dec_init(ec_dec *_this,unsigned char *_buf,ec_uint32 _storage);
|
||||||
|
|
||||||
/*Calculates the cumulative frequency for the next symbol.
|
/*Calculates the cumulative frequency for the next symbol.
|
||||||
This can then be fed into the probability model to determine what that
|
This can then be fed into the probability model to determine what that
|
||||||
symbol is, and the additional frequency information required to advance to
|
symbol is, and the additional frequency information required to advance to
|
||||||
|
@ -82,6 +55,8 @@ void ec_dec_init(ec_dec *_this,ec_byte_buffer *_buf);
|
||||||
up to and including the one encoded is fh, then the returned value
|
up to and including the one encoded is fh, then the returned value
|
||||||
will fall in the range [fl,fh).*/
|
will fall in the range [fl,fh).*/
|
||||||
unsigned ec_decode(ec_dec *_this,unsigned _ft);
|
unsigned ec_decode(ec_dec *_this,unsigned _ft);
|
||||||
|
|
||||||
|
/*Equivalent to ec_decode() with _ft==1<<_bits.*/
|
||||||
unsigned ec_decode_bin(ec_dec *_this,unsigned _bits);
|
unsigned ec_decode_bin(ec_dec *_this,unsigned _bits);
|
||||||
|
|
||||||
/*Advance the decoder past the next symbol using the frequency information the
|
/*Advance the decoder past the next symbol using the frequency information the
|
||||||
|
@ -97,22 +72,11 @@ unsigned ec_decode_bin(ec_dec *_this,unsigned _bits);
|
||||||
_ft: The total frequency of the symbols in the alphabet the symbol decoded
|
_ft: The total frequency of the symbols in the alphabet the symbol decoded
|
||||||
was encoded in.
|
was encoded in.
|
||||||
This must be the same as passed to the preceding call to ec_decode().*/
|
This must be the same as passed to the preceding call to ec_decode().*/
|
||||||
void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,
|
void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft);
|
||||||
unsigned _ft);
|
|
||||||
/*Extracts a sequence of raw bits from the stream.
|
/* Decode a bit that has a 1/(1<<_logp) probability of being a one */
|
||||||
The bits must have been encoded with ec_enc_bits().
|
int ec_dec_bit_logp(ec_dec *_this,unsigned _logp);
|
||||||
No call to ec_dec_update() is necessary after this call.
|
|
||||||
_ftb: The number of bits to extract.
|
|
||||||
This must be between 0 and 25, inclusive.
|
|
||||||
Return: The decoded bits.*/
|
|
||||||
ec_uint32 ec_dec_bits(ec_dec *_this,unsigned _ftb);
|
|
||||||
/*Extracts a raw unsigned integer with a non-power-of-2 range from the stream.
|
|
||||||
The bits must have been encoded with ec_enc_uint().
|
|
||||||
No call to ec_dec_update() is necessary after this call.
|
|
||||||
_ft: The number of integers that can be decoded (one more than the max).
|
|
||||||
This must be at least one, and no more than 2**32-1.
|
|
||||||
Return: The decoded bits.*/
|
|
||||||
ec_uint32 ec_dec_uint(ec_dec *_this,ec_uint32 _ft);
|
|
||||||
/*Decodes a symbol given an "inverse" CDF table.
|
/*Decodes a symbol given an "inverse" CDF table.
|
||||||
No call to ec_dec_update() is necessary after this call.
|
No call to ec_dec_update() is necessary after this call.
|
||||||
_icdf: The "inverse" CDF, such that symbol s falls in the range
|
_icdf: The "inverse" CDF, such that symbol s falls in the range
|
||||||
|
@ -123,23 +87,20 @@ ec_uint32 ec_dec_uint(ec_dec *_this,ec_uint32 _ft);
|
||||||
Return: The decoded symbol s.*/
|
Return: The decoded symbol s.*/
|
||||||
int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb);
|
int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb);
|
||||||
|
|
||||||
/* Decode a bit that has a _prob/65536 probability of being a one */
|
/*Extracts a raw unsigned integer with a non-power-of-2 range from the stream.
|
||||||
int ec_dec_bit_prob(ec_dec *_this,unsigned _prob);
|
The bits must have been encoded with ec_enc_uint().
|
||||||
|
No call to ec_dec_update() is necessary after this call.
|
||||||
|
_ft: The number of integers that can be decoded (one more than the max).
|
||||||
|
This must be at least one, and no more than 2**32-1.
|
||||||
|
Return: The decoded bits.*/
|
||||||
|
ec_uint32 ec_dec_uint(ec_dec *_this,ec_uint32 _ft);
|
||||||
|
|
||||||
/* Decode a bit that has a 1/(1<<_logp) probability of being a one */
|
/*Extracts a sequence of raw bits from the stream.
|
||||||
int ec_dec_bit_logp(ec_dec *_this,unsigned _logp);
|
The bits must have been encoded with ec_enc_bits().
|
||||||
|
No call to ec_dec_update() is necessary after this call.
|
||||||
/*Returns the number of bits "used" by the encoded symbols so far.
|
_ftb: The number of bits to extract.
|
||||||
This same number can be computed by the encoder, and is suitable for making
|
This must be between 0 and 25, inclusive.
|
||||||
coding decisions.
|
Return: The decoded bits.*/
|
||||||
_b: The number of extra bits of precision to include.
|
ec_uint32 ec_dec_bits(ec_dec *_this,unsigned _ftb);
|
||||||
At most 16 will be accurate.
|
|
||||||
Return: The number of bits scaled by 2**_b.
|
|
||||||
This will always be slightly larger than the exact value (e.g., all
|
|
||||||
rounding error is in the positive direction).*/
|
|
||||||
ec_uint32 ec_dec_tell(ec_dec *_this,int _b);
|
|
||||||
|
|
||||||
/*Return: A nonzero value if any error has been detected during decoding.*/
|
|
||||||
int ec_dec_get_error(ec_dec *_this);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
247
libcelt/entenc.c
247
libcelt/entenc.c
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2001-2008 Timothy B. Terriberry
|
/* Copyright (c) 2001-2011 Timothy B. Terriberry
|
||||||
Copyright (c) 2008-2009 Xiph.Org Foundation */
|
Copyright (c) 2008-2009 Xiph.Org Foundation */
|
||||||
/*
|
/*
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -33,56 +33,152 @@
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
#include "os_support.h"
|
#include "os_support.h"
|
||||||
#include "entenc.h"
|
|
||||||
#include "arch.h"
|
#include "arch.h"
|
||||||
|
#include "entenc.h"
|
||||||
|
#include "mfrngcod.h"
|
||||||
|
|
||||||
|
|
||||||
void ec_byte_writeinit_buffer(ec_byte_buffer *_b,
|
|
||||||
unsigned char *_buf,ec_uint32 _size){
|
/*A range encoder.
|
||||||
_b->buf=_buf;
|
See entdec.c and the references for implementation details \cite{Mar79,MNW98}.
|
||||||
_b->end_offs=_b->offs=0;
|
|
||||||
_b->storage=_size;
|
@INPROCEEDINGS{Mar79,
|
||||||
|
author="Martin, G.N.N.",
|
||||||
|
title="Range encoding: an algorithm for removing redundancy from a digitised
|
||||||
|
message",
|
||||||
|
booktitle="Video \& Data Recording Conference",
|
||||||
|
year=1979,
|
||||||
|
address="Southampton",
|
||||||
|
month=Jul
|
||||||
}
|
}
|
||||||
|
@ARTICLE{MNW98,
|
||||||
|
author="Alistair Moffat and Radford Neal and Ian H. Witten",
|
||||||
|
title="Arithmetic Coding Revisited",
|
||||||
|
journal="{ACM} Transactions on Information Systems",
|
||||||
|
year=1998,
|
||||||
|
volume=16,
|
||||||
|
number=3,
|
||||||
|
pages="256--294",
|
||||||
|
month=Jul,
|
||||||
|
URL="http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf"
|
||||||
|
}*/
|
||||||
|
|
||||||
void ec_byte_shrink(ec_byte_buffer *_b,ec_uint32 _size){
|
|
||||||
celt_assert(_b->offs+_b->end_offs<=_size);
|
|
||||||
CELT_MOVE(_b->buf+_size-_b->end_offs,
|
|
||||||
_b->buf+_b->storage-_b->end_offs,_b->end_offs);
|
|
||||||
_b->storage=_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ec_byte_write(ec_byte_buffer *_b,unsigned _value){
|
|
||||||
if(_b->offs+_b->end_offs>=_b->storage)return -1;
|
static int ec_write_byte(ec_enc *_this,unsigned _value){
|
||||||
_b->buf[_b->offs++]=(unsigned char)_value;
|
if(_this->offs+_this->end_offs>=_this->storage)return -1;
|
||||||
|
_this->buf[_this->offs++]=(unsigned char)_value;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ec_byte_write_at_end(ec_byte_buffer *_b,unsigned _value){
|
static int ec_write_byte_at_end(ec_enc *_this,unsigned _value){
|
||||||
if(_b->offs+_b->end_offs>=_b->storage)return -1;
|
if(_this->offs+_this->end_offs>=_this->storage)return -1;
|
||||||
_b->buf[_b->storage-++(_b->end_offs)]=(unsigned char)_value;
|
_this->buf[_this->storage-++(_this->end_offs)]=(unsigned char)_value;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ec_byte_write_done(ec_byte_buffer *_b,int _start_bits_available,
|
|
||||||
unsigned _end_byte,int _end_bits_used){
|
/*Outputs a symbol, with a carry bit.
|
||||||
int ret;
|
If there is a potential to propagate a carry over several symbols, they are
|
||||||
CELT_MEMSET(_b->buf+_b->offs,0,_b->storage-_b->offs-_b->end_offs);
|
buffered until it can be determined whether or not an actual carry will
|
||||||
ret=0;
|
occur.
|
||||||
if(_end_bits_used>0){
|
If the counter for the buffered symbols overflows, then the stream becomes
|
||||||
if(_b->offs+_b->end_offs>=_b->storage){
|
undecodable.
|
||||||
/*If there's no range coder data at all, give up.*/
|
This gives a theoretical limit of a few billion symbols in a single packet on
|
||||||
if(_b->end_offs>=_b->storage)return -1;
|
32-bit systems.
|
||||||
/*If we've busted, don't add too many extra bits to the last byte; it
|
The alternative is to truncate the range in order to force a carry, but
|
||||||
would corrupt the range coder data, and that's more important.*/
|
requires similar carry tracking in the decoder, needlessly slowing it down.*/
|
||||||
if(_start_bits_available<_end_bits_used){
|
static void ec_enc_carry_out(ec_enc *_this,int _c){
|
||||||
_end_bits_used=_start_bits_available;
|
if(_c!=EC_SYM_MAX){
|
||||||
_end_byte&=(1<<_start_bits_available)-1;
|
/*No further carry propagation possible, flush buffer.*/
|
||||||
ret=-1;
|
int carry;
|
||||||
|
carry=_c>>EC_SYM_BITS;
|
||||||
|
/*Don't output a byte on the first write.
|
||||||
|
This compare should be taken care of by branch-prediction thereafter.*/
|
||||||
|
if(_this->rem>=0)_this->error|=ec_write_byte(_this,_this->rem+carry);
|
||||||
|
if(_this->ext>0){
|
||||||
|
unsigned sym;
|
||||||
|
sym=EC_SYM_MAX+carry&EC_SYM_MAX;
|
||||||
|
do _this->error|=ec_write_byte(_this,sym);
|
||||||
|
while(--(_this->ext)>0);
|
||||||
|
}
|
||||||
|
_this->rem=_c&EC_SYM_MAX;
|
||||||
|
}
|
||||||
|
else _this->ext++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ec_enc_normalize(ec_enc *_this){
|
||||||
|
/*If the range is too small, output some bits and rescale it.*/
|
||||||
|
while(_this->rng<=EC_CODE_BOT){
|
||||||
|
ec_enc_carry_out(_this,(int)(_this->val>>EC_CODE_SHIFT));
|
||||||
|
/*Move the next-to-high-order symbol into the high-order position.*/
|
||||||
|
_this->val=_this->val<<EC_SYM_BITS&EC_CODE_TOP-1;
|
||||||
|
_this->rng<<=EC_SYM_BITS;
|
||||||
|
_this->nbits_total+=EC_SYM_BITS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_b->buf[_b->storage-_b->end_offs-1]|=_end_byte;
|
|
||||||
|
void ec_enc_init(ec_enc *_this,unsigned char *_buf,ec_uint32 _size){
|
||||||
|
_this->buf=_buf;
|
||||||
|
_this->end_offs=0;
|
||||||
|
_this->end_window=0;
|
||||||
|
_this->nend_bits=0;
|
||||||
|
/*This is the offset from which ec_tell() will subtract partial bits.*/
|
||||||
|
_this->nbits_total=EC_CODE_BITS+1;
|
||||||
|
_this->offs=0;
|
||||||
|
_this->rng=EC_CODE_TOP;
|
||||||
|
_this->rem=-1;
|
||||||
|
_this->val=0;
|
||||||
|
_this->ext=0;
|
||||||
|
_this->storage=_size;
|
||||||
|
_this->error=0;
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
|
void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft){
|
||||||
|
ec_uint32 r;
|
||||||
|
r=_this->rng/_ft;
|
||||||
|
if(_fl>0){
|
||||||
|
_this->val+=_this->rng-IMUL32(r,(_ft-_fl));
|
||||||
|
_this->rng=IMUL32(r,(_fh-_fl));
|
||||||
|
}
|
||||||
|
else _this->rng-=IMUL32(r,(_ft-_fh));
|
||||||
|
ec_enc_normalize(_this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits){
|
||||||
|
ec_uint32 r;
|
||||||
|
r=_this->rng>>_bits;
|
||||||
|
if(_fl>0){
|
||||||
|
_this->val+=_this->rng-IMUL32(r,((1<<_bits)-_fl));
|
||||||
|
_this->rng=IMUL32(r,(_fh-_fl));
|
||||||
|
}
|
||||||
|
else _this->rng-=IMUL32(r,((1<<_bits)-_fh));
|
||||||
|
ec_enc_normalize(_this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*The probability of having a "one" is 1/(1<<_logp).*/
|
||||||
|
void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp){
|
||||||
|
ec_uint32 r;
|
||||||
|
ec_uint32 s;
|
||||||
|
ec_uint32 l;
|
||||||
|
r=_this->rng;
|
||||||
|
l=_this->val;
|
||||||
|
s=r>>_logp;
|
||||||
|
r-=s;
|
||||||
|
if(_val)_this->val=l+r;
|
||||||
|
_this->rng=_val?s:r;
|
||||||
|
ec_enc_normalize(_this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb){
|
||||||
|
ec_uint32 r;
|
||||||
|
r=_this->rng>>_ftb;
|
||||||
|
if(_s>0){
|
||||||
|
_this->val+=_this->rng-IMUL32(r,_icdf[_s-1]);
|
||||||
|
_this->rng=IMUL32(r,_icdf[_s-1]-_icdf[_s]);
|
||||||
|
}
|
||||||
|
else _this->rng-=IMUL32(r,_icdf[_s]);
|
||||||
|
ec_enc_normalize(_this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ec_enc_uint(ec_enc *_this,ec_uint32 _fl,ec_uint32 _ft){
|
void ec_enc_uint(ec_enc *_this,ec_uint32 _fl,ec_uint32 _ft){
|
||||||
|
@ -103,6 +199,81 @@ void ec_enc_uint(ec_enc *_this,ec_uint32 _fl,ec_uint32 _ft){
|
||||||
else ec_encode(_this,_fl,_fl+1,_ft+1);
|
else ec_encode(_this,_fl,_fl+1,_ft+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ec_enc_get_error(ec_enc *_this){
|
void ec_enc_bits(ec_enc *_this,ec_uint32 _fl,unsigned _bits){
|
||||||
return _this->error;
|
ec_window window;
|
||||||
|
int used;
|
||||||
|
window=_this->end_window;
|
||||||
|
used=_this->nend_bits;
|
||||||
|
if(used+_bits>EC_WINDOW_SIZE){
|
||||||
|
do{
|
||||||
|
_this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX);
|
||||||
|
window>>=EC_SYM_BITS;
|
||||||
|
used-=EC_SYM_BITS;
|
||||||
|
}
|
||||||
|
while(used>=EC_SYM_BITS);
|
||||||
|
}
|
||||||
|
window|=(ec_window)_fl<<used;
|
||||||
|
used+=_bits;
|
||||||
|
_this->end_window=window;
|
||||||
|
_this->nend_bits=used;
|
||||||
|
_this->nbits_total+=_bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ec_enc_shrink(ec_enc *_this,ec_uint32 _size){
|
||||||
|
celt_assert(_this->offs+_this->end_offs<=_size);
|
||||||
|
CELT_MOVE(_this->buf+_size-_this->end_offs,
|
||||||
|
_this->buf+_this->storage-_this->end_offs,_this->end_offs);
|
||||||
|
_this->storage=_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ec_enc_done(ec_enc *_this){
|
||||||
|
ec_window window;
|
||||||
|
int used;
|
||||||
|
ec_uint32 msk;
|
||||||
|
ec_uint32 end;
|
||||||
|
int l;
|
||||||
|
/*We output the minimum number of bits that ensures that the symbols encoded
|
||||||
|
thus far will be decoded correctly regardless of the bits that follow.*/
|
||||||
|
l=EC_CODE_BITS-EC_ILOG(_this->rng);
|
||||||
|
msk=EC_CODE_TOP-1>>l;
|
||||||
|
end=_this->val+msk&~msk;
|
||||||
|
if((end|msk)>=_this->val+_this->rng){
|
||||||
|
l++;
|
||||||
|
msk>>=1;
|
||||||
|
end=_this->val+msk&~msk;
|
||||||
|
}
|
||||||
|
while(l>0){
|
||||||
|
ec_enc_carry_out(_this,(int)(end>>EC_CODE_SHIFT));
|
||||||
|
end=end<<EC_SYM_BITS&EC_CODE_TOP-1;
|
||||||
|
l-=EC_SYM_BITS;
|
||||||
|
}
|
||||||
|
/*If we have a buffered byte flush it into the output buffer.*/
|
||||||
|
if(_this->rem>=0||_this->ext>0)ec_enc_carry_out(_this,0);
|
||||||
|
/*If we have buffered extra bits, flush them as well.*/
|
||||||
|
window=_this->end_window;
|
||||||
|
used=_this->nend_bits;
|
||||||
|
while(used>=EC_SYM_BITS){
|
||||||
|
_this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX);
|
||||||
|
window>>=EC_SYM_BITS;
|
||||||
|
used-=EC_SYM_BITS;
|
||||||
|
}
|
||||||
|
/*Clear any excess space and add any remaining extra bits to the last byte.*/
|
||||||
|
if(!_this->error){
|
||||||
|
CELT_MEMSET(_this->buf+_this->offs,0,
|
||||||
|
_this->storage-_this->offs-_this->end_offs);
|
||||||
|
if(used>0){
|
||||||
|
/*If there's no range coder data at all, give up.*/
|
||||||
|
if(_this->end_offs>=_this->storage)_this->error=-1;
|
||||||
|
else{
|
||||||
|
l=-l;
|
||||||
|
/*If we've busted, don't add too many extra bits to the last byte; it
|
||||||
|
would corrupt the range coder data, and that's more important.*/
|
||||||
|
if(_this->offs+_this->end_offs>=_this->storage&&l<used){
|
||||||
|
window&=(1<<l)-1;
|
||||||
|
_this->error=-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_this->buf[_this->storage-_this->end_offs-1]|=(unsigned char)window;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2001-2008 Timothy B. Terriberry
|
/* Copyright (c) 2001-2011 Timothy B. Terriberry
|
||||||
Copyright (c) 2008-2009 Xiph.Org Foundation */
|
Copyright (c) 2008-2009 Xiph.Org Foundation */
|
||||||
/*
|
/*
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -36,37 +36,10 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct ec_enc ec_enc;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*The entropy encoder.*/
|
|
||||||
struct ec_enc{
|
|
||||||
/*Buffered output.*/
|
|
||||||
ec_byte_buffer *buf;
|
|
||||||
/*A buffered output symbol, awaiting carry propagation.*/
|
|
||||||
int rem;
|
|
||||||
/*Number of extra carry propagating symbols.*/
|
|
||||||
size_t ext;
|
|
||||||
/*The number of values in the current range.*/
|
|
||||||
ec_uint32 rng;
|
|
||||||
/*The low end of the current range (inclusive).*/
|
|
||||||
ec_uint32 low;
|
|
||||||
/*Bits that will be written at the end.*/
|
|
||||||
ec_window end_window;
|
|
||||||
/*Number of valid bits in end_window.*/
|
|
||||||
int nend_bits;
|
|
||||||
/*The total number of whole bits written.*/
|
|
||||||
int nbits_total;
|
|
||||||
/*Nonzero if an error occurred.*/
|
|
||||||
int error;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*Initializes the encoder.
|
/*Initializes the encoder.
|
||||||
_buf: The buffer to store output bytes in.
|
_buf: The buffer to store output bytes in.
|
||||||
This must have already been initialized for writing and reset.*/
|
_size: The size of the buffer, in chars.*/
|
||||||
void ec_enc_init(ec_enc *_this,ec_byte_buffer *_buf);
|
void ec_enc_init(ec_enc *_this,unsigned char *_buf,ec_uint32 _size);
|
||||||
/*Encodes a symbol given its frequency information.
|
/*Encodes a symbol given its frequency information.
|
||||||
The frequency information must be discernable by the decoder, assuming it
|
The frequency information must be discernable by the decoder, assuming it
|
||||||
has read only the previous symbols from the stream.
|
has read only the previous symbols from the stream.
|
||||||
|
@ -81,21 +54,9 @@ void ec_enc_init(ec_enc *_this,ec_byte_buffer *_buf);
|
||||||
decoded value will fall.
|
decoded value will fall.
|
||||||
_ft: The sum of the frequencies of all the symbols*/
|
_ft: The sum of the frequencies of all the symbols*/
|
||||||
void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft);
|
void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft);
|
||||||
|
|
||||||
|
/*Equivalent to ec_encode() with _ft==1<<_bits.*/
|
||||||
void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits);
|
void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits);
|
||||||
/*Encodes a sequence of raw bits in the stream.
|
|
||||||
_fl: The bits to encode.
|
|
||||||
_ftb: The number of bits to encode.
|
|
||||||
This must be between 0 and 25, inclusive.*/
|
|
||||||
void ec_enc_bits(ec_enc *_this,ec_uint32 _fl,unsigned _ftb);
|
|
||||||
|
|
||||||
/*Encodes a raw unsigned integer in the stream.
|
|
||||||
_fl: The integer to encode.
|
|
||||||
_ft: The number of integers that can be encoded (one more than the max).
|
|
||||||
This must be at least one, and no more than 2**32-1.*/
|
|
||||||
void ec_enc_uint(ec_enc *_this,ec_uint32 _fl,ec_uint32 _ft);
|
|
||||||
|
|
||||||
/* Encode a bit that has a _prob/65536 probability of being a one */
|
|
||||||
void ec_enc_bit_prob(ec_enc *_this,int val,unsigned _prob);
|
|
||||||
|
|
||||||
/* Encode a bit that has a 1/(1<<_logp) probability of being a one */
|
/* Encode a bit that has a 1/(1<<_logp) probability of being a one */
|
||||||
void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp);
|
void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp);
|
||||||
|
@ -109,22 +70,31 @@ void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp);
|
||||||
_ftb: The number of bits of precision in the cumulative distribution.*/
|
_ftb: The number of bits of precision in the cumulative distribution.*/
|
||||||
void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb);
|
void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb);
|
||||||
|
|
||||||
/*Returns the number of bits "used" by the encoded symbols so far.
|
/*Encodes a raw unsigned integer in the stream.
|
||||||
This same number can be computed by the decoder, and is suitable for making
|
_fl: The integer to encode.
|
||||||
coding decisions.
|
_ft: The number of integers that can be encoded (one more than the max).
|
||||||
_b: The number of extra bits of precision to include.
|
This must be at least one, and no more than 2**32-1.*/
|
||||||
At most 16 will be accurate.
|
void ec_enc_uint(ec_enc *_this,ec_uint32 _fl,ec_uint32 _ft);
|
||||||
Return: The number of bits scaled by 2**_b.
|
|
||||||
This will always be slightly larger than the exact value (e.g., all
|
/*Encodes a sequence of raw bits in the stream.
|
||||||
rounding error is in the positive direction).*/
|
_fl: The bits to encode.
|
||||||
ec_uint32 ec_enc_tell(ec_enc *_this,int _b);
|
_ftb: The number of bits to encode.
|
||||||
|
This must be between 0 and 25, inclusive.*/
|
||||||
|
void ec_enc_bits(ec_enc *_this,ec_uint32 _fl,unsigned _ftb);
|
||||||
|
|
||||||
|
/*Compacts the data to fit in the target size.
|
||||||
|
This moves up the raw bits at the end of the current buffer so they are at
|
||||||
|
the end of the new buffer size.
|
||||||
|
The caller must ensure that the amount of data that's already been written
|
||||||
|
will fit in the new size.
|
||||||
|
_size: The number of bytes in the new buffer.
|
||||||
|
This must be large enough to contain the bits already written, and
|
||||||
|
must be no larger than the existing size.*/
|
||||||
|
void ec_enc_shrink(ec_enc *_this,ec_uint32 _size);
|
||||||
|
|
||||||
/*Indicates that there are no more symbols to encode.
|
/*Indicates that there are no more symbols to encode.
|
||||||
All reamining output bytes are flushed to the output buffer.
|
All reamining output bytes are flushed to the output buffer.
|
||||||
ec_enc_init() must be called before the encoder can be used again.*/
|
ec_enc_init() must be called before the encoder can be used again.*/
|
||||||
void ec_enc_done(ec_enc *_this);
|
void ec_enc_done(ec_enc *_this);
|
||||||
|
|
||||||
/*Returns a nonzero value if any error has been detected during encoding*/
|
|
||||||
int ec_enc_get_error(ec_enc *_this);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -218,7 +218,7 @@ static int quant_coarse_energy_impl(const CELTMode *m, int start, int end,
|
||||||
qi0 = qi;
|
qi0 = qi;
|
||||||
/* If we don't have enough bits to encode all the energy, just assume
|
/* If we don't have enough bits to encode all the energy, just assume
|
||||||
something safe. */
|
something safe. */
|
||||||
tell = ec_enc_tell(enc, 0);
|
tell = ec_tell(enc);
|
||||||
bits_left = budget-tell-3*C*(end-i);
|
bits_left = budget-tell-3*C*(end-i);
|
||||||
if (i!=start && bits_left < 30)
|
if (i!=start && bits_left < 30)
|
||||||
{
|
{
|
||||||
|
@ -272,7 +272,6 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
|
||||||
VARDECL(celt_word16, oldEBands_intra);
|
VARDECL(celt_word16, oldEBands_intra);
|
||||||
VARDECL(celt_word16, error_intra);
|
VARDECL(celt_word16, error_intra);
|
||||||
ec_enc enc_start_state;
|
ec_enc enc_start_state;
|
||||||
ec_byte_buffer buf_start_state;
|
|
||||||
ec_uint32 tell;
|
ec_uint32 tell;
|
||||||
int badness1=0;
|
int badness1=0;
|
||||||
SAVE_STACK;
|
SAVE_STACK;
|
||||||
|
@ -283,7 +282,7 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
|
||||||
else
|
else
|
||||||
*delayedIntra = 0;
|
*delayedIntra = 0;
|
||||||
|
|
||||||
tell = ec_enc_tell(enc, 0);
|
tell = ec_tell(enc);
|
||||||
if (tell+3 > budget)
|
if (tell+3 > budget)
|
||||||
two_pass = intra = 0;
|
two_pass = intra = 0;
|
||||||
|
|
||||||
|
@ -297,7 +296,6 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enc_start_state = *enc;
|
enc_start_state = *enc;
|
||||||
buf_start_state = *(enc->buf);
|
|
||||||
|
|
||||||
ALLOC(oldEBands_intra, C*m->nbEBands, celt_word16);
|
ALLOC(oldEBands_intra, C*m->nbEBands, celt_word16);
|
||||||
ALLOC(error_intra, C*m->nbEBands, celt_word16);
|
ALLOC(error_intra, C*m->nbEBands, celt_word16);
|
||||||
|
@ -312,38 +310,34 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
|
||||||
if (!intra)
|
if (!intra)
|
||||||
{
|
{
|
||||||
ec_enc enc_intra_state;
|
ec_enc enc_intra_state;
|
||||||
ec_byte_buffer buf_intra_state;
|
|
||||||
int tell_intra;
|
int tell_intra;
|
||||||
ec_uint32 nstart_bytes;
|
ec_uint32 nstart_bytes;
|
||||||
ec_uint32 nintra_bytes;
|
ec_uint32 nintra_bytes;
|
||||||
int badness2;
|
int badness2;
|
||||||
VARDECL(unsigned char, intra_bits);
|
VARDECL(unsigned char, intra_bits);
|
||||||
|
|
||||||
tell_intra = ec_enc_tell(enc, 3);
|
tell_intra = ec_tell_frac(enc);
|
||||||
|
|
||||||
enc_intra_state = *enc;
|
enc_intra_state = *enc;
|
||||||
buf_intra_state = *(enc->buf);
|
|
||||||
|
|
||||||
nstart_bytes = ec_byte_bytes(&buf_start_state);
|
nstart_bytes = ec_range_bytes(&enc_start_state);
|
||||||
nintra_bytes = ec_byte_bytes(&buf_intra_state);
|
nintra_bytes = ec_range_bytes(&enc_intra_state);
|
||||||
ALLOC(intra_bits, nintra_bytes-nstart_bytes, unsigned char);
|
ALLOC(intra_bits, nintra_bytes-nstart_bytes, unsigned char);
|
||||||
/* Copy bits from intra bit-stream */
|
/* Copy bits from intra bit-stream */
|
||||||
CELT_COPY(intra_bits,
|
CELT_COPY(intra_bits,
|
||||||
ec_byte_get_buffer(&buf_intra_state) + nstart_bytes,
|
ec_get_buffer(&enc_intra_state) + nstart_bytes,
|
||||||
nintra_bytes - nstart_bytes);
|
nintra_bytes - nstart_bytes);
|
||||||
|
|
||||||
*enc = enc_start_state;
|
*enc = enc_start_state;
|
||||||
*(enc->buf) = buf_start_state;
|
|
||||||
|
|
||||||
badness2 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands, budget,
|
badness2 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands, budget,
|
||||||
tell, e_prob_model[LM][intra], error, enc, C, LM, 0, max_decay);
|
tell, e_prob_model[LM][intra], error, enc, C, LM, 0, max_decay);
|
||||||
|
|
||||||
if (two_pass && (badness1 < badness2 || (badness1 == badness2 && ec_enc_tell(enc, 3) > tell_intra)))
|
if (two_pass && (badness1 < badness2 || (badness1 == badness2 && ec_tell_frac(enc) > tell_intra)))
|
||||||
{
|
{
|
||||||
*enc = enc_intra_state;
|
*enc = enc_intra_state;
|
||||||
*(enc->buf) = buf_intra_state;
|
|
||||||
/* Copy intra bits to bit-stream */
|
/* Copy intra bits to bit-stream */
|
||||||
CELT_COPY(ec_byte_get_buffer(&buf_intra_state) + nstart_bytes,
|
CELT_COPY(ec_get_buffer(&enc_intra_state) + nstart_bytes,
|
||||||
intra_bits, nintra_bytes - nstart_bytes);
|
intra_bits, nintra_bytes - nstart_bytes);
|
||||||
CELT_COPY(oldEBands, oldEBands_intra, C*end);
|
CELT_COPY(oldEBands, oldEBands_intra, C*end);
|
||||||
CELT_COPY(error, error_intra, C*end);
|
CELT_COPY(error, error_intra, C*end);
|
||||||
|
@ -444,7 +438,7 @@ void unquant_coarse_energy(const CELTMode *m, int start, int end, celt_word16 *o
|
||||||
coef = pred_coef[LM];
|
coef = pred_coef[LM];
|
||||||
}
|
}
|
||||||
|
|
||||||
budget = dec->buf->storage*8;
|
budget = dec->storage*8;
|
||||||
|
|
||||||
/* Decode at a fixed coarse resolution */
|
/* Decode at a fixed coarse resolution */
|
||||||
for (i=start;i<end;i++)
|
for (i=start;i<end;i++)
|
||||||
|
@ -454,7 +448,7 @@ void unquant_coarse_energy(const CELTMode *m, int start, int end, celt_word16 *o
|
||||||
int qi;
|
int qi;
|
||||||
celt_word32 q;
|
celt_word32 q;
|
||||||
celt_word32 tmp;
|
celt_word32 tmp;
|
||||||
tell = ec_dec_tell(dec, 0);
|
tell = ec_tell(dec);
|
||||||
if(budget-tell>=15)
|
if(budget-tell>=15)
|
||||||
{
|
{
|
||||||
int pi;
|
int pi;
|
||||||
|
|
|
@ -1,260 +0,0 @@
|
||||||
/* Copyright (c) 2001-2008 Timothy B. Terriberry
|
|
||||||
Copyright (c) 2008-2009 Xiph.Org Foundation */
|
|
||||||
/*
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
|
|
||||||
- Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
|
||||||
contributors may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
|
||||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "arch.h"
|
|
||||||
#include "entdec.h"
|
|
||||||
#include "mfrngcod.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*A range decoder.
|
|
||||||
This is an entropy decoder based upon \cite{Mar79}, which is itself a
|
|
||||||
rediscovery of the FIFO arithmetic code introduced by \cite{Pas76}.
|
|
||||||
It is very similar to arithmetic encoding, except that encoding is done with
|
|
||||||
digits in any base, instead of with bits, and so it is faster when using
|
|
||||||
larger bases (i.e.: a byte).
|
|
||||||
The author claims an average waste of $\frac{1}{2}\log_b(2b)$ bits, where $b$
|
|
||||||
is the base, longer than the theoretical optimum, but to my knowledge there
|
|
||||||
is no published justification for this claim.
|
|
||||||
This only seems true when using near-infinite precision arithmetic so that
|
|
||||||
the process is carried out with no rounding errors.
|
|
||||||
|
|
||||||
IBM (the author's employer) never sought to patent the idea, and to my
|
|
||||||
knowledge the algorithm is unencumbered by any patents, though its
|
|
||||||
performance is very competitive with proprietary arithmetic coding.
|
|
||||||
The two are based on very similar ideas, however.
|
|
||||||
An excellent description of implementation details is available at
|
|
||||||
http://www.arturocampos.com/ac_range.html
|
|
||||||
A recent work \cite{MNW98} which proposes several changes to arithmetic
|
|
||||||
encoding for efficiency actually re-discovers many of the principles
|
|
||||||
behind range encoding, and presents a good theoretical analysis of them.
|
|
||||||
|
|
||||||
End of stream is handled by writing out the smallest number of bits that
|
|
||||||
ensures that the stream will be correctly decoded regardless of the value of
|
|
||||||
any subsequent bits.
|
|
||||||
ec_dec_tell() can be used to determine how many bits were needed to decode
|
|
||||||
all the symbols thus far; other data can be packed in the remaining bits of
|
|
||||||
the input buffer.
|
|
||||||
@PHDTHESIS{Pas76,
|
|
||||||
author="Richard Clark Pasco",
|
|
||||||
title="Source coding algorithms for fast data compression",
|
|
||||||
school="Dept. of Electrical Engineering, Stanford University",
|
|
||||||
address="Stanford, CA",
|
|
||||||
month=May,
|
|
||||||
year=1976
|
|
||||||
}
|
|
||||||
@INPROCEEDINGS{Mar79,
|
|
||||||
author="Martin, G.N.N.",
|
|
||||||
title="Range encoding: an algorithm for removing redundancy from a digitised
|
|
||||||
message",
|
|
||||||
booktitle="Video & Data Recording Conference",
|
|
||||||
year=1979,
|
|
||||||
address="Southampton",
|
|
||||||
month=Jul
|
|
||||||
}
|
|
||||||
@ARTICLE{MNW98,
|
|
||||||
author="Alistair Moffat and Radford Neal and Ian H. Witten",
|
|
||||||
title="Arithmetic Coding Revisited",
|
|
||||||
journal="{ACM} Transactions on Information Systems",
|
|
||||||
year=1998,
|
|
||||||
volume=16,
|
|
||||||
number=3,
|
|
||||||
pages="256--294",
|
|
||||||
month=Jul,
|
|
||||||
URL="http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf"
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
/*Normalizes the contents of dif and rng so that rng lies entirely in the
|
|
||||||
high-order symbol.*/
|
|
||||||
static inline void ec_dec_normalize(ec_dec *_this){
|
|
||||||
/*If the range is too small, rescale it and input some bits.*/
|
|
||||||
while(_this->rng<=EC_CODE_BOT){
|
|
||||||
int sym;
|
|
||||||
_this->nbits_total+=EC_SYM_BITS;
|
|
||||||
_this->rng<<=EC_SYM_BITS;
|
|
||||||
/*Use up the remaining bits from our last symbol.*/
|
|
||||||
sym=_this->rem;
|
|
||||||
/*Read the next value from the input.*/
|
|
||||||
_this->rem=ec_byte_read(_this->buf);
|
|
||||||
/*Take the rest of the bits we need from this new symbol.*/
|
|
||||||
sym=(sym<<EC_SYM_BITS|_this->rem)>>EC_SYM_BITS-EC_CODE_EXTRA;
|
|
||||||
/*And subtract them from dif, capped to be less than EC_CODE_TOP.*/
|
|
||||||
_this->dif=(_this->dif<<EC_SYM_BITS)+(EC_SYM_MAX&~sym)&EC_CODE_TOP-1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ec_dec_init(ec_dec *_this,ec_byte_buffer *_buf){
|
|
||||||
_this->buf=_buf;
|
|
||||||
_this->rem=ec_byte_read(_buf);
|
|
||||||
_this->rng=1U<<EC_CODE_EXTRA;
|
|
||||||
_this->dif=_this->rng-1-(_this->rem>>EC_SYM_BITS-EC_CODE_EXTRA);
|
|
||||||
/*Normalize the interval.*/
|
|
||||||
ec_dec_normalize(_this);
|
|
||||||
_this->end_window=0;
|
|
||||||
_this->nend_bits=0;
|
|
||||||
/*This is the offset from which ec_enc_tell() will subtract partial bits.
|
|
||||||
This must be after the initial ec_dec_normalize(), or you will have to
|
|
||||||
compensate for the bits that are read there.*/
|
|
||||||
_this->nbits_total=EC_CODE_BITS+1;
|
|
||||||
_this->error=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned ec_decode(ec_dec *_this,unsigned _ft){
|
|
||||||
unsigned s;
|
|
||||||
_this->nrm=_this->rng/_ft;
|
|
||||||
s=(unsigned)(_this->dif/_this->nrm);
|
|
||||||
return _ft-EC_MINI(s+1,_ft);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned ec_decode_bin(ec_dec *_this,unsigned _bits){
|
|
||||||
unsigned s;
|
|
||||||
_this->nrm=_this->rng>>_bits;
|
|
||||||
s=(unsigned)(_this->dif/_this->nrm);
|
|
||||||
return (1<<_bits)-EC_MINI(s+1,1<<_bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft){
|
|
||||||
ec_uint32 s;
|
|
||||||
s=IMUL32(_this->nrm,_ft-_fh);
|
|
||||||
_this->dif-=s;
|
|
||||||
_this->rng=_fl>0?IMUL32(_this->nrm,_fh-_fl):_this->rng-s;
|
|
||||||
ec_dec_normalize(_this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*The probability of having a "one" is given in 1/65536.*/
|
|
||||||
int ec_dec_bit_prob(ec_dec *_this,unsigned _prob){
|
|
||||||
ec_uint32 r;
|
|
||||||
ec_uint32 d;
|
|
||||||
ec_uint32 s;
|
|
||||||
int val;
|
|
||||||
r=_this->rng;
|
|
||||||
d=_this->dif;
|
|
||||||
s=(r>>16)*_prob;
|
|
||||||
val=d<s;
|
|
||||||
if(!val)_this->dif=d-s;
|
|
||||||
_this->rng=val?s:r-s;
|
|
||||||
ec_dec_normalize(_this);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*The probability of having a "one" is 1/(1<<_logp).*/
|
|
||||||
int ec_dec_bit_logp(ec_dec *_this,unsigned _logp){
|
|
||||||
ec_uint32 r;
|
|
||||||
ec_uint32 d;
|
|
||||||
ec_uint32 s;
|
|
||||||
int val;
|
|
||||||
r=_this->rng;
|
|
||||||
d=_this->dif;
|
|
||||||
s=r>>_logp;
|
|
||||||
val=d<s;
|
|
||||||
if(!val)_this->dif=d-s;
|
|
||||||
_this->rng=val?s:r-s;
|
|
||||||
ec_dec_normalize(_this);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb){
|
|
||||||
ec_uint32 r;
|
|
||||||
ec_uint32 d;
|
|
||||||
ec_uint32 s;
|
|
||||||
ec_uint32 t;
|
|
||||||
int val;
|
|
||||||
s=_this->rng;
|
|
||||||
d=_this->dif;
|
|
||||||
r=s>>_ftb;
|
|
||||||
val=0;
|
|
||||||
do{
|
|
||||||
t=s;
|
|
||||||
s=IMUL32(r,_icdf[val++]);
|
|
||||||
}
|
|
||||||
while(d<s);
|
|
||||||
_this->dif=d-s;
|
|
||||||
_this->rng=t-s;
|
|
||||||
ec_dec_normalize(_this);
|
|
||||||
return val-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ec_uint32 ec_dec_bits(ec_dec *_this,unsigned _bits){
|
|
||||||
ec_window window;
|
|
||||||
int available;
|
|
||||||
ec_uint32 ret;
|
|
||||||
window=_this->end_window;
|
|
||||||
available=_this->nend_bits;
|
|
||||||
if(available<_bits){
|
|
||||||
do{
|
|
||||||
window|=(ec_window)ec_byte_read_from_end(_this->buf)<<available;
|
|
||||||
available+=EC_SYM_BITS;
|
|
||||||
}
|
|
||||||
while(available<=EC_WINDOW_SIZE-EC_SYM_BITS);
|
|
||||||
}
|
|
||||||
ret=(ec_uint32)window&((ec_uint32)1<<_bits)-1;
|
|
||||||
window>>=_bits;
|
|
||||||
available-=_bits;
|
|
||||||
_this->end_window=window;
|
|
||||||
_this->nend_bits=available;
|
|
||||||
_this->nbits_total+=_bits;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ec_uint32 ec_dec_tell(ec_dec *_this,int _b){
|
|
||||||
ec_uint32 nbits;
|
|
||||||
ec_uint32 r;
|
|
||||||
int l;
|
|
||||||
/*To handle the non-integral number of bits still left in the decoder state,
|
|
||||||
we compute the worst-case number of bits of low that must be encoded to
|
|
||||||
ensure that the value is inside the range for any possible subsequent
|
|
||||||
bits.
|
|
||||||
The computation here is independent of low itself (the decoder does not
|
|
||||||
even track that value), even though the real number of bits used after
|
|
||||||
ec_enc_done() may be 1 smaller if rng is a power of two and the
|
|
||||||
corresponding trailing bits of low are all zeros.
|
|
||||||
If we did try to track that special case, then coding a value with a
|
|
||||||
probability of 1/(1<<n) might sometimes appear to use more than n bits.
|
|
||||||
This may help explain the surprising result that a newly initialized
|
|
||||||
decoder claims to have used 1 bit.*/
|
|
||||||
nbits=_this->nbits_total<<_b;
|
|
||||||
l=EC_ILOG(_this->rng);
|
|
||||||
r=_this->rng>>l-16;
|
|
||||||
while(_b-->0){
|
|
||||||
int b;
|
|
||||||
r=r*r>>15;
|
|
||||||
b=(int)(r>>16);
|
|
||||||
l=l<<1|b;
|
|
||||||
r>>=b;
|
|
||||||
}
|
|
||||||
return nbits-l;
|
|
||||||
}
|
|
|
@ -1,267 +0,0 @@
|
||||||
/* Copyright (c) 2001-2008 Timothy B. Terriberry
|
|
||||||
Copyright (c) 2008-2009 Xiph.Org Foundation */
|
|
||||||
/*
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
|
|
||||||
- Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
|
||||||
contributors may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
|
||||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "arch.h"
|
|
||||||
#include "entenc.h"
|
|
||||||
#include "mfrngcod.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*A range encoder.
|
|
||||||
See rangedec.c and the references for implementation details
|
|
||||||
\cite{Mar79,MNW98}.
|
|
||||||
|
|
||||||
@INPROCEEDINGS{Mar79,
|
|
||||||
author="Martin, G.N.N.",
|
|
||||||
title="Range encoding: an algorithm for removing redundancy from a digitised
|
|
||||||
message",
|
|
||||||
booktitle="Video \& Data Recording Conference",
|
|
||||||
year=1979,
|
|
||||||
address="Southampton",
|
|
||||||
month=Jul
|
|
||||||
}
|
|
||||||
@ARTICLE{MNW98,
|
|
||||||
author="Alistair Moffat and Radford Neal and Ian H. Witten",
|
|
||||||
title="Arithmetic Coding Revisited",
|
|
||||||
journal="{ACM} Transactions on Information Systems",
|
|
||||||
year=1998,
|
|
||||||
volume=16,
|
|
||||||
number=3,
|
|
||||||
pages="256--294",
|
|
||||||
month=Jul,
|
|
||||||
URL="http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf"
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*Outputs a symbol, with a carry bit.
|
|
||||||
If there is a potential to propagate a carry over several symbols, they are
|
|
||||||
buffered until it can be determined whether or not an actual carry will
|
|
||||||
occur.
|
|
||||||
If the counter for the buffered symbols overflows, then the stream becomes
|
|
||||||
undecodable.
|
|
||||||
This gives a theoretical limit of a few billion symbols in a single packet on
|
|
||||||
32-bit systems.
|
|
||||||
The alternative is to truncate the range in order to force a carry, but
|
|
||||||
requires similar carry tracking in the decoder, needlessly slowing it down.*/
|
|
||||||
static void ec_enc_carry_out(ec_enc *_this,int _c){
|
|
||||||
if(_c!=EC_SYM_MAX){
|
|
||||||
/*No further carry propagation possible, flush buffer.*/
|
|
||||||
int carry;
|
|
||||||
carry=_c>>EC_SYM_BITS;
|
|
||||||
/*Don't output a byte on the first write.
|
|
||||||
This compare should be taken care of by branch-prediction thereafter.*/
|
|
||||||
if(_this->rem>=0)_this->error|=ec_byte_write(_this->buf,_this->rem+carry);
|
|
||||||
if(_this->ext>0){
|
|
||||||
unsigned sym;
|
|
||||||
sym=EC_SYM_MAX+carry&EC_SYM_MAX;
|
|
||||||
do _this->error|=ec_byte_write(_this->buf,sym);
|
|
||||||
while(--(_this->ext)>0);
|
|
||||||
}
|
|
||||||
_this->rem=_c&EC_SYM_MAX;
|
|
||||||
}
|
|
||||||
else _this->ext++;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void ec_enc_normalize(ec_enc *_this){
|
|
||||||
/*If the range is too small, output some bits and rescale it.*/
|
|
||||||
while(_this->rng<=EC_CODE_BOT){
|
|
||||||
ec_enc_carry_out(_this,(int)(_this->low>>EC_CODE_SHIFT));
|
|
||||||
/*Move the next-to-high-order symbol into the high-order position.*/
|
|
||||||
_this->low=_this->low<<EC_SYM_BITS&EC_CODE_TOP-1;
|
|
||||||
_this->rng<<=EC_SYM_BITS;
|
|
||||||
_this->nbits_total+=EC_SYM_BITS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ec_enc_init(ec_enc *_this,ec_byte_buffer *_buf){
|
|
||||||
_this->buf=_buf;
|
|
||||||
_this->rem=-1;
|
|
||||||
_this->ext=0;
|
|
||||||
_this->low=0;
|
|
||||||
_this->rng=EC_CODE_TOP;
|
|
||||||
_this->end_window=0;
|
|
||||||
_this->nend_bits=0;
|
|
||||||
/*This is the offset from which ec_enc_tell() will subtract partial bits.*/
|
|
||||||
_this->nbits_total=EC_CODE_BITS+1;
|
|
||||||
_this->error=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft){
|
|
||||||
ec_uint32 r;
|
|
||||||
r=_this->rng/_ft;
|
|
||||||
if(_fl>0){
|
|
||||||
_this->low+=_this->rng-IMUL32(r,(_ft-_fl));
|
|
||||||
_this->rng=IMUL32(r,(_fh-_fl));
|
|
||||||
}
|
|
||||||
else _this->rng-=IMUL32(r,(_ft-_fh));
|
|
||||||
ec_enc_normalize(_this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits){
|
|
||||||
ec_uint32 r;
|
|
||||||
r=_this->rng>>_bits;
|
|
||||||
if(_fl>0){
|
|
||||||
_this->low+=_this->rng-IMUL32(r,((1<<_bits)-_fl));
|
|
||||||
_this->rng=IMUL32(r,(_fh-_fl));
|
|
||||||
}
|
|
||||||
else _this->rng-=IMUL32(r,((1<<_bits)-_fh));
|
|
||||||
ec_enc_normalize(_this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*The probability of having a "one" is given in 1/65536.*/
|
|
||||||
void ec_enc_bit_prob(ec_enc *_this,int _val,unsigned _prob){
|
|
||||||
ec_uint32 r;
|
|
||||||
ec_uint32 s;
|
|
||||||
ec_uint32 l;
|
|
||||||
r=_this->rng;
|
|
||||||
l=_this->low;
|
|
||||||
s=(r>>16)*_prob;
|
|
||||||
r-=s;
|
|
||||||
if(_val)_this->low=l+r;
|
|
||||||
_this->rng=_val?s:r;
|
|
||||||
ec_enc_normalize(_this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*The probability of having a "one" is 1/(1<<_logp).*/
|
|
||||||
void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp){
|
|
||||||
ec_uint32 r;
|
|
||||||
ec_uint32 s;
|
|
||||||
ec_uint32 l;
|
|
||||||
r=_this->rng;
|
|
||||||
l=_this->low;
|
|
||||||
s=r>>_logp;
|
|
||||||
r-=s;
|
|
||||||
if(_val)_this->low=l+r;
|
|
||||||
_this->rng=_val?s:r;
|
|
||||||
ec_enc_normalize(_this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb){
|
|
||||||
ec_uint32 r;
|
|
||||||
r=_this->rng>>_ftb;
|
|
||||||
if(_s>0){
|
|
||||||
_this->low+=_this->rng-IMUL32(r,_icdf[_s-1]);
|
|
||||||
_this->rng=IMUL32(r,_icdf[_s-1]-_icdf[_s]);
|
|
||||||
}
|
|
||||||
else _this->rng-=IMUL32(r,_icdf[_s]);
|
|
||||||
ec_enc_normalize(_this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ec_enc_bits(ec_enc *_this,ec_uint32 _fl,unsigned _bits){
|
|
||||||
ec_window window;
|
|
||||||
int used;
|
|
||||||
window=_this->end_window;
|
|
||||||
used=_this->nend_bits;
|
|
||||||
if(used+_bits>EC_WINDOW_SIZE){
|
|
||||||
do{
|
|
||||||
_this->error|=
|
|
||||||
ec_byte_write_at_end(_this->buf,(unsigned)window&EC_SYM_MAX);
|
|
||||||
window>>=EC_SYM_BITS;
|
|
||||||
used-=EC_SYM_BITS;
|
|
||||||
}
|
|
||||||
while(used>=EC_SYM_BITS);
|
|
||||||
}
|
|
||||||
window|=(ec_window)_fl<<used;
|
|
||||||
used+=_bits;
|
|
||||||
_this->end_window=window;
|
|
||||||
_this->nend_bits=used;
|
|
||||||
_this->nbits_total+=_bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
ec_uint32 ec_enc_tell(ec_enc *_this,int _b){
|
|
||||||
ec_uint32 nbits;
|
|
||||||
ec_uint32 r;
|
|
||||||
int l;
|
|
||||||
/*To handle the non-integral number of bits still left in the decoder state,
|
|
||||||
we compute the worst-case number of bits of low that must be encoded to
|
|
||||||
ensure that the value is inside the range for any possible subsequent
|
|
||||||
bits.
|
|
||||||
The computation here is independent of low itself (the decoder does not
|
|
||||||
even track that value), even though the real number of bits used after
|
|
||||||
ec_enc_done() may be 1 smaller if rng is a power of two and the
|
|
||||||
corresponding trailing bits of low are all zeros.
|
|
||||||
If we did try to track that special case, then coding a value with a
|
|
||||||
probability of 1/(1<<n) might sometimes appear to use more than n bits.
|
|
||||||
This may help explain the surprising result that a newly initialized
|
|
||||||
encoder claims to have used 1 bit.*/
|
|
||||||
nbits=_this->nbits_total<<_b;
|
|
||||||
l=EC_ILOG(_this->rng);
|
|
||||||
r=_this->rng>>l-16;
|
|
||||||
while(_b-->0){
|
|
||||||
int b;
|
|
||||||
r=r*r>>15;
|
|
||||||
b=(int)(r>>16);
|
|
||||||
l=l<<1|b;
|
|
||||||
r>>=b;
|
|
||||||
}
|
|
||||||
return nbits-l;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ec_enc_done(ec_enc *_this){
|
|
||||||
ec_window window;
|
|
||||||
int used;
|
|
||||||
ec_uint32 msk;
|
|
||||||
ec_uint32 end;
|
|
||||||
int l;
|
|
||||||
/*We output the minimum number of bits that ensures that the symbols encoded
|
|
||||||
thus far will be decoded correctly regardless of the bits that follow.*/
|
|
||||||
l=EC_CODE_BITS-EC_ILOG(_this->rng);
|
|
||||||
msk=EC_CODE_TOP-1>>l;
|
|
||||||
end=_this->low+msk&~msk;
|
|
||||||
if((end|msk)>=_this->low+_this->rng){
|
|
||||||
l++;
|
|
||||||
msk>>=1;
|
|
||||||
end=_this->low+msk&~msk;
|
|
||||||
}
|
|
||||||
while(l>0){
|
|
||||||
ec_enc_carry_out(_this,(int)(end>>EC_CODE_SHIFT));
|
|
||||||
end=end<<EC_SYM_BITS&EC_CODE_TOP-1;
|
|
||||||
l-=EC_SYM_BITS;
|
|
||||||
}
|
|
||||||
/*If we have a buffered byte flush it into the output buffer.*/
|
|
||||||
if(_this->rem>=0||_this->ext>0)ec_enc_carry_out(_this,0);
|
|
||||||
/*If we have buffered extra bits, flush them as well.*/
|
|
||||||
window=_this->end_window;
|
|
||||||
used=_this->nend_bits;
|
|
||||||
while(used>=EC_SYM_BITS){
|
|
||||||
_this->error|=
|
|
||||||
ec_byte_write_at_end(_this->buf,(unsigned)window&EC_SYM_MAX);
|
|
||||||
window>>=EC_SYM_BITS;
|
|
||||||
used-=EC_SYM_BITS;
|
|
||||||
}
|
|
||||||
/*Clear any excess space and add any remaining extra bits to the last byte.*/
|
|
||||||
if(!_this->error)_this->error=ec_byte_write_done(_this->buf,-l,window,used);
|
|
||||||
}
|
|
|
@ -254,7 +254,7 @@ void compute_pulse_cache(CELTMode *m, int LM)
|
||||||
static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int skip_start,
|
static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int skip_start,
|
||||||
const int *bits1, const int *bits2, const int *thresh, const int *cap, int total, celt_int32 *_balance,
|
const int *bits1, const int *bits2, const int *thresh, const int *cap, int total, celt_int32 *_balance,
|
||||||
int skip_rsv, int *intensity, int intensity_rsv, int *dual_stereo, int dual_stereo_rsv, int *bits,
|
int skip_rsv, int *intensity, int intensity_rsv, int *dual_stereo, int dual_stereo_rsv, int *bits,
|
||||||
int *ebits, int *fine_priority, int _C, int LM, void *ec, int encode, int prev)
|
int *ebits, int *fine_priority, int _C, int LM, ec_ctx *ec, int encode, int prev)
|
||||||
{
|
{
|
||||||
int psum;
|
int psum;
|
||||||
int lo, hi;
|
int lo, hi;
|
||||||
|
@ -359,11 +359,11 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int
|
||||||
fluctuating in and out.*/
|
fluctuating in and out.*/
|
||||||
if (band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4)
|
if (band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4)
|
||||||
{
|
{
|
||||||
ec_enc_bit_logp((ec_enc *)ec, 1, 1);
|
ec_enc_bit_logp(ec, 1, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ec_enc_bit_logp((ec_enc *)ec, 0, 1);
|
ec_enc_bit_logp(ec, 0, 1);
|
||||||
} else if (ec_dec_bit_logp((ec_dec *)ec, 1)) {
|
} else if (ec_dec_bit_logp(ec, 1)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*We used a bit to skip this band.*/
|
/*We used a bit to skip this band.*/
|
||||||
|
@ -393,10 +393,10 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int
|
||||||
if (encode)
|
if (encode)
|
||||||
{
|
{
|
||||||
*intensity = IMIN(*intensity, codedBands);
|
*intensity = IMIN(*intensity, codedBands);
|
||||||
ec_enc_uint((ec_enc *)ec, *intensity-start, codedBands+1-start);
|
ec_enc_uint(ec, *intensity-start, codedBands+1-start);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*intensity = start+ec_dec_uint((ec_dec *)ec, codedBands+1-start);
|
*intensity = start+ec_dec_uint(ec, codedBands+1-start);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*intensity = 0;
|
*intensity = 0;
|
||||||
|
@ -408,9 +408,9 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int
|
||||||
if (dual_stereo_rsv > 0)
|
if (dual_stereo_rsv > 0)
|
||||||
{
|
{
|
||||||
if (encode)
|
if (encode)
|
||||||
ec_enc_bit_logp((ec_enc *)ec, *dual_stereo, 1);
|
ec_enc_bit_logp(ec, *dual_stereo, 1);
|
||||||
else
|
else
|
||||||
*dual_stereo = ec_dec_bit_logp((ec_dec *)ec, 1);
|
*dual_stereo = ec_dec_bit_logp(ec, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*dual_stereo = 0;
|
*dual_stereo = 0;
|
||||||
|
@ -527,7 +527,7 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int
|
||||||
}
|
}
|
||||||
|
|
||||||
int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stereo,
|
int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stereo,
|
||||||
int total, celt_int32 *balance, int *pulses, int *ebits, int *fine_priority, int _C, int LM, void *ec, int encode, int prev)
|
int total, celt_int32 *balance, int *pulses, int *ebits, int *fine_priority, int _C, int LM, ec_ctx *ec, int encode, int prev)
|
||||||
{
|
{
|
||||||
int lo, hi, len, j;
|
int lo, hi, len, j;
|
||||||
const int C = CHANNELS(_C);
|
const int C = CHANNELS(_C);
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
|
|
||||||
#define MAX_FINE_BITS 8
|
#define MAX_FINE_BITS 8
|
||||||
|
|
||||||
#define BITRES 3
|
|
||||||
#define FINE_OFFSET 21
|
#define FINE_OFFSET 21
|
||||||
#define QTHETA_OFFSET 4
|
#define QTHETA_OFFSET 4
|
||||||
#define QTHETA_OFFSET_TWOPHASE 16
|
#define QTHETA_OFFSET_TWOPHASE 16
|
||||||
|
@ -106,7 +105,7 @@ celt_int16 **compute_alloc_cache(CELTMode *m, int M);
|
||||||
@return Total number of bits allocated
|
@return Total number of bits allocated
|
||||||
*/
|
*/
|
||||||
int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stero,
|
int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stero,
|
||||||
int total, celt_int32 *balance, int *pulses, int *ebits, int *fine_priority, int _C, int LM, void *ec, int encode, int prev);
|
int total, celt_int32 *balance, int *pulses, int *ebits, int *fine_priority, int _C, int LM, ec_ctx *ec, int encode, int prev);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
|
|
||||||
#define CELT_C
|
#define CELT_C
|
||||||
#include "../libcelt/stack_alloc.h"
|
#include "../libcelt/stack_alloc.h"
|
||||||
#include "../libcelt/rangeenc.c"
|
|
||||||
#include "../libcelt/rangedec.c"
|
|
||||||
#include "../libcelt/entenc.c"
|
#include "../libcelt/entenc.c"
|
||||||
#include "../libcelt/entdec.c"
|
#include "../libcelt/entdec.c"
|
||||||
#include "../libcelt/entcode.c"
|
#include "../libcelt/entcode.c"
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
#include "entdec.h"
|
#include "entdec.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "../libcelt/rangeenc.c"
|
|
||||||
#include "../libcelt/rangedec.c"
|
|
||||||
#include "../libcelt/entenc.c"
|
#include "../libcelt/entenc.c"
|
||||||
#include "../libcelt/entdec.c"
|
#include "../libcelt/entdec.c"
|
||||||
#include "../libcelt/entcode.c"
|
#include "../libcelt/entcode.c"
|
||||||
|
@ -24,7 +22,6 @@
|
||||||
#define DATA_SIZE2 10000
|
#define DATA_SIZE2 10000
|
||||||
|
|
||||||
int main(int _argc,char **_argv){
|
int main(int _argc,char **_argv){
|
||||||
ec_byte_buffer buf;
|
|
||||||
ec_enc enc;
|
ec_enc enc;
|
||||||
ec_dec dec;
|
ec_dec dec;
|
||||||
long nbits;
|
long nbits;
|
||||||
|
@ -50,8 +47,7 @@ int main(int _argc,char **_argv){
|
||||||
seed = time(NULL);
|
seed = time(NULL);
|
||||||
/*Testing encoding of raw bit values.*/
|
/*Testing encoding of raw bit values.*/
|
||||||
ptr = malloc(DATA_SIZE);
|
ptr = malloc(DATA_SIZE);
|
||||||
ec_byte_writeinit_buffer(&buf, ptr, DATA_SIZE);
|
ec_enc_init(&enc,ptr, DATA_SIZE);
|
||||||
ec_enc_init(&enc,&buf);
|
|
||||||
for(ft=2;ft<1024;ft++){
|
for(ft=2;ft<1024;ft++){
|
||||||
for(i=0;i<ft;i++){
|
for(i=0;i<ft;i++){
|
||||||
entropy+=log(ft)*M_LOG2E;
|
entropy+=log(ft)*M_LOG2E;
|
||||||
|
@ -62,9 +58,9 @@ int main(int _argc,char **_argv){
|
||||||
for(ftb=0;ftb<16;ftb++){
|
for(ftb=0;ftb<16;ftb++){
|
||||||
for(i=0;i<(1<<ftb);i++){
|
for(i=0;i<(1<<ftb);i++){
|
||||||
entropy+=ftb;
|
entropy+=ftb;
|
||||||
nbits=ec_enc_tell(&enc,0);
|
nbits=ec_tell(&enc);
|
||||||
ec_enc_bits(&enc,i,ftb);
|
ec_enc_bits(&enc,i,ftb);
|
||||||
nbits2=ec_enc_tell(&enc,0);
|
nbits2=ec_tell(&enc);
|
||||||
if(nbits2-nbits!=ftb){
|
if(nbits2-nbits!=ftb){
|
||||||
fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
|
fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
|
||||||
nbits2-nbits,ftb);
|
nbits2-nbits,ftb);
|
||||||
|
@ -72,14 +68,13 @@ int main(int _argc,char **_argv){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nbits=ec_enc_tell(&enc,4);
|
nbits=ec_tell_frac(&enc);
|
||||||
ec_enc_done(&enc);
|
ec_enc_done(&enc);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Encoded %0.2lf bits of entropy to %0.2lf bits (%0.3lf%% wasted).\n",
|
"Encoded %0.2lf bits of entropy to %0.2lf bits (%0.3lf%% wasted).\n",
|
||||||
entropy,ldexp(nbits,-4),100*(nbits-ldexp(entropy,4))/nbits);
|
entropy,ldexp(nbits,-3),100*(nbits-ldexp(entropy,3))/nbits);
|
||||||
fprintf(stderr,"Packed to %li bytes.\n",(long)ec_byte_bytes(&buf));
|
fprintf(stderr,"Packed to %li bytes.\n",(long)ec_range_bytes(&enc));
|
||||||
ec_byte_readinit(&buf,ptr,DATA_SIZE);
|
ec_dec_init(&dec,ptr,DATA_SIZE);
|
||||||
ec_dec_init(&dec,&buf);
|
|
||||||
for(ft=2;ft<1024;ft++){
|
for(ft=2;ft<1024;ft++){
|
||||||
for(i=0;i<ft;i++){
|
for(i=0;i<ft;i++){
|
||||||
sym=ec_dec_uint(&dec,ft);
|
sym=ec_dec_uint(&dec,ft);
|
||||||
|
@ -98,11 +93,11 @@ int main(int _argc,char **_argv){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nbits2=ec_dec_tell(&dec,4);
|
nbits2=ec_tell_frac(&dec);
|
||||||
if(nbits!=nbits2){
|
if(nbits!=nbits2){
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Reported number of bits used was %0.2lf, should be %0.2lf.\n",
|
"Reported number of bits used was %0.2lf, should be %0.2lf.\n",
|
||||||
ldexp(nbits2,-4),ldexp(nbits,-4));
|
ldexp(nbits2,-3),ldexp(nbits,-3));
|
||||||
ret=-1;
|
ret=-1;
|
||||||
}
|
}
|
||||||
srand(seed);
|
srand(seed);
|
||||||
|
@ -117,41 +112,39 @@ int main(int _argc,char **_argv){
|
||||||
sz=rand()/((RAND_MAX>>(rand()%9))+1);
|
sz=rand()/((RAND_MAX>>(rand()%9))+1);
|
||||||
data=(unsigned *)malloc(sz*sizeof(*data));
|
data=(unsigned *)malloc(sz*sizeof(*data));
|
||||||
tell=(unsigned *)malloc((sz+1)*sizeof(*tell));
|
tell=(unsigned *)malloc((sz+1)*sizeof(*tell));
|
||||||
ec_byte_writeinit_buffer(&buf, ptr, DATA_SIZE2);
|
ec_enc_init(&enc,ptr,DATA_SIZE2);
|
||||||
ec_enc_init(&enc,&buf);
|
|
||||||
zeros = rand()%13==0;
|
zeros = rand()%13==0;
|
||||||
tell[0]=ec_enc_tell(&enc, 3);
|
tell[0]=ec_tell_frac(&enc);
|
||||||
for(j=0;j<sz;j++){
|
for(j=0;j<sz;j++){
|
||||||
if (zeros)
|
if (zeros)
|
||||||
data[j]=0;
|
data[j]=0;
|
||||||
else
|
else
|
||||||
data[j]=rand()%ft;
|
data[j]=rand()%ft;
|
||||||
ec_enc_uint(&enc,data[j],ft);
|
ec_enc_uint(&enc,data[j],ft);
|
||||||
tell[j+1]=ec_enc_tell(&enc, 3);
|
tell[j+1]=ec_tell_frac(&enc);
|
||||||
}
|
}
|
||||||
if (rand()%2==0)
|
if (rand()%2==0)
|
||||||
while(ec_enc_tell(&enc, 0)%8 != 0)
|
while(ec_tell(&enc)%8 != 0)
|
||||||
ec_enc_uint(&enc, rand()%2, 2);
|
ec_enc_uint(&enc, rand()%2, 2);
|
||||||
tell_bits = ec_enc_tell(&enc, 0);
|
tell_bits = ec_tell(&enc);
|
||||||
ec_enc_done(&enc);
|
ec_enc_done(&enc);
|
||||||
if(tell_bits!=ec_enc_tell(&enc,0)){
|
if(tell_bits!=ec_tell(&enc)){
|
||||||
fprintf(stderr,"tell() changed after ec_enc_done(): %i instead of %i (Random seed: %u)\n",
|
fprintf(stderr,"ec_tell() changed after ec_enc_done(): %i instead of %i (Random seed: %u)\n",
|
||||||
ec_enc_tell(&enc,0),tell_bits,seed);
|
ec_tell(&enc),tell_bits,seed);
|
||||||
ret=-1;
|
ret=-1;
|
||||||
}
|
}
|
||||||
if ((tell_bits+7)/8 < ec_byte_bytes(&buf))
|
if ((tell_bits+7)/8 < ec_range_bytes(&enc))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "tell() lied, there's %i bytes instead of %d (Random seed: %u)\n",
|
fprintf (stderr, "ec_tell() lied, there's %i bytes instead of %d (Random seed: %u)\n",
|
||||||
ec_byte_bytes(&buf), (tell_bits+7)/8,seed);
|
ec_range_bytes(&enc), (tell_bits+7)/8,seed);
|
||||||
ret=-1;
|
ret=-1;
|
||||||
}
|
}
|
||||||
tell_bits -= 8*ec_byte_bytes(&buf);
|
tell_bits -= 8*ec_range_bytes(&enc);
|
||||||
ec_byte_readinit(&buf,ptr,DATA_SIZE2);
|
ec_dec_init(&dec,ptr,DATA_SIZE2);
|
||||||
ec_dec_init(&dec,&buf);
|
if(ec_tell_frac(&dec)!=tell[0]){
|
||||||
if(ec_dec_tell(&dec,3)!=tell[0]){
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
|
"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
|
||||||
0,ec_dec_tell(&dec,3),tell[0],seed);
|
0,ec_tell_frac(&dec),tell[0],seed);
|
||||||
}
|
}
|
||||||
for(j=0;j<sz;j++){
|
for(j=0;j<sz;j++){
|
||||||
sym=ec_dec_uint(&dec,ft);
|
sym=ec_dec_uint(&dec,ft);
|
||||||
|
@ -161,10 +154,10 @@ int main(int _argc,char **_argv){
|
||||||
sym,data[j],ft,j,sz,seed);
|
sym,data[j],ft,j,sz,seed);
|
||||||
ret=-1;
|
ret=-1;
|
||||||
}
|
}
|
||||||
if(ec_dec_tell(&dec,3)!=tell[j+1]){
|
if(ec_tell_frac(&dec)!=tell[j+1]){
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
|
"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
|
||||||
j+1,ec_dec_tell(&dec,3),tell[j+1],seed);
|
j+1,ec_tell_frac(&dec),tell[j+1],seed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(tell);
|
free(tell);
|
||||||
|
@ -182,9 +175,8 @@ int main(int _argc,char **_argv){
|
||||||
data=(unsigned *)malloc(sz*sizeof(*data));
|
data=(unsigned *)malloc(sz*sizeof(*data));
|
||||||
tell=(unsigned *)malloc((sz+1)*sizeof(*tell));
|
tell=(unsigned *)malloc((sz+1)*sizeof(*tell));
|
||||||
enc_method=(unsigned *)malloc(sz*sizeof(*enc_method));
|
enc_method=(unsigned *)malloc(sz*sizeof(*enc_method));
|
||||||
ec_byte_writeinit_buffer(&buf, ptr, DATA_SIZE2);
|
ec_enc_init(&enc,ptr,DATA_SIZE2);
|
||||||
ec_enc_init(&enc,&buf);
|
tell[0]=ec_tell_frac(&enc);
|
||||||
tell[0]=ec_enc_tell(&enc,3);
|
|
||||||
for(j=0;j<sz;j++){
|
for(j=0;j<sz;j++){
|
||||||
data[j]=rand()/((RAND_MAX>>1)+1);
|
data[j]=rand()/((RAND_MAX>>1)+1);
|
||||||
logp1[j]=(rand()%15)+1;
|
logp1[j]=(rand()%15)+1;
|
||||||
|
@ -208,20 +200,19 @@ int main(int _argc,char **_argv){
|
||||||
ec_enc_icdf(&enc,data[j],icdf,logp1[j]);
|
ec_enc_icdf(&enc,data[j],icdf,logp1[j]);
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
tell[j+1]=ec_enc_tell(&enc,3);
|
tell[j+1]=ec_tell_frac(&enc);
|
||||||
}
|
}
|
||||||
ec_enc_done(&enc);
|
ec_enc_done(&enc);
|
||||||
if((ec_enc_tell(&enc,0)+7)/8<ec_byte_bytes(&buf)){
|
if((ec_tell(&enc)+7)/8<ec_range_bytes(&enc)){
|
||||||
fprintf(stderr,"tell() lied, there's %i bytes instead of %d (Random seed: %u)\n",
|
fprintf(stderr,"tell() lied, there's %i bytes instead of %d (Random seed: %u)\n",
|
||||||
ec_byte_bytes(&buf),(ec_enc_tell(&enc,0)+7)/8,seed);
|
ec_range_bytes(&enc),(ec_tell(&enc)+7)/8,seed);
|
||||||
ret=-1;
|
ret=-1;
|
||||||
}
|
}
|
||||||
ec_byte_readinit(&buf,ptr,DATA_SIZE2);
|
ec_dec_init(&dec,ptr,DATA_SIZE2);
|
||||||
ec_dec_init(&dec,&buf);
|
if(ec_tell_frac(&dec)!=tell[0]){
|
||||||
if(ec_dec_tell(&dec,3)!=tell[0]){
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
|
"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
|
||||||
0,ec_dec_tell(&dec,3),tell[0],seed);
|
0,ec_tell_frac(&dec),tell[0],seed);
|
||||||
}
|
}
|
||||||
for(j=0;j<sz;j++){
|
for(j=0;j<sz;j++){
|
||||||
int fs;
|
int fs;
|
||||||
|
@ -258,10 +249,10 @@ int main(int _argc,char **_argv){
|
||||||
enc_method[j],dec_method);
|
enc_method[j],dec_method);
|
||||||
ret=-1;
|
ret=-1;
|
||||||
}
|
}
|
||||||
if(ec_dec_tell(&dec,3)!=tell[j+1]){
|
if(ec_tell_frac(&dec)!=tell[j+1]){
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
|
"Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
|
||||||
j+1,ec_dec_tell(&dec,3),tell[j+1],seed);
|
j+1,ec_tell_frac(&dec),tell[j+1],seed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(enc_method);
|
free(enc_method);
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
#define CELT_C
|
#define CELT_C
|
||||||
#include "../libcelt/stack_alloc.h"
|
#include "../libcelt/stack_alloc.h"
|
||||||
|
|
||||||
#include "../libcelt/rangeenc.c"
|
|
||||||
#include "../libcelt/rangedec.c"
|
|
||||||
#include "../libcelt/entenc.c"
|
#include "../libcelt/entenc.c"
|
||||||
#include "../libcelt/entdec.c"
|
#include "../libcelt/entdec.c"
|
||||||
#include "../libcelt/entcode.c"
|
#include "../libcelt/entcode.c"
|
||||||
|
@ -30,14 +28,11 @@ int main(void)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
ec_enc enc;
|
ec_enc enc;
|
||||||
ec_dec dec;
|
ec_dec dec;
|
||||||
ec_byte_buffer buf;
|
|
||||||
unsigned char *ptr;
|
unsigned char *ptr;
|
||||||
int val[10000], decay[10000];
|
int val[10000], decay[10000];
|
||||||
ALLOC_STACK;
|
ALLOC_STACK;
|
||||||
ptr = malloc(DATA_SIZE);
|
ptr = malloc(DATA_SIZE);
|
||||||
ec_byte_writeinit_buffer(&buf, ptr, DATA_SIZE);
|
ec_enc_init(&enc,ptr,DATA_SIZE);
|
||||||
//ec_byte_writeinit(&buf);
|
|
||||||
ec_enc_init(&enc,&buf);
|
|
||||||
|
|
||||||
val[0] = 3; decay[0] = 6000;
|
val[0] = 3; decay[0] = 6000;
|
||||||
val[1] = 0; decay[1] = 5800;
|
val[1] = 0; decay[1] = 5800;
|
||||||
|
@ -53,8 +48,7 @@ int main(void)
|
||||||
|
|
||||||
ec_enc_done(&enc);
|
ec_enc_done(&enc);
|
||||||
|
|
||||||
ec_byte_readinit(&buf,ec_byte_get_buffer(&buf),ec_byte_bytes(&buf));
|
ec_dec_init(&dec,ec_get_buffer(&enc),ec_range_bytes(&enc));
|
||||||
ec_dec_init(&dec,&buf);
|
|
||||||
|
|
||||||
for (i=0;i<10000;i++)
|
for (i=0;i<10000;i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -168,7 +168,7 @@ int async_tandem(int rate, int frame_size, int channels, int bitrate_min,
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
#ifdef CUSTOM_MODES
|
#ifdef CUSTOM_MODES
|
||||||
int sizes[8]={960,480,240,120,512,256,128,64};
|
int sizes[8]={960,512,480,256,240,128,120,64};
|
||||||
#else
|
#else
|
||||||
int sizes[4]={960,480,240,120};
|
int sizes[4]={960,480,240,120};
|
||||||
#endif
|
#endif
|
||||||
|
@ -193,8 +193,8 @@ int main(int argc, char *argv[])
|
||||||
for (ch = 1; ch <= 2; ch++) {
|
for (ch = 1; ch <= 2; ch++) {
|
||||||
async_tandem(48000, sizes[n], ch, 12000 * ch, 128000 * ch);
|
async_tandem(48000, sizes[n], ch, 12000 * ch, 128000 * ch);
|
||||||
async_tandem(44100, sizes[n], ch, 12000 * ch, 128000 * ch);
|
async_tandem(44100, sizes[n], ch, 12000 * ch, 128000 * ch);
|
||||||
async_tandem(32000, sizes[n], ch, 12000 * ch, 128000 * ch);
|
if(n>0)async_tandem(32000, sizes[n], ch, 12000 * ch, 128000 * ch);
|
||||||
async_tandem(16000, sizes[n], ch, 12000 * ch, 64000 * ch);
|
if(n>2)async_tandem(16000, sizes[n], ch, 12000 * ch, 64000 * ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue