CBR: set gains to their previons values where we're busting the budget
authorJean-Marc Valin <jmvalin@jmvalin.ca>
Fri, 3 Jun 2016 20:27:48 +0000 (16:27 -0400)
committerJean-Marc Valin <jmvalin@jmvalin.ca>
Tue, 19 Jul 2016 20:11:50 +0000 (16:11 -0400)
silk/fixed/encode_frame_FIX.c
silk/float/encode_frame_FLP.c

index 5bc94c3..c8913d0 100644 (file)
@@ -201,14 +201,15 @@ opus_int silk_encode_frame_FIX(
                             psEnc->sCmn.arch);
                 }
 
+                if ( iter == maxIter && !found_lower ) {
+                    silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
+                }
+
                 /****************************************/
                 /* Encode Parameters                    */
                 /****************************************/
                 silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
 
-                if ( iter == maxIter && !found_lower ) {
-                    silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
-                }
                 /****************************************/
                 /* Encode Excitation Signal             */
                 /****************************************/
@@ -217,13 +218,30 @@ opus_int silk_encode_frame_FIX(
 
                 nBits = ec_tell( psRangeEnc );
 
+                /* If we still bust after the last iteration, do some damage control. */
                 if ( iter == maxIter && !found_lower && nBits > maxBits ) {
                     silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
+
+                    /* Keep gains the same as the last frame. */
+                    psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
+                    for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
+                        psEnc->sCmn.indices.GainsIndices[ i ] = 4;
+                    }
+                    if (condCoding != CODE_CONDITIONALLY) {
+                       psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev;
+                    }
+                    psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
+                    psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
+                    /* Clear all pulses. */
                     for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
                         psEnc->sCmn.pulses[ i ] = 0;
                     }
+
+                    silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
+
                     silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
                         psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
+
                     nBits = ec_tell( psRangeEnc );
                 }
 
index 59efcb4..746fd57 100644 (file)
@@ -187,14 +187,15 @@ opus_int silk_encode_frame_FLP(
                 /*****************************************/
                 silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, x_frame );
 
+                if ( iter == maxIter && !found_lower ) {
+                    silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
+                }
+
                 /****************************************/
                 /* Encode Parameters                    */
                 /****************************************/
                 silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
 
-                if ( iter == maxIter && !found_lower ) {
-                    silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
-                }
                 /****************************************/
                 /* Encode Excitation Signal             */
                 /****************************************/
@@ -203,13 +204,30 @@ opus_int silk_encode_frame_FLP(
 
                 nBits = ec_tell( psRangeEnc );
 
+                /* If we still bust after the last iteration, do some damage control. */
                 if ( iter == maxIter && !found_lower && nBits > maxBits ) {
                     silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
+
+                    /* Keep gains the same as the last frame. */
+                    psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
+                    for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
+                        psEnc->sCmn.indices.GainsIndices[ i ] = 4;
+                    }
+                    if (condCoding != CODE_CONDITIONALLY) {
+                       psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev;
+                    }
+                    psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
+                    psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
+                    /* Clear all pulses. */
                     for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
                         psEnc->sCmn.pulses[ i ] = 0;
                     }
+
+                    silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
+
                     silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
                         psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
+
                     nBits = ec_tell( psRangeEnc );
                 }