Fix for flutter with FEC

The bug was caused by an improper feedback of the per-frame bitrate, causing
the bitrate to jump up and down from frame to frame, within a packet.
The patch avoids this, and also gives a slight improvement in general for
multi-frame packets, even without FEC.

Signed-off-by: Jean-Marc Valin <jmvalin@jmvalin.ca>
This commit is contained in:
Koen Vos 2015-08-10 12:22:25 -04:00 committed by Jean-Marc Valin
parent 8adff0bb31
commit 3499e78bd5
5 changed files with 21 additions and 11 deletions

View file

@ -376,26 +376,33 @@ opus_int silk_Encode( /* O Returns error co
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 );
}
silk_HP_variable_cutoff( psEnc->state_Fxx );
/* Total target bits for packet */
nBits = silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 );
/* Subtract half of the bits already used */
/* Subtract bits used for LBRR */
if( !prefillFlag ) {
nBits -= ec_tell( psRangeEnc ) >> 1;
nBits -= psEnc->nBitsUsedLBRR;
}
/* Divide by number of uncoded frames left in packet */
nBits = silk_DIV32_16( nBits, psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket - psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded );
nBits = silk_DIV32_16( nBits, psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket );
/* Convert to bits/second */
if( encControl->payloadSize_ms == 10 ) {
TargetRate_bps = silk_SMULBB( nBits, 100 );
} else {
TargetRate_bps = silk_SMULBB( nBits, 50 );
}
/* Subtract fraction of bits in excess of target in previous packets */
/* Subtract fraction of bits in excess of target in previous frames and packets */
TargetRate_bps -= silk_DIV32_16( silk_MUL( psEnc->nBitsExceeded, 1000 ), BITRESERVOIR_DECAY_TIME_MS );
if( !prefillFlag && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded > 0 ) {
/* Compare actual vs target bits so far in this packet */
opus_int32 bitsBalance = ec_tell( psRangeEnc ) - psEnc->nBitsUsedLBRR - nBits * psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded;
TargetRate_bps -= silk_DIV32_16( silk_MUL( bitsBalance, 1000 ), BITRESERVOIR_DECAY_TIME_MS );
}
/* Never exceed input bitrate */
TargetRate_bps = silk_LIMIT( TargetRate_bps, encControl->bitRate, 5000 );