mirror of
https://github.com/xiph/opus.git
synced 2025-06-02 00:27:43 +00:00
Limits how fast the CBR gain multiplier can increase
This fixes an overflow that was caused by having a huge gain
This commit is contained in:
parent
1fad3048af
commit
44a030deed
1 changed files with 14 additions and 12 deletions
|
@ -94,7 +94,8 @@ opus_int silk_encode_frame_FLP(
|
|||
silk_float res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];
|
||||
ec_enc sRangeEnc_copy, sRangeEnc_copy2;
|
||||
silk_nsq_state sNSQ_copy, sNSQ_copy2;
|
||||
opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_Q10, gainMult_lower, gainMult_upper;
|
||||
opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper;
|
||||
opus_int16 gainMult_Q8;
|
||||
opus_int16 ec_prevLagIndex_copy;
|
||||
opus_int ec_prevSignalType_copy;
|
||||
opus_int8 LastGainIndex_copy2;
|
||||
|
@ -181,7 +182,7 @@ TOC(NSQ)
|
|||
} else {
|
||||
/* Loop over quantizer and entroy coding to control bitrate */
|
||||
maxIter = 5;
|
||||
gainMult_Q10 = SILK_FIX_CONST( 1, 10 );
|
||||
gainMult_Q8 = SILK_FIX_CONST( 1, 8 );
|
||||
found_lower = 0;
|
||||
found_upper = 0;
|
||||
for( iter = 0; ; iter++ ) {
|
||||
|
@ -234,7 +235,7 @@ TOC(ENCODE_PULSES)
|
|||
if( nBits > maxBits ) {
|
||||
found_upper = 1;
|
||||
nBits_upper = nBits;
|
||||
gainMult_upper = gainMult_Q10;
|
||||
gainMult_upper = gainMult_Q8;
|
||||
if( found_lower == 0 && iter >= 3 ) {
|
||||
/* Adjust the quantizer's rate/distortion tradeoff */
|
||||
sEncCtrl.Lambda *= 1.5f;
|
||||
|
@ -242,7 +243,7 @@ TOC(ENCODE_PULSES)
|
|||
} else if( nBits < maxBits - 5 ) {
|
||||
found_lower = 1;
|
||||
nBits_lower = nBits;
|
||||
gainMult_lower = gainMult_Q10;
|
||||
gainMult_lower = gainMult_Q8;
|
||||
/* Copy part of the output state */
|
||||
silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
|
||||
silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );
|
||||
|
@ -256,25 +257,26 @@ TOC(ENCODE_PULSES)
|
|||
if( ( found_lower & found_upper ) == 0 ) {
|
||||
/* Adjust gain according to high-rate rate/distortion curve */
|
||||
opus_int32 gain_factor_Q16;
|
||||
gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
|
||||
gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
|
||||
gain_factor_Q16 = silk_min_32(gain_factor_Q16, SILK_FIX_CONST( 2, 16 ) );
|
||||
if( nBits > maxBits ) {
|
||||
gain_factor_Q16 = silk_max_32( gain_factor_Q16, SILK_FIX_CONST( 1.3, 16 ) );
|
||||
}
|
||||
gainMult_Q10 = silk_SMULWW( gainMult_Q10, gain_factor_Q16 );
|
||||
gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
|
||||
} else {
|
||||
/* Adjust gain by interpolating */
|
||||
gainMult_Q10 = gainMult_lower + ( ( gainMult_upper - gainMult_lower ) * ( maxBits - nBits_lower ) ) / ( nBits_upper - nBits_lower );
|
||||
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_Q10 > gainMult_lower + silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ) ) {
|
||||
gainMult_Q10 = gainMult_lower + silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 );
|
||||
if( gainMult_Q8 > gainMult_lower + silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ) ) {
|
||||
gainMult_Q8 = gainMult_lower + silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 );
|
||||
} else
|
||||
if( gainMult_Q10 < gainMult_upper - silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ) ) {
|
||||
gainMult_Q10 = gainMult_upper - silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 );
|
||||
if( gainMult_Q8 < gainMult_upper - silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ) ) {
|
||||
gainMult_Q8 = gainMult_upper - silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||
pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWW( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q10 ), 6 );
|
||||
pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 );
|
||||
}
|
||||
psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue