diff options
author | Koen Vos <koenvos74@gmail.com> | 2015-08-10 12:22:25 -0400 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2015-08-10 12:22:25 -0400 |
commit | 3499e78bd5a93edcef80f6cbd88e7fc1e1666d9b (patch) | |
tree | 9d4e572970521401d7b08db541b01fa03c147e5f /silk/enc_API.c | |
parent | 8adff0bb31989deb616ca72d16fc3e791ed91b10 (diff) | |
download | opus-3499e78bd5a93edcef80f6cbd88e7fc1e1666d9b.tar.gz |
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>
Diffstat (limited to 'silk/enc_API.c')
-rw-r--r-- | silk/enc_API.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/silk/enc_API.c b/silk/enc_API.c index f1993ada..f8060286 100644 --- a/silk/enc_API.c +++ b/silk/enc_API.c @@ -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 ); |