Fixes a rare integer overflow in the SILK "50% of max rate" rule
[opus.git] / src / opus_encoder.c
index 327d3cf..e9a6c25 100644 (file)
@@ -123,6 +123,11 @@ static const opus_int32 mode_thresholds[2][2] = {
       {  48000,      24000}, /* mono */
       {  48000,      24000}, /* stereo */
 };
+
+static const int celt_delay_table[5] = {
+/* API 8  12  16  24  48 */
+      10, 16, 21, 27, 55
+};
 int opus_encoder_get_size(int channels)
 {
     int silkEncSizeBytes, celtEncSizeBytes;
@@ -202,14 +207,8 @@ int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int applicat
     st->encoder_buffer = st->Fs/100;
 
     st->delay_compensation = st->Fs/400;
-    /* This part is meant to compensate for the resampler delay as a function
-       of the API sampling rate */
-    if (st->Fs == 48000)
-        st->delay_compensation += 23;
-    else if (st->Fs == 24000)
-       st->delay_compensation += 15;
-    else
-       st->delay_compensation += 2;
+
+    st->delay_compensation += celt_delay_table[rateID(st->Fs)];
 
     st->hybrid_stereo_width_Q14             = 1 << 14;
     st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );
@@ -359,6 +358,7 @@ static void stereo_fade(const opus_val16 *in, opus_val16 *out, opus_val16 g1, op
 OpusEncoder *opus_encoder_create(opus_int32 Fs, int channels, int application, int *error)
 {
    int ret;
+   OpusEncoder *st;
    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))
@@ -367,7 +367,7 @@ OpusEncoder *opus_encoder_create(opus_int32 Fs, int channels, int application, i
          *error = OPUS_BAD_ARG;
       return NULL;
    }
-   OpusEncoder *st = (OpusEncoder *)opus_alloc(opus_encoder_get_size(channels));
+   st = (OpusEncoder *)opus_alloc(opus_encoder_get_size(channels));
    if (st == NULL)
    {
       if (error)
@@ -462,67 +462,52 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
     else
        voice_est = 64;
 
-#ifdef FUZZING
-    /* Random mono/stereo decision */
-    if (st->channels == 2 && (rand()&0x1F)==0)
-       st->stream_channels = 3-st->stream_channels;
-#else
-    /* Rate-dependent mono-stereo decision */
     if (st->force_channels!=OPUS_AUTO && st->channels == 2)
     {
         st->stream_channels = st->force_channels;
-    } else if (st->channels == 2)
-    {
-       opus_int32 stereo_threshold;
-       stereo_threshold = stereo_music_threshold + ((voice_est*voice_est*(stereo_voice_threshold-stereo_music_threshold))>>14);
-       if (st->stream_channels == 2)
-          stereo_threshold -= 4000;
-       else
-          stereo_threshold += 4000;
-       st->stream_channels = (equiv_rate > stereo_threshold) ? 2 : 1;
     } else {
-            st->stream_channels = st->channels;
-    }
+#ifdef FUZZING
+       /* Random mono/stereo decision */
+       if (st->channels == 2 && (rand()&0x1F)==0)
+          st->stream_channels = 3-st->stream_channels;
+#else
+       /* Rate-dependent mono-stereo decision */
+       if (st->channels == 2)
+       {
+          opus_int32 stereo_threshold;
+          stereo_threshold = stereo_music_threshold + ((voice_est*voice_est*(stereo_voice_threshold-stereo_music_threshold))>>14);
+          if (st->stream_channels == 2)
+             stereo_threshold -= 4000;
+          else
+             stereo_threshold += 4000;
+          st->stream_channels = (equiv_rate > stereo_threshold) ? 2 : 1;
+       } else {
+          st->stream_channels = st->channels;
+       }
 #endif
-
-    if (st->silk_mode.toMono==1 && st->stream_channels==2)
-    {
-       /* In case the encoder changes its mind on stereo->mono transition */
-       st->silk_mode.toMono = -1;
-    } else if (st->stream_channels == 1 && st->prev_channels ==2 && st->silk_mode.toMono==0)
-    {
-       /* Delay stereo->mono transition by two frames so that SILK can do a smooth downmix */
-       st->silk_mode.toMono=1;
-       st->stream_channels = 2;
-    } else if (st->stream_channels == 1 && st->prev_channels ==2 && st->silk_mode.toMono==1)
-    {
-       st->silk_mode.toMono=2;
-       st->stream_channels = 2;
-    } else {
-       st->silk_mode.toMono=0;
     }
 
-#ifdef FUZZING
-    /* Random mode switching */
-    if ((rand()&0xF)==0)
-    {
-       if ((rand()&0x1)==0)
-          st->mode = MODE_CELT_ONLY;
-       else
-          st->mode = MODE_SILK_ONLY;
-    } else {
-       if (st->prev_mode==MODE_CELT_ONLY)
-          st->mode = MODE_CELT_ONLY;
-       else
-          st->mode = MODE_SILK_ONLY;
-    }
-#else
     /* Mode selection depending on application and signal type */
     if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
     {
        st->mode = MODE_CELT_ONLY;
     } else if (st->user_forced_mode == OPUS_AUTO)
     {
+#ifdef FUZZING
+       /* Random mode switching */
+       if ((rand()&0xF)==0)
+       {
+          if ((rand()&0x1)==0)
+             st->mode = MODE_CELT_ONLY;
+          else
+             st->mode = MODE_SILK_ONLY;
+       } else {
+          if (st->prev_mode==MODE_CELT_ONLY)
+             st->mode = MODE_CELT_ONLY;
+          else
+             st->mode = MODE_SILK_ONLY;
+       }
+#else
        int chan;
        opus_int32 mode_voice, mode_music;
        opus_int32 threshold;
@@ -539,15 +524,25 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
            threshold += 4000;
 
        st->mode = (equiv_rate >= threshold) ? MODE_CELT_ONLY: MODE_SILK_ONLY;
+#endif
     } else {
        st->mode = st->user_forced_mode;
     }
-#endif
 
     /* Override the chosen mode to make sure we meet the requested frame size */
     if (st->mode != MODE_CELT_ONLY && frame_size < st->Fs/100)
        st->mode = MODE_CELT_ONLY;
 
+    if (st->stream_channels == 1 && st->prev_channels ==2 && st->silk_mode.toMono==0
+          && st->mode != MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)
+    {
+       /* Delay stereo->mono transition by two frames so that SILK can do a smooth downmix */
+       st->silk_mode.toMono = 1;
+       st->stream_channels = 2;
+    } else {
+       st->silk_mode.toMono = 0;
+    }
+
     if (st->prev_mode > 0 &&
         ((st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ||
     (st->mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)))
@@ -636,10 +631,11 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
        VARDECL(unsigned char, tmp_data);
        VARDECL(unsigned char, rp_);
        int nb_frames;
-       int bak_mode, bak_bandwidth, bak_channels;
+       int bak_mode, bak_bandwidth, bak_channels, bak_to_mono;
        OpusRepacketizer *rp;
        int bytes_per_frame;
 
+
        nb_frames = frame_size > st->Fs/25 ? 3 : 2;
        bytes_per_frame = max_data_bytes/nb_frames-3;
 
@@ -655,10 +651,16 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
        st->user_forced_mode = st->mode;
        st->user_bandwidth = st->bandwidth;
        st->force_channels = st->stream_channels;
+       bak_to_mono = st->silk_mode.toMono;
 
+       if (bak_to_mono)
+          st->force_channels = 1;
+       else
+          st->prev_channels = st->stream_channels;
        for (i=0;i<nb_frames;i++)
        {
           int tmp_len;
+          st->silk_mode.toMono = 0;
           tmp_len = opus_encode_native(st, pcm+i*(st->channels*st->Fs/50), st->Fs/50, tmp_data+i*bytes_per_frame, bytes_per_frame);
           ret = opus_repacketizer_cat(rp, tmp_data+i*bytes_per_frame, tmp_len);
        }
@@ -667,6 +669,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
        st->user_forced_mode = bak_mode;
        st->user_bandwidth = bak_bandwidth;
        st->force_channels = bak_channels;
+       st->silk_mode.toMono = bak_to_mono;
        RESTORE_STACK;
        return ret;
     }
@@ -750,7 +753,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
             }
         }
         /* SILK is not allow to use more than 50% of max_data_bytes */
-        if (max_data_bytes < 2*st->silk_mode.bitRate*frame_size / (st->Fs * 8))
+        if (max_data_bytes < st->silk_mode.bitRate*frame_size / (st->Fs * 4))
            st->silk_mode.bitRate = max_data_bytes*st->Fs*4/frame_size;
 
         st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs;
@@ -891,7 +894,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
 
 
     if (st->mode != MODE_HYBRID || st->stream_channels==1)
-       st->silk_mode.stereoWidth_Q14 = 1<<14;
+       st->hybrid_stereo_width_Q14 = st->silk_mode.stereoWidth_Q14 = 1<<14;
     if( st->channels == 2 ) {
         /* Apply stereo width reduction (at low bitrates) */
         if( st->hybrid_stereo_width_Q14 < (1 << 14) || st->silk_mode.stereoWidth_Q14 < (1 << 14) ) {
@@ -914,15 +917,19 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
         }
     }
 
-    if (st->mode != MODE_CELT_ONLY && ec_tell(&enc)+29+8*(st->mode == MODE_HYBRID) < 8*nb_compr_bytes)
+    if ( st->mode != MODE_CELT_ONLY && ec_tell(&enc)+17+20*(st->mode == MODE_HYBRID) < 8*(max_data_bytes-1))
     {
-        /* Check if we have a redundant 0-8 kHz band */
-        ec_enc_bit_logp(&enc, redundancy, 12);
+        /* For SILK mode, the redundancy is inferred from the length */
+        if (st->mode == MODE_HYBRID && (redundancy || ec_tell(&enc)+37 < 8*nb_compr_bytes))
+           ec_enc_bit_logp(&enc, redundancy, 12);
         if (redundancy)
         {
             int max_redundancy;
             ec_enc_bit_logp(&enc, celt_to_silk, 1);
-            max_redundancy = nb_compr_bytes-((ec_tell(&enc)+7)>>3)-(st->mode == MODE_HYBRID);
+            if (st->mode == MODE_HYBRID)
+               max_redundancy = (max_data_bytes-1)-nb_compr_bytes-1;
+            else
+               max_redundancy = (max_data_bytes-1)-((ec_tell(&enc)+7)>>3);
             /* Target the same bit-rate for redundancy as for the rest,
                up to a max of 257 bytes */
             redundancy_bytes = IMIN(max_redundancy, st->bitrate_bps/1600);
@@ -950,7 +957,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
             while(ret>2&&data[ret-1]==0)ret--;
         nb_compr_bytes = ret;
     } else {
-       nb_compr_bytes = IMIN(1275-redundancy_bytes, nb_compr_bytes);
+       nb_compr_bytes = IMIN((max_data_bytes-1)-redundancy_bytes, nb_compr_bytes);
        ec_enc_shrink(&enc, nb_compr_bytes);
     }
 
@@ -1107,7 +1114,7 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
         case OPUS_SET_FORCE_CHANNELS_REQUEST:
         {
             opus_int32 value = va_arg(ap, opus_int32);
-            if(value<1 || value>st->channels)
+            if((value<1 || value>st->channels) && value != OPUS_AUTO)
                 return OPUS_BAD_ARG;
             st->force_channels = value;
         }