Error checking on the decoder side
authorJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Mon, 19 Jul 2010 01:20:35 +0000 (21:20 -0400)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Mon, 19 Jul 2010 01:20:35 +0000 (21:20 -0400)
libcelt/celt.c
libcelt/entdec.c
libcelt/entdec.h
libcelt/entenc.c
libcelt/entenc.h
libcelt/rangedec.c
libcelt/testcelt.c

index 587aed4..5adaee2 100644 (file)
@@ -1104,7 +1104,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, c
    ec_enc_done(enc);
    
    RESTORE_STACK;
-   if (enc->error)
+   if (ec_enc_get_error(enc))
       return CELT_CORRUPTED_DATA;
    else
       return nbCompressedBytes;
@@ -1734,7 +1734,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
    {
       celt_decode_lost(st, pcm, N, LM);
       RESTORE_STACK;
-      return 0;
+      return CELT_OK;
    }
    if (len<0) {
      RESTORE_STACK;
@@ -1785,6 +1785,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
       if (maxpitch<0)
       {
          celt_notify("detected pitch when not allowed, bit corruption suspected");
+         dec->error |= 1;
          pitch_index = 0;
          has_pitch = 0;
       } else {
@@ -1856,7 +1857,10 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
    deemphasis(st->out_mem, pcm, N, C, st->mode->preemph, st->preemph_memD);
    st->loss_count = 0;
    RESTORE_STACK;
-   return 0;
+   if (ec_dec_get_error(dec))
+      return CELT_CORRUPTED_DATA;
+   else
+      return CELT_OK;
 }
 
 #ifdef FIXED_POINT
@@ -1888,8 +1892,9 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
    
    ALLOC(out, C*N, celt_int16);
    ret=celt_decode_with_ec(st, data, len, out, frame_size, dec);
-   for (j=0;j<C*N;j++)
-      pcm[j]=out[j]*(1/32768.);
+   if (ret==0)
+      for (j=0;j<C*N;j++)
+         pcm[j]=out[j]*(1/32768.);
      
    RESTORE_STACK;
    return ret;
@@ -1924,8 +1929,9 @@ int celt_decode_with_ec(CELTDecoder * restrict st, const unsigned char *data, in
 
    ret=celt_decode_with_ec_float(st, data, len, out, frame_size, dec);
 
-   for (j=0;j<C*N;j++)
-      pcm[j] = FLOAT2INT16 (out[j]);
+   if (ret==0)
+      for (j=0;j<C*N;j++)
+         pcm[j] = FLOAT2INT16 (out[j]);
    
    RESTORE_STACK;
    return ret;
index 5b8846b..b29eae1 100644 (file)
@@ -99,8 +99,9 @@ ec_uint32 ec_dec_uint(ec_dec *_this,ec_uint32 _ft){
     t = t<<ftb|ec_dec_bits(_this,ftb);
     if (t>_ft)
     {
-       celt_notify("uint decode error");
-       t = _ft;
+      celt_notify("uint decode error");
+      _this->error |= 1;
+      t = _ft;
     }
     return t;
   } else {
@@ -111,3 +112,8 @@ ec_uint32 ec_dec_uint(ec_dec *_this,ec_uint32 _ft){
     return t;
   }
 }
+
+int ec_dec_get_error(ec_dec *_this)
+{
+  return _this->error || (ec_dec_tell(_this,0) > 8*_this->buf->storage);
+}
index d672d88..7e9d127 100644 (file)
@@ -56,6 +56,8 @@ struct ec_dec{
    /*Number of valid bits in end_byte*/
    int             end_bits_left;
    int             nb_end_bits;
+   /*Nonzero if an error occurred*/
+   int             error;
 };
 
 
@@ -123,4 +125,7 @@ int ec_dec_bit_prob(ec_dec *_this,unsigned _prob);
            rounding error is in the positive direction).*/
 long ec_dec_tell(ec_dec *_this,int _b);
 
+/*Returns a nonzero value if any error has been detected during decoding*/
+int ec_dec_get_error(ec_dec *_this);
+
 #endif
index ce04350..82f208e 100644 (file)
@@ -102,3 +102,8 @@ void ec_enc_uint(ec_enc *_this,ec_uint32 _fl,ec_uint32 _ft){
     ec_encode(_this,_fl,_fl+1,_ft+1);
   }
 }
+
+int ec_enc_get_error(ec_enc *_this)
+{
+  return _this->error;
+}
index abc6ba2..09abe9f 100644 (file)
@@ -57,7 +57,7 @@ struct ec_enc{
    /*Number of valid bits in end_byte*/
    int             end_bits_left;
    int             nb_end_bits;
-   /*Nonzero is an error occurred*/
+   /*Nonzero if an error occurred*/
    int             error;
 };
 
@@ -111,4 +111,7 @@ long ec_enc_tell(ec_enc *_this,int _b);
   ec_enc_init() must be called before the encoder can be used again.*/
 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
index fc83aa6..65a5e60 100644 (file)
@@ -144,6 +144,7 @@ void ec_dec_init(ec_dec *_this,ec_byte_buffer *_buf){
   /*_this->end_byte=ec_byte_look_at_end(_this->buf);*/
   _this->end_bits_left=0;
   _this->nb_end_bits=0;
+  _this->error=0;
 }
 
 
index 28d3461..7fa511c 100644 (file)
@@ -136,10 +136,8 @@ int main(int argc, char *argv[])
          break;
       len = celt_encode_resynthesis(enc, in, in, frame_size, data, bytes_per_packet);
       if (len <= 0)
-      {
-         fprintf (stderr, "celt_encode() returned an error: %s\n", celt_strerror(len));
-         return 1;
-      }
+         fprintf (stderr, "celt_encode() failed: %s\n", celt_strerror(len));
+
       /* This is for simulating bit errors */
 #if 0
       int errors = 0;
@@ -162,13 +160,16 @@ int main(int argc, char *argv[])
       else if (errors%2 == 1)
          data[rand()%8] ^= 1<<rand()%8;
 #endif
+
 #if 1 /* Set to zero to use the encoder's output instead */
       /* This is to simulate packet loss */
       if (argc==9 && rand()%1000<atoi(argv[argc-3]))
       /*if (errors && (errors%2==0))*/
-         celt_decode(dec, NULL, len, out, frame_size);
+         err = celt_decode(dec, NULL, len, out, frame_size);
       else
-         celt_decode(dec, data, len, out, frame_size);
+         err = celt_decode(dec, data, len, out, frame_size);
+      if (err != 0)
+         fprintf(stderr, "celt_decode() failed: %s\n", celt_strerror(err));
 #else
       for (i=0;i<frame_size*channels;i++)
          out[i] = in[i];