shithub: opus

Download patch

ref: e1be1920bac28c897a940be55319abbb1bed0f51
parent: e699c1989c88fcff8c4bcf0f073966094be2d2cc
author: Jean-Marc Valin <[email protected]>
date: Mon Nov 28 17:48:01 EST 2011

Some minor (non-bitstream-affecting) changes to help us have better test vectors

These fix corner cases discovered during the latest fuzzing tests.

--- a/celt/celt_lpc.c
+++ b/celt/celt_lpc.c
@@ -164,10 +164,10 @@
       opus_val32 ac0=0;
       int shift;
       for(i=0;i<n;i++)
-         ac0 += SHR32(MULT16_16(xx[i],xx[i]),8);
+         ac0 += SHR32(MULT16_16(xx[i],xx[i]),9);
       ac0 += 1+n;
 
-      shift = celt_ilog2(ac0)-30+9;
+      shift = celt_ilog2(ac0)-30+10;
       shift = (shift+1)/2;
       for(i=0;i<n;i++)
          xx[i] = VSHR32(xx[i], shift);
--- a/silk/LPC_inv_pred_gain.c
+++ b/silk/LPC_inv_pred_gain.c
@@ -54,6 +54,7 @@
     for( k = order - 1; k > 0; k-- ) {
         /* Check for stability */
         if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) {
+            *invGain_Q30 = 0;
             return 1;
         }
 
@@ -88,6 +89,7 @@
 
     /* Check for stability */
     if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) {
+        *invGain_Q30 = 0;
         return 1;
     }
 
@@ -127,6 +129,7 @@
     }
     /* If the DC is unstable, we don't even need to do the full calculations */
     if( DC_resp >= 4096 ) {
+       *invGain_Q30 = 0;
        return 1;
     }
     return LPC_inverse_pred_gain_QA( invGain_Q30, Atmp_QA, order );
--- a/silk/PLC.c
+++ b/silk/PLC.c
@@ -184,6 +184,9 @@
     opus_int32 sLTP_Q14[ 2 * MAX_FRAME_LENGTH ];
     silk_PLC_struct *psPLC = &psDec->sPLC;
 
+    if (psDec->first_frame_after_reset)
+       silk_memset(psPLC->prevLPC_Q12, 0, MAX_LPC_ORDER*sizeof(psPLC->prevLPC_Q12[ 0 ]));
+
     /* Find random noise component */
     /* Scale previous excitation signal */
     exc_buf_ptr = exc_buf;
--- a/silk/fixed/prefilter_FIX.c
+++ b/silk/fixed/prefilter_FIX.c
@@ -148,7 +148,7 @@
         pxw += psEnc->sCmn.subfr_length;
     }
 
-    P->lagPrev = psEncCtrl->pitchL[ MAX_NB_SUBFR - 1 ];
+    P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ];
 }
 
 /* Prefilter for finding Quantizer input signal */
--- a/silk/float/encode_frame_FLP.c
+++ b/silk/float/encode_frame_FLP.c
@@ -52,9 +52,6 @@
     /**************************************************/
     /* Convert speech activity into VAD and DTX flags */
     /**************************************************/
-    if( psEnc->sCmn.nFramesEncoded == 0 ) {
-        psEnc->sCmn.inDTX = psEnc->sCmn.useDTX;
-    }
     if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {
         psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;
         psEnc->sCmn.noSpeechCounter++;
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -685,7 +685,7 @@
         st->bandwidth = bandwidth;
         /* Prevents any transition to SWB/FB until the SILK layer has fully
            switched to WB mode and turned the variable LP filter off */
-        if (st->mode != MODE_CELT_ONLY && !st->silk_mode.inWBmodeWithoutVariableLP && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND)
+        if (!st->first && st->mode != MODE_CELT_ONLY && !st->silk_mode.inWBmodeWithoutVariableLP && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND)
             st->bandwidth = OPUS_BANDWIDTH_WIDEBAND;
     }
 
@@ -786,7 +786,7 @@
         st->mode = MODE_SILK_ONLY;
 
     /* printf("%d %d %d %d\n", st->bitrate_bps, st->stream_channels, st->mode, curr_bandwidth); */
-    bytes_target = IMIN(max_data_bytes-1, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1;
+    bytes_target = IMIN(max_data_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1;
 
     data += 1;
 
@@ -872,6 +872,7 @@
         if (st->mode == MODE_SILK_ONLY)
         {
            opus_int32 effective_max_rate = max_rate;
+           st->silk_mode.maxInternalSampleRate = 16000;
            if (frame_rate > 50)
               effective_max_rate = effective_max_rate*2/3;
            if (effective_max_rate < 13000)
@@ -932,6 +933,7 @@
         }
         if (nBytes==0)
         {
+           st->rangeFinal = 0;
            data[-1] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels);
            RESTORE_STACK;
            return 1;
@@ -1087,14 +1089,6 @@
     {
         ret = (ec_tell(&enc)+7)>>3;
         ec_enc_done(&enc);
-        /*When in LPC only mode it's perfectly
-          reasonable to strip off trailing zero bytes as
-          the required range decoder behavior is to
-          fill these in. This can't be done when the MDCT
-          modes are used because the decoder needs to know
-          the actual length for allocation purposes.*/
-        if(!redundancy)
-            while(ret>2&&data[ret-1]==0)ret--;
         nb_compr_bytes = ret;
     } else {
        nb_compr_bytes = IMIN((max_data_bytes-1)-redundancy_bytes, nb_compr_bytes);
@@ -1129,7 +1123,7 @@
            celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
         }
         /* If false, we already busted the budget and we'll end up with a "PLC packet" */
-        if (ec_tell(&enc) < 8*nb_compr_bytes)
+        if (ec_tell(&enc) <= 8*nb_compr_bytes)
         {
            ret = celt_encode_with_ec(celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc);
            if (ret < 0)
@@ -1183,6 +1177,15 @@
        data[1] = 0;
        ret = 1;
        st->rangeFinal = 0;
+    } else if (st->mode==MODE_SILK_ONLY&&!redundancy)
+    {
+       /*When in LPC only mode it's perfectly
+         reasonable to strip off trailing zero bytes as
+         the required range decoder behavior is to
+         fill these in. This can't be done when the MDCT
+         modes are used because the decoder needs to know
+         the actual length for allocation purposes.*/
+       while(ret>2&&data[ret]==0)ret--;
     }
     /* Count ToC and redundancy */
     ret += 1+redundancy_bytes;