shithub: opus

Download patch

ref: 9c937631215577e96e377b2c6aa6ad8f700efeda
parent: de3e16c858ac240303f1626b93d53a52b080c1a2
parent: ed921b01bcbe65fabe853607630866af81bc5da5
author: Jean-Marc Valin <[email protected]>
date: Sun Oct 2 20:51:32 EDT 2011

Merge remote-tracking branch 'greg/master'

Conflicts:
	src/opus_encoder.c

--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -88,8 +88,9 @@
    CELTDecoder *celt_dec;
    int ret, silkDecSizeBytes;
 
-   if (channels<1 || channels > 2)
+   if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2))
       return OPUS_BAD_ARG;
+
    OPUS_CLEAR((char*)st, opus_decoder_get_size(channels));
    /* Initialize SILK encoder */
    ret = silk_Get_Decoder_Size(&silkDecSizeBytes);
@@ -122,6 +123,12 @@
 OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error)
 {
    int ret;
+   if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2))
+   {
+      if (error)
+         *error = OPUS_BAD_ARG;
+      return NULL;
+   }
    OpusDecoder *st = (OpusDecoder *)opus_alloc(opus_decoder_get_size(channels));
    if (st == NULL)
    {
@@ -659,7 +666,7 @@
 	tot_offset += offset;
 
 	if (count*st->frame_size > frame_size)
-		return OPUS_BAD_ARG;
+		return OPUS_BUFFER_TOO_SMALL;
 	nb_samples=0;
 	for (i=0;i<count;i++)
 	{
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -77,6 +77,7 @@
     int          mode;
     int          prev_mode;
     int          prev_channels;
+    int          prev_framesize;
     int          bandwidth;
     /* Sampling rate (at the API level) */
     int          first;
@@ -143,13 +144,10 @@
     int err;
     int ret, silkEncSizeBytes;
 
-    if (channels > 2 || channels < 1)
+   if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)||
+        (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO
+        && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY))
         return OPUS_BAD_ARG;
-    if (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO
-     && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY)
-        return OPUS_BAD_ARG;
-    if (Fs != 8000 && Fs != 12000 && Fs != 16000 && Fs != 24000 && Fs != 48000)
-        return OPUS_BAD_ARG;
 
     OPUS_CLEAR((char*)st, opus_encoder_get_size(channels));
     /* Create SILK encoder */
@@ -358,9 +356,17 @@
     }
 }
 
-OpusEncoder *opus_encoder_create(opus_int32 Fs, int channels, int mode, int *error)
+OpusEncoder *opus_encoder_create(opus_int32 Fs, int channels, int application, int *error)
 {
    int ret;
+   if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)||
+       (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO
+       && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY))
+   {
+      if (error)
+         *error = OPUS_BAD_ARG;
+      return NULL;
+   }
    OpusEncoder *st = (OpusEncoder *)opus_alloc(opus_encoder_get_size(channels));
    if (st == NULL)
    {
@@ -368,7 +374,7 @@
          *error = OPUS_ALLOC_FAIL;
       return NULL;
    }
-   ret = opus_encoder_init(st, Fs, channels, mode);
+   ret = opus_encoder_init(st, Fs, channels, application);
    if (error)
       *error = ret;
    if (ret != OPUS_OK)
@@ -378,6 +384,18 @@
    }
    return st;
 }
+
+static opus_int32 user_bitrate_to_bitrate(OpusEncoder *st, int frame_size, int max_data_bytes)
+{
+  if(!frame_size)frame_size=st->Fs/400;
+  if (st->user_bitrate_bps==OPUS_AUTO)
+    return 60*st->Fs/frame_size + st->Fs*st->channels;
+  else if (st->user_bitrate_bps==OPUS_BITRATE_MAX)
+    return max_data_bytes*8*st->Fs/frame_size;
+  else
+    return st->user_bitrate_bps;
+}
+
 #ifdef FIXED_POINT
 #define opus_encode_native opus_encode
 int opus_encode(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
@@ -428,12 +446,7 @@
     else
        delay_compensation = st->delay_compensation;
 
-    if (st->user_bitrate_bps==OPUS_AUTO)
-        st->bitrate_bps = 60*st->Fs/frame_size + st->Fs*st->channels;
-    else if (st->user_bitrate_bps==OPUS_BITRATE_MAX)
-       st->bitrate_bps = max_data_bytes*8*st->Fs/frame_size;
-    else
-        st->bitrate_bps = st->user_bitrate_bps;
+    st->bitrate_bps = user_bitrate_to_bitrate(st, frame_size, max_data_bytes);
 
     /* Equivalent 20-ms rate for mode/channel/bandwidth decisions */
     equiv_rate = st->bitrate_bps - 60*(st->Fs/frame_size - 50);
@@ -988,6 +1001,7 @@
     else
         st->prev_mode = st->mode;
     st->prev_channels = st->stream_channels;
+    st->prev_framesize = frame_size;
 
     st->first = 0;
     RESTORE_STACK;
@@ -1062,7 +1076,7 @@
         case OPUS_GET_APPLICATION_REQUEST:
         {
             opus_int32 *value = va_arg(ap, opus_int32*);
-            *value = st->mode;
+            *value = st->application;
         }
         break;
         case OPUS_SET_BITRATE_REQUEST:
@@ -1083,12 +1097,14 @@
         case OPUS_GET_BITRATE_REQUEST:
         {
             opus_int32 *value = va_arg(ap, opus_int32*);
-            *value = st->bitrate_bps;
+            *value = user_bitrate_to_bitrate(st, st->prev_framesize, 1276);
         }
         break;
         case OPUS_SET_FORCE_CHANNELS_REQUEST:
         {
             opus_int32 value = va_arg(ap, opus_int32);
+            if(value<1 || value>st->channels)
+                return OPUS_BAD_ARG;
             st->force_channels = value;
         }
         break;
@@ -1106,7 +1122,7 @@
             st->user_bandwidth = value;
             if (st->user_bandwidth == OPUS_BANDWIDTH_NARROWBAND) {
                 st->silk_mode.maxInternalSampleRate = 8000;
-            } else if (st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) {
+            } else if (st->user_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) {
                 st->silk_mode.maxInternalSampleRate = 12000;
             } else {
                 st->silk_mode.maxInternalSampleRate = 16000;
@@ -1122,6 +1138,8 @@
         case OPUS_SET_DTX_REQUEST:
         {
             opus_int32 value = va_arg(ap, opus_int32);
+            if(value<0 || value>1)
+                return OPUS_BAD_ARG;
             st->silk_mode.useDTX = value;
         }
         break;
@@ -1134,6 +1152,8 @@
         case OPUS_SET_COMPLEXITY_REQUEST:
         {
             opus_int32 value = va_arg(ap, opus_int32);
+            if(value<0 || value>10)
+                return OPUS_BAD_ARG;
             st->silk_mode.complexity = value;
             celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(value));
         }
@@ -1147,6 +1167,8 @@
         case OPUS_SET_INBAND_FEC_REQUEST:
         {
             opus_int32 value = va_arg(ap, opus_int32);
+            if(value<0 || value>1)
+                return OPUS_BAD_ARG;
             st->silk_mode.useInBandFEC = value;
         }
         break;
@@ -1174,6 +1196,8 @@
         case OPUS_SET_VBR_REQUEST:
         {
             opus_int32 value = va_arg(ap, opus_int32);
+            if(value<0 || value>1)
+                return OPUS_BAD_ARG;
             st->use_vbr = value;
             st->silk_mode.useCBR = 1-value;
         }
@@ -1201,6 +1225,8 @@
         case OPUS_SET_VBR_CONSTRAINT_REQUEST:
         {
             opus_int32 value = va_arg(ap, opus_int32);
+            if(value<0 || value>1)
+                return OPUS_BAD_ARG;
             st->vbr_constraint = value;
         }
         break;
@@ -1213,6 +1239,8 @@
         case OPUS_SET_SIGNAL_REQUEST:
         {
             opus_int32 value = va_arg(ap, opus_int32);
+            if(value!=OPUS_AUTO && value!=OPUS_SIGNAL_VOICE && value!=OPUS_SIGNAL_MUSIC)
+                return OPUS_BAD_ARG;
             st->signal_type = value;
         }
         break;
@@ -1259,7 +1287,7 @@
         case OPUS_SET_FORCE_MODE_REQUEST:
         {
             opus_int32 value = va_arg(ap, opus_int32);
-            if (value < MODE_SILK_ONLY || value > MODE_CELT_ONLY)
+            if ((value < MODE_SILK_ONLY || value > MODE_CELT_ONLY) && value != OPUS_AUTO)
                goto bad_arg;
             st->user_forced_mode = value;
         }