shithub: opus

Download patch

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 */