Bit of cleaning up in the byte dumping part. Making use of any remaining bit(s)
authorJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Sun, 27 Jan 2008 06:34:35 +0000 (17:34 +1100)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Sun, 27 Jan 2008 06:34:35 +0000 (17:34 +1100)
to do error detection in the decoder.

libcelt/bands.c
libcelt/celt.c
libcelt/celt.h

index 026eae9..f637546 100644 (file)
@@ -240,6 +240,7 @@ void quant_bands(const CELTMode *m, float *X, float *P, float *W, struct alloc_d
    
    for (i=0;i<m->nbEBands;i++)
       offsets[i] = 0;
+   /* Use a single-bit margin to guard against overrunning (make sure it's enough) */
    bits = total_bits - ec_enc_tell(enc, 0) - 1;
    compute_allocation(alloc, offsets, bits, pulses);
    
@@ -291,6 +292,7 @@ void unquant_bands(const CELTMode *m, float *X, float *P, struct alloc_data *all
    
    for (i=0;i<m->nbEBands;i++)
       offsets[i] = 0;
+   /* Use a single-bit margin to guard against overrunning (make sure it's enough) */
    bits = total_bits - ec_dec_tell(dec, 0) - 1;
    compute_allocation(alloc, offsets, bits, pulses);
 
index bef0be9..e2af3a7 100644 (file)
@@ -379,28 +379,32 @@ int celt_encode(CELTEncoder *st, short *pcm, unsigned char *compressed, int nbCo
       }
    }
    
-   /* Not sure why, but filling the rest with zeros tends to help */
-   while (ec_enc_tell(&st->enc, 0) < nbCompressedBytes*8)
-      ec_enc_uint(&st->enc, 0, 2);
+   //printf ("%d\n", ec_enc_tell(&st->enc, 0)-8*nbCompressedBytes);
+   /* Finishing the stream with a 0101... pattern so that the decoder can check is everything's right */
+   {
+      int val = 0;
+      while (ec_enc_tell(&st->enc, 0) < nbCompressedBytes*8)
+      {
+         ec_enc_uint(&st->enc, val, 2);
+         val = 1-val;
+      }
+   }
    ec_enc_done(&st->enc);
    {
       unsigned char *data;
       int nbBytes = ec_byte_bytes(&st->buf);
-      if (nbBytes > nbCompressedBytes)
+      if (nbBytes != nbCompressedBytes)
       {
-         celt_warning("got too many bytes");
+         if (nbBytes > nbCompressedBytes)
+            celt_warning("got too many bytes");
+         else
+            celt_warning("not enough bytes");
          return CELT_INTERNAL_ERROR;
       }
       //printf ("%d\n", *nbBytes);
       data = ec_byte_get_buffer(&st->buf);
       for (i=0;i<nbBytes;i++)
          compressed[i] = data[i];
-      
-      /* Fill the last byte with the right pattern so the decoder doesn't get confused
-         if the encoder didn't return enough bytes */
-      /* FIXME: This isn't quite what the decoder expects, but it's the best we can do for now */
-      for (;i<nbCompressedBytes;i++)
-         compressed[i] = 0x00;
    }
    /* Reset the packing for the next encoding */
    ec_byte_reset(&st->buf);
@@ -409,21 +413,6 @@ int celt_encode(CELTEncoder *st, short *pcm, unsigned char *compressed, int nbCo
    return nbCompressedBytes;
 }
 
-char *celt_encoder_get_bytes(CELTEncoder *st, int *nbBytes)
-{
-   char *data;
-   ec_enc_done(&st->enc);
-   *nbBytes = ec_byte_bytes(&st->buf);
-   data = ec_byte_get_buffer(&st->buf);
-   //printf ("%d\n", *nbBytes);
-   
-   /* Reset the packing for the next encoding */
-   ec_byte_reset(&st->buf);
-   ec_enc_init(&st->enc,&st->buf);
-
-   return data;
-}
-
 
 /****************************************************************************/
 /*                                                                          */
@@ -640,6 +629,19 @@ int celt_decode(CELTDecoder *st, char *data, int len, short *pcm)
       }
    }
 
+   {
+      int val = 0;
+      while (ec_dec_tell(&dec, 0) < len*8)
+      {
+         if (ec_dec_uint(&dec, 2) != val)
+         {
+            celt_warning("decode error");
+            return CELT_CORRUPTED_DATA;
+         }
+         val = 1-val;
+      }
+   }
+
    return 0;
    //printf ("\n");
 }
index bfa0156..130abc3 100644 (file)
 extern "C" {
 #endif
 
-#define CELT_BAD_ARG -1
-#define CELT_INVALID_MODE -2
-#define CELT_INTERNAL_ERROR -3
-#define CELT_CORRUPTED_DATA -4
+#define CELT_OK                0
+#define CELT_BAD_ARG          -1
+#define CELT_INVALID_MODE     -2
+#define CELT_INTERNAL_ERROR   -3
+#define CELT_CORRUPTED_DATA   -4
 
 
 typedef struct CELTEncoder CELTEncoder;