Encoder now has a way to check whether an error has occurred
authorJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Sun, 18 Jul 2010 13:42:05 +0000 (09:42 -0400)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Sun, 18 Jul 2010 13:42:05 +0000 (09:42 -0400)
libcelt/bands.c
libcelt/celt.c
libcelt/entcode.h
libcelt/entenc.c
libcelt/entenc.h
libcelt/quant_bands.c
libcelt/rangeenc.c
libcelt/testcelt.c

index 84b2c31..b995478 100644 (file)
@@ -173,8 +173,7 @@ void denormalise_bands(const CELTMode *m, const celt_norm * restrict X, celt_sig
    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;
index 0cab155..587aed4 100644 (file)
@@ -1104,7 +1104,10 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, c
    ec_enc_done(enc);
    
    RESTORE_STACK;
-   return nbCompressedBytes;
+   if (enc->error)
+      return CELT_CORRUPTED_DATA;
+   else
+      return nbCompressedBytes;
 }
 
 #ifdef FIXED_POINT
index 64fca13..ee1d1d9 100644 (file)
@@ -64,8 +64,8 @@ void ec_byte_writeinit_buffer(ec_byte_buffer *_b, unsigned char *_buf, long _siz
 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);
index 9ae9fc6..ce04350 100644 (file)
@@ -49,21 +49,25 @@ void ec_byte_shrink(ec_byte_buffer *_b, long _size){
    _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;
 }
 
 
index d0bb734..abc6ba2 100644 (file)
@@ -57,6 +57,8 @@ struct ec_enc{
    /*Number of valid bits in end_byte*/
    int             end_bits_left;
    int             nb_end_bits;
+   /*Nonzero is an error occurred*/
+   int             error;
 };
 
 
index af2b7e1..484c024 100644 (file)
@@ -121,6 +121,8 @@ unsigned quant_coarse_energy(const CELTMode *m, int start, int end, const celt_w
          /* 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);
index 68ff6c4..9f874b2 100644 (file)
@@ -83,11 +83,11 @@ static void ec_enc_carry_out(ec_enc *_this,int _c){
     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 @@ void ec_enc_init(ec_enc *_this,ec_byte_buffer *_buf){
   _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 @@ void ec_encode_raw(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned bits){
   {
     _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;
index 87f1c30..28d3461 100644 (file)
@@ -137,7 +137,7 @@ int main(int argc, char *argv[])
       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 */