Removed all the silk_ prefixes in source file names (not symbols)
[opus.git] / src / opus_decoder.c
index 4361e5b..c607edf 100644 (file)
 #include "opus.h"
 #include "entdec.h"
 #include "modes.h"
-#include "silk_API.h"
+#include "API.h"
 #include "stack_alloc.h"
 #include "float_cast.h"
 #include "opus_private.h"
 #include "os_support.h"
+#include "structs.h"
+#include "define.h"
 
 struct OpusDecoder {
    int          celt_dec_offset;
@@ -70,6 +72,8 @@ int opus_decoder_get_size(int channels)
 {
    int silkDecSizeBytes, celtDecSizeBytes;
    int ret;
+   if (channels<1 || channels > 2)
+      return 0;
    ret = silk_Get_Decoder_Size( &silkDecSizeBytes );
    if(ret)
       return 0;
@@ -88,10 +92,9 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels)
       return OPUS_BAD_ARG;
    OPUS_CLEAR((char*)st, opus_decoder_get_size(channels));
    /* Initialize SILK encoder */
-   ret = silk_Get_Decoder_Size( &silkDecSizeBytes );
-   if( ret ) {
-      return OPUS_INTERNAL_ERROR;
-   }
+   ret = silk_Get_Decoder_Size(&silkDecSizeBytes);
+   if(ret)return OPUS_INTERNAL_ERROR;
+
    silkDecSizeBytes = align(silkDecSizeBytes);
    st->silk_dec_offset = align(sizeof(OpusDecoder));
    st->celt_dec_offset = st->silk_dec_offset+silkDecSizeBytes;
@@ -103,22 +106,17 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels)
 
    /* Reset decoder */
    ret = silk_InitDecoder( silk_dec );
-   if( ret ) {
-      goto failure;
-   }
+   if(ret)return OPUS_INTERNAL_ERROR;
 
    /* Initialize CELT decoder */
    ret = celt_decoder_init(celt_dec, Fs, channels);
-   if (ret != OPUS_OK)
-      goto failure;
+   if(ret!=OPUS_OK)return OPUS_INTERNAL_ERROR;
+
    celt_decoder_ctl(celt_dec, CELT_SET_SIGNALLING(0));
 
    st->prev_mode = 0;
    st->frame_size = Fs/400;
    return OPUS_OK;
-failure:
-   opus_free(st);
-   return OPUS_INTERNAL_ERROR;
 }
 
 OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error)
@@ -279,7 +277,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
                 DecControl.internalSampleRate = 16000;
             } else {
                DecControl.internalSampleRate = 16000;
-                SKP_assert( 0 );
+                silk_assert( 0 );
             }
         } else {
             /* Hybrid mode */
@@ -301,7 +299,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
                                pcm_ptr[i] = 0;
                } else {
                   RESTORE_STACK;
-                  return OPUS_CORRUPTED_DATA;
+                  return OPUS_INVALID_PACKET;
                }
             }
             pcm_ptr += silk_frame_size * st->channels;
@@ -310,7 +308,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
     }
 
     start_band = 0;
-    if (mode != MODE_CELT_ONLY && data != NULL)
+    if (mode != MODE_CELT_ONLY && data != NULL && ec_tell(&dec)+29+8*(st->mode == MODE_HYBRID) < 8*len)
     {
         /* Check if we have a redundant 0-8 kHz band */
         redundancy = ec_dec_bit_logp(&dec, 12);
@@ -329,9 +327,11 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
                }
             }
             len -= redundancy_bytes;
-            if (len<0) {
-               RESTORE_STACK;
-               return OPUS_CORRUPTED_DATA;
+            if (len<0)
+            {
+               len=0;
+               redundancy_bytes=0;
+               redundancy = 0;
             }
             /* Shrink decoder because of raw bits */
             dec.storage -= redundancy_bytes;
@@ -508,7 +508,7 @@ static int opus_packet_parse_impl(const unsigned char *data, int len,
       if (!self_delimited)
       {
          if (len&0x1)
-            return OPUS_CORRUPTED_DATA;
+            return OPUS_INVALID_PACKET;
          size[0] = last_size = len/2;
       }
       break;
@@ -518,19 +518,19 @@ static int opus_packet_parse_impl(const unsigned char *data, int len,
       bytes = parse_size(data, len, size);
       len -= bytes;
       if (size[0]<0 || size[0] > len)
-         return OPUS_CORRUPTED_DATA;
+         return OPUS_INVALID_PACKET;
       data += bytes;
       last_size = len-size[0];
       break;
       /* Multiple CBR/VBR frames (from 0 to 120 ms) */
    case 3:
       if (len<1)
-         return OPUS_CORRUPTED_DATA;
+         return OPUS_INVALID_PACKET;
       /* Number of frames encoded in bits 0 to 5 */
       ch = *data++;
       count = ch&0x3F;
       if (count <= 0 || framesize*count > 5760)
-          return OPUS_CORRUPTED_DATA;
+          return OPUS_INVALID_PACKET;
       len--;
       /* Padding flag is bit 6 */
       if (ch&0x40)
@@ -539,7 +539,7 @@ static int opus_packet_parse_impl(const unsigned char *data, int len,
          int p;
          do {
             if (len<=0)
-               return OPUS_CORRUPTED_DATA;
+               return OPUS_INVALID_PACKET;
             p = *data++;
             len--;
             padding += p==255 ? 254: p;
@@ -547,10 +547,10 @@ static int opus_packet_parse_impl(const unsigned char *data, int len,
          len -= padding;
       }
       if (len<0)
-         return OPUS_CORRUPTED_DATA;
+         return OPUS_INVALID_PACKET;
       /* VBR flag is bit 7 */
       cbr = !(ch&0x80);
-      if (cbr)
+      if (!cbr)
       {
          /* VBR case */
          last_size = len;
@@ -559,18 +559,18 @@ static int opus_packet_parse_impl(const unsigned char *data, int len,
             bytes = parse_size(data, len, size+i);
             len -= bytes;
             if (size[i]<0 || size[i] > len)
-               return OPUS_CORRUPTED_DATA;
+               return OPUS_INVALID_PACKET;
             data += bytes;
             last_size -= bytes+size[i];
          }
          if (last_size<0)
-            return OPUS_CORRUPTED_DATA;
+            return OPUS_INVALID_PACKET;
       } else if (!self_delimited)
       {
          /* CBR case */
          last_size = len/count;
          if (last_size*count!=len)
-            return OPUS_CORRUPTED_DATA;
+            return OPUS_INVALID_PACKET;
          for (i=0;i<count-1;i++)
             size[i] = last_size;
       }
@@ -582,17 +582,17 @@ static int opus_packet_parse_impl(const unsigned char *data, int len,
       bytes = parse_size(data, len, size+count-1);
       len -= bytes;
       if (size[count-1]<0 || size[count-1] > len)
-         return OPUS_CORRUPTED_DATA;
+         return OPUS_INVALID_PACKET;
       data += bytes;
       /* For CBR packets, apply the size to all the frames. */
       if (cbr)
       {
          if (size[count-1]*count > len)
-            return OPUS_CORRUPTED_DATA;
+            return OPUS_INVALID_PACKET;
          for (i=0;i<count-1;i++)
             size[i] = size[count-1];
       } else if(size[count-1] > last_size)
-         return OPUS_CORRUPTED_DATA;
+         return OPUS_INVALID_PACKET;
    } else
    {
       /* Because it's not encoded explicitly, it's possible the size of the
@@ -600,7 +600,7 @@ static int opus_packet_parse_impl(const unsigned char *data, int len,
           1275.
          Reject them here.*/
       if (last_size > 1275)
-        return OPUS_CORRUPTED_DATA;
+        return OPUS_INVALID_PACKET;
       size[count-1] = last_size;
    }
 
@@ -639,6 +639,7 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data,
        int tot_offset;
        /* 48 x 2.5 ms = 120 ms */
        short size[48];
+       if (decode_fec<0 || decode_fec>1)return OPUS_BAD_ARG;
        if (len==0 || data==NULL)
            return opus_decode_frame(st, NULL, 0, pcm, frame_size, 0);
        else if (len<0)
@@ -738,6 +739,12 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
 {
    int ret = OPUS_OK;
    va_list ap;
+   void *silk_dec;
+   CELTDecoder *celt_dec;
+
+   silk_dec = (char*)st+st->silk_dec_offset;
+   celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
+
 
    va_start(ap, request);
 
@@ -757,14 +764,8 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
    break;
    case OPUS_RESET_STATE:
    {
-      void *silk_dec;
-      CELTDecoder *celt_dec;
-
-      silk_dec = (char*)st+st->silk_dec_offset;
-      celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
-
       OPUS_CLEAR((char*)&st->OPUS_DECODER_RESET_START,
-            opus_decoder_get_size(st->channels)-
+            sizeof(OpusDecoder)-
             ((char*)&st->OPUS_DECODER_RESET_START - (char*)st));
 
       celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
@@ -773,6 +774,22 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
       st->frame_size = st->Fs/400;
    }
    break;
+   case OPUS_GET_PITCH_REQUEST:
+   {
+      int *value = va_arg(ap, opus_int32*);
+      if (value==NULL)
+      {
+         ret = OPUS_BAD_ARG;
+         break;
+      }
+      if (st->prev_mode == MODE_CELT_ONLY)
+         celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value));
+      else
+         *value = ((silk_decoder_state*)silk_dec)->indices.signalType == TYPE_VOICED
+         ? ((silk_decoder_state*)silk_dec)->lagPrev*48/((silk_decoder_state*)silk_dec)->fs_kHz
+         : 0;
+   }
+   break;
    default:
       /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/
       ret = OPUS_UNIMPLEMENTED;
@@ -844,7 +861,7 @@ int opus_packet_get_nb_frames(const unsigned char packet[], int len)
        else if (count!=3)
                return 2;
        else if (len<2)
-               return OPUS_CORRUPTED_DATA;
+               return OPUS_INVALID_PACKET;
        else
                return packet[1]&0x3F;
 }
@@ -856,7 +873,7 @@ int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char pack
        samples = count*opus_packet_get_samples_per_frame(packet, dec->Fs);
        /* Can't have more than 120 ms */
        if (samples*25 > dec->Fs*3)
-               return OPUS_CORRUPTED_DATA;
+               return OPUS_INVALID_PACKET;
        else
                return samples;
 }