diff options
author | Koen Vos <koen.vos@skype.net> | 2011-10-24 09:10:58 -0400 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2011-10-24 09:10:58 -0400 |
commit | 43a0de4af15b6cf61938d5c442e3b689773d085b (patch) | |
tree | 3e35faaa84a93d1f2f752a6fe34ed2b1ec2a4d30 /silk/float | |
parent | 3b2aee062d08fc72f12a4379ce2d6e2b444d5021 (diff) | |
download | opus-43a0de4af15b6cf61938d5c442e3b689773d085b.tar.gz |
Optimization of the CBR loop
Also some comment/warning fixes
Diffstat (limited to 'silk/float')
-rw-r--r-- | silk/float/encode_frame_FLP.c | 104 | ||||
-rw-r--r-- | silk/float/process_gains_FLP.c | 2 |
2 files changed, 61 insertions, 45 deletions
diff --git a/silk/float/encode_frame_FLP.c b/silk/float/encode_frame_FLP.c index 8206459d..2330476a 100644 --- a/silk/float/encode_frame_FLP.c +++ b/silk/float/encode_frame_FLP.c @@ -95,6 +95,7 @@ opus_int silk_encode_frame_FLP( ec_enc sRangeEnc_copy, sRangeEnc_copy2; silk_nsq_state sNSQ_copy, sNSQ_copy2; opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper; + opus_int32 gainsID, gainsID_lower, gainsID_upper; opus_int16 gainMult_Q8; opus_int16 ec_prevLagIndex_copy; opus_int ec_prevSignalType_copy; @@ -185,50 +186,58 @@ TOC(NSQ) gainMult_Q8 = SILK_FIX_CONST( 1, 8 ); found_lower = 0; found_upper = 0; + gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); + gainsID_lower = -1; + gainsID_upper = -1; + /* Copy part of the input state */ + silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) ); + silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); + seed_copy = psEnc->sCmn.indices.Seed; + ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex; + ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType; for( iter = 0; ; iter++ ) { - /* Copy part of the input state */ - silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) ); - silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); - seed_copy = psEnc->sCmn.indices.Seed; - ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex; - ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType; - - /*****************************************/ - /* Noise shaping quantization */ - /*****************************************/ + if( gainsID == gainsID_lower ) { + nBits = nBits_lower; + } else if( gainsID == gainsID_upper ) { + nBits = nBits_upper; + } else { + /*****************************************/ + /* Noise shaping quantization */ + /*****************************************/ TIC(NSQ) - silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, xfw ); + silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, xfw ); TOC(NSQ) - /****************************************/ - /* Encode Parameters */ - /****************************************/ + /****************************************/ + /* Encode Parameters */ + /****************************************/ TIC(ENCODE_PARAMS) - silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); + silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); TOC(ENCODE_PARAMS) - /****************************************/ - /* Encode Excitation Signal */ - /****************************************/ + /****************************************/ + /* Encode Excitation Signal */ + /****************************************/ TIC(ENCODE_PULSES) - silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, - psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); + silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, + psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); TOC(ENCODE_PULSES) + + nBits = ec_tell( psRangeEnc ); - nBits = ec_tell( psRangeEnc ); - - if( useCBR == 0 && iter == 0 && nBits <= maxBits ) { - break; + if( useCBR == 0 && iter == 0 && nBits <= maxBits ) { + break; + } } if( iter == maxIter ) { - if( nBits > maxBits && found_lower ) { + if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) { /* Restore output state from earlier iteration that did meet the bitrate budget */ - silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); - silk_assert( sRangeEnc_copy2.offs<=1275 ); - silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs ); - silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) ); - psEnc->sShape.LastGainIndex = LastGainIndex_copy2; + silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); + silk_assert( sRangeEnc_copy2.offs <= 1275 ); + silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs ); + silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) ); + psEnc->sShape.LastGainIndex = LastGainIndex_copy2; } break; } @@ -237,7 +246,8 @@ TOC(ENCODE_PULSES) found_upper = 1; nBits_upper = nBits; gainMult_upper = gainMult_Q8; - if( found_lower == 0 && iter >= 3 ) { + gainsID_upper = gainsID; + if( found_lower == 0 && iter >= 2 ) { /* Adjust the quantizer's rate/distortion tradeoff */ sEncCtrl.Lambda *= 1.5f; } @@ -245,12 +255,15 @@ TOC(ENCODE_PULSES) found_lower = 1; nBits_lower = nBits; gainMult_lower = gainMult_Q8; - /* Copy part of the output state */ - silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); - silk_assert( psRangeEnc->offs<=1275 ); - silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs ); - silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); - LastGainIndex_copy2 = psEnc->sShape.LastGainIndex; + if( gainsID != gainsID_lower ) { + gainsID_lower = gainsID; + /* Copy part of the output state */ + silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); + silk_assert( psRangeEnc->offs <= 1275 ); + silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs ); + silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); + LastGainIndex_copy2 = psEnc->sShape.LastGainIndex; + } } else { /* Within 5 bits of budget: close enough */ break; @@ -269,23 +282,26 @@ TOC(ENCODE_PULSES) /* Adjust gain by interpolating */ gainMult_Q8 = gainMult_lower + ( ( gainMult_upper - gainMult_lower ) * ( maxBits - nBits_lower ) ) / ( nBits_upper - nBits_lower ); /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */ - if( gainMult_Q8 > gainMult_lower + silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ) ) { - gainMult_Q8 = gainMult_lower + silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ); + if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) { + gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ); } else - if( gainMult_Q8 < gainMult_upper - silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ) ) { - gainMult_Q8 = gainMult_upper - silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ); - } + if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) { + gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ); + } } for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 ); } - psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; - /* Noise shaping quantization */ + /* Quantize gains */ + psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16, &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); + /* Unique identifier of gains vector */ + gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); + /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { sEncCtrl.Gains[ i ] = pGains_Q16[ i ] / 65536.0f; diff --git a/silk/float/process_gains_FLP.c b/silk/float/process_gains_FLP.c index 0708a5c2..f9b57f46 100644 --- a/silk/float/process_gains_FLP.c +++ b/silk/float/process_gains_FLP.c @@ -71,7 +71,7 @@ void silk_process_gains_FLP( silk_memcpy( psEncCtrl->GainsUnq_Q16, pGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); psEncCtrl->lastGainIndexPrev = psShapeSt->LastGainIndex; - /* Noise shaping quantization */ + /* Quantize gains */ silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16, &psShapeSt->LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); |