ref: ab04fbb1b7d0b727636d28fc2cadb5df9febe515
parent: fd9c0f1e1f1b74c46c5872217e3289a9edf69d48
author: Jean-Marc Valin <jmvalin@amazon.com>
date: Sat Jul 23 23:46:16 EDT 2022
Smooth out the LBRR rate estimate Reduces fluctuations in the non-FEC target bitrate.
--- a/silk/enc_API.c
+++ b/silk/enc_API.c
@@ -270,6 +270,7 @@
psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 );
ALLOC( buf, nSamplesFromInputMax, opus_int16 );
while( 1 ) {
+ int curr_nBitsUsedLBRR = 0;
nSamplesToBuffer = psEnc->state_Fxx[ 0 ].sCmn.frame_length - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx;
nSamplesToBuffer = silk_min( nSamplesToBuffer, nSamplesToBufferMax );
nSamplesFromInput = silk_DIV32_16( nSamplesToBuffer * psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 );
@@ -342,6 +343,7 @@
opus_uint8 iCDF[ 2 ] = { 0, 0 };
iCDF[ 0 ] = 256 - silk_RSHIFT( 256, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal );
ec_enc_icdf( psRangeEnc, 0, iCDF, 8 );
+ curr_nBitsUsedLBRR = ec_tell( psRangeEnc );
/* Encode any LBRR data from previous packet */
/* Encode LBRR flags */
@@ -386,8 +388,7 @@
for( n = 0; n < encControl->nChannelsInternal; n++ ) {
silk_memset( psEnc->state_Fxx[ n ].sCmn.LBRR_flags, 0, sizeof( psEnc->state_Fxx[ n ].sCmn.LBRR_flags ) );
}
-
- psEnc->nBitsUsedLBRR = ec_tell( psRangeEnc );
+ curr_nBitsUsedLBRR = ec_tell( psRangeEnc ) - curr_nBitsUsedLBRR;
}
silk_HP_variable_cutoff( psEnc->state_Fxx );
@@ -396,6 +397,16 @@
nBits = silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 );
/* Subtract bits used for LBRR */
if( !prefillFlag ) {
+ /* psEnc->nBitsUsedLBRR is an exponential moving average of the LBRR usage,
+ except that for the first LBRR frame it does no averaging and for the first
+ frame after after LBRR, it goes back to zero immediately. */
+ if ( curr_nBitsUsedLBRR < 10 ) {
+ psEnc->nBitsUsedLBRR = 0;
+ } else if ( psEnc->nBitsUsedLBRR < 10) {
+ psEnc->nBitsUsedLBRR = curr_nBitsUsedLBRR;
+ } else {
+ psEnc->nBitsUsedLBRR = ( psEnc->nBitsUsedLBRR + curr_nBitsUsedLBRR ) / 2;
+ }
nBits -= psEnc->nBitsUsedLBRR;
}
/* Divide by number of uncoded frames left in packet */