Non-fatal bit-stream errors are now reported through ctl()
authorJean-Marc Valin <jean-marc.valin@octasic.com>
Fri, 18 Mar 2011 19:34:11 +0000 (15:34 -0400)
committerJean-Marc Valin <jean-marc.valin@octasic.com>
Fri, 18 Mar 2011 19:34:11 +0000 (15:34 -0400)
libcelt/celt.c
libcelt/celt.h
libcelt/modes.c

index b6711ae..f615091 100644 (file)
@@ -1626,7 +1626,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
 
    RESTORE_STACK;
    if (ec_get_error(enc))
-      return CELT_CORRUPTED_DATA;
+      return CELT_INTERNAL_ERROR;
    else
       return nbCompressedBytes;
 }
@@ -1839,6 +1839,7 @@ struct CELTDecoder {
 #define DECODER_RESET_START rng
 
    celt_uint32 rng;
+   int error;
    int last_pitch_index;
    int loss_count;
    int postfilter_period;
@@ -2279,7 +2280,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
       if (LM>st->mode->maxLM)
          return CELT_CORRUPTED_DATA;
       if (frame_size < st->mode->shortMdctSize<<LM)
-         return CELT_BAD_ARG;
+         return CELT_BUFFER_TOO_SMALL;
       else
          frame_size = st->mode->shortMdctSize<<LM;
    } else {
@@ -2571,10 +2572,11 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
    deemphasis(out_syn, pcm, N, CC, st->downsample, st->mode->preemph, st->preemph_memD);
    st->loss_count = 0;
    RESTORE_STACK;
-   if (ec_tell(dec) > 8*len || ec_get_error(dec))
-      return CELT_CORRUPTED_DATA;
-   else
-      return frame_size/st->downsample;
+   if (ec_tell(dec) > 8*len)
+      return CELT_INTERNAL_ERROR;
+   if(ec_get_error(dec))
+      st->error = 1;
+   return frame_size/st->downsample;
 }
 
 #ifdef FIXED_POINT
@@ -2687,6 +2689,15 @@ int celt_decoder_ctl(CELTDecoder * restrict st, int request, ...)
          st->signalling = value;
       }
       break;
+      case CELT_GET_AND_CLEAR_ERROR_REQUEST:
+      {
+         int *value = va_arg(ap, int*);
+         if (value==NULL)
+            goto bad_arg;
+         *value=st->error;
+         st->error = 0;
+      }
+      break;
       case CELT_RESET_STATE:
       {
          CELT_MEMSET((char*)&st->DECODER_RESET_START, 0,
index 008e525..91dcc5e 100644 (file)
@@ -51,6 +51,7 @@ extern "C" {
 
 #define _celt_check_int(x) (((void)((x) == (celt_int32)0)), (celt_int32)(x))
 #define _celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (CELTMode**)(ptr)))
+#define _celt_check_int_ptr(ptr) ((ptr) + ((ptr) - (int*)(ptr)))
 
 /* Error codes */
 /** No error */
@@ -58,7 +59,7 @@ extern "C" {
 /** An (or more) invalid argument (e.g. out of range) */
 #define CELT_BAD_ARG          -1
 /** The mode struct passed is invalid */
-#define CELT_INVALID_MODE     -2
+#define CELT_BUFFER_TOO_SMALL -2
 /** An internal error was detected */
 #define CELT_INTERNAL_ERROR   -3
 /** The data passed (e.g. compressed data to decoder) is corrupted */
@@ -104,6 +105,10 @@ extern "C" {
 #define CELT_SET_INPUT_CLIPPING_REQUEST    14
 #define CELT_SET_INPUT_CLIPPING(x) CELT_SET_INPUT_CLIPPING_REQUEST, _celt_check_int(x)
 
+#define CELT_GET_AND_CLEAR_ERROR_REQUEST   15
+#define CELT_GET_AND_CLEAR_ERROR(x) CELT_GET_AND_CLEAR_ERROR_REQUEST, _celt_check_int_ptr(x)
+
+/* Internal */
 #define CELT_SET_START_BAND_REQUEST    10000
 #define CELT_SET_START_BAND(x) CELT_SET_START_BAND_REQUEST, _celt_check_int(x)
 
index 7649143..7aa6eba 100644 (file)
@@ -308,7 +308,7 @@ CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error)
    if ((celt_int32)frame_size*1000 < Fs)
    {
       if (error)
-         *error = CELT_INVALID_MODE;
+         *error = CELT_BAD_ARG;
       return NULL;
    }
 
@@ -330,7 +330,7 @@ CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error)
    if ((celt_int32)(frame_size>>LM)*300 > Fs)
    {
       if (error)
-         *error = CELT_INVALID_MODE;
+         *error = CELT_BAD_ARG;
       return NULL;
    }
 
@@ -425,7 +425,7 @@ CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error)
    return mode;
 failure: 
    if (error)
-      *error = CELT_INVALID_MODE;
+      *error = CELT_ALLOC_FAIL;
    if (mode!=NULL)
       celt_mode_destroy(mode);
    return NULL;