ref: 9d785afb677256b26c5c51ad08e5b321f9ec7640
parent: 8952c45ea54a5608cd61fe2e137e39d0c3b19853
author: Jean-Marc Valin <[email protected]>
date: Sun Jul 18 05:42:05 EDT 2010
Encoder now has a way to check whether an error has occurred
--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -173,8 +173,7 @@
const celt_int16 *eBands = m->eBands;
const int C = CHANNELS(_C);
N = M*m->shortMdctSize;
- if (C>2)
- celt_fatal("denormalise_bands() not implemented for >2 channels");
+ celt_assert2(C<=2, "denormalise_bands() not implemented for >2 channels");
for (c=0;c<C;c++)
{
celt_sig * restrict f;
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -1104,7 +1104,10 @@
ec_enc_done(enc);
RESTORE_STACK;
- return nbCompressedBytes;
+ if (enc->error)
+ return CELT_CORRUPTED_DATA;
+ else
+ return nbCompressedBytes;
}
#ifdef FIXED_POINT
--- a/libcelt/entcode.h
+++ b/libcelt/entcode.h
@@ -64,8 +64,8 @@
void ec_byte_shrink(ec_byte_buffer *_b, long _size);
void ec_byte_writeinit(ec_byte_buffer *_b);
void ec_byte_writetrunc(ec_byte_buffer *_b,long _bytes);
-void ec_byte_write1(ec_byte_buffer *_b,unsigned _value);
-void ec_byte_write_at_end(ec_byte_buffer *_b,unsigned _value);
+int ec_byte_write1(ec_byte_buffer *_b,unsigned _value);
+int ec_byte_write_at_end(ec_byte_buffer *_b,unsigned _value);
void ec_byte_write4(ec_byte_buffer *_b,ec_uint32 _value);
void ec_byte_writecopy(ec_byte_buffer *_b,void *_source,long _bytes);
void ec_byte_writeclear(ec_byte_buffer *_b);
--- a/libcelt/entenc.c
+++ b/libcelt/entenc.c
@@ -49,21 +49,25 @@
_b->storage=_size;
}
-void ec_byte_write1(ec_byte_buffer *_b,unsigned _value){
+int ec_byte_write1(ec_byte_buffer *_b,unsigned _value){
ptrdiff_t endbyte;
endbyte=_b->ptr-_b->buf;
if(endbyte>=_b->storage){
- celt_fatal("range encoder overflow\n");
+ return 1;
+ } else {
+ *(_b->ptr++)=(unsigned char)_value;
+ return 0;
}
- *(_b->ptr++)=(unsigned char)_value;
}
-void ec_byte_write_at_end(ec_byte_buffer *_b,unsigned _value){
+int ec_byte_write_at_end(ec_byte_buffer *_b,unsigned _value){
if (_b->end_ptr < _b->ptr)
{
- celt_fatal("byte buffer collision");
+ return 1;
+ } else {
+ *(_b->end_ptr--)=(unsigned char)_value;
+ return 0;
}
- *(_b->end_ptr--)=(unsigned char)_value;
}
--- a/libcelt/entenc.h
+++ b/libcelt/entenc.h
@@ -57,6 +57,8 @@
/*Number of valid bits in end_byte*/
int end_bits_left;
int nb_end_bits;
+ /*Nonzero is an error occurred*/
+ int error;
};
--- a/libcelt/quant_bands.c
+++ b/libcelt/quant_bands.c
@@ -121,6 +121,8 @@
/* Rounding to nearest integer here is really important! */
qi = (int)floor(.5f+f);
#endif
+ /* Prevent the energy from going down too quickly (e.g. for bands
+ that have just one bin) */
if (qi < 0 && x < oldEBands[i+c*m->nbEBands]-max_decay)
{
qi += SHR16(oldEBands[i+c*m->nbEBands]-max_decay-x, DB_SHIFT);
--- a/libcelt/rangeenc.c
+++ b/libcelt/rangeenc.c
@@ -83,11 +83,11 @@
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)ec_byte_write1(_this->buf,_this->rem+carry);
+ if(_this->rem>=0)_this->error|=ec_byte_write1(_this->buf,_this->rem+carry);
if(_this->ext>0){
unsigned sym;
sym=EC_SYM_MAX+carry&EC_SYM_MAX;
- do ec_byte_write1(_this->buf,sym);
+ do _this->error|=ec_byte_write1(_this->buf,sym);
while(--(_this->ext)>0);
}
_this->rem=_c&EC_SYM_MAX;
@@ -114,6 +114,7 @@
_this->end_byte=0;
_this->end_bits_left=8;
_this->nb_end_bits=0;
+ _this->error=0;
}
void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft){
@@ -158,7 +159,7 @@
{
_this->end_byte |= (_fl<<(8-_this->end_bits_left)) & 0xff;
_fl >>= _this->end_bits_left;
- ec_byte_write_at_end(_this->buf, _this->end_byte);
+ _this->error|=ec_byte_write_at_end(_this->buf, _this->end_byte);
_this->end_byte = 0;
bits -= _this->end_bits_left;
_this->end_bits_left = 8;
--- a/libcelt/testcelt.c
+++ b/libcelt/testcelt.c
@@ -137,7 +137,7 @@
len = celt_encode_resynthesis(enc, in, in, frame_size, data, bytes_per_packet);
if (len <= 0)
{
- fprintf (stderr, "celt_encode() returned %d\n", len);
+ fprintf (stderr, "celt_encode() returned an error: %s\n", celt_strerror(len));
return 1;
}
/* This is for simulating bit errors */