summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@jmvalin.ca>2016-04-20 03:37:32 -0400
committerJean-Marc Valin <jmvalin@jmvalin.ca>2016-07-15 17:51:45 -0400
commitcfd0de824e09faa631acf4e52579d5bff2341985 (patch)
treea1a3db62bae63b7eb11cf2d5a4de9351a6466ef8
parentdc10071fff75722c5b9250d999738f99a6a15811 (diff)
downloadopus-cfd0de824e09faa631acf4e52579d5bff2341985.tar.gz
Makes the encoder more aggressive about meeting the rate target
-rw-r--r--silk/NSQ.c17
-rw-r--r--silk/NSQ_del_dec.c16
-rw-r--r--silk/float/encode_frame_FLP.c18
3 files changed, 45 insertions, 6 deletions
diff --git a/silk/NSQ.c b/silk/NSQ.c
index 43e3fee7..5032b9c5 100644
--- a/silk/NSQ.c
+++ b/silk/NSQ.c
@@ -226,6 +226,10 @@ void silk_noise_shape_quantizer(
silk_short_prediction_create_arch_coef(a_Q12_arch, a_Q12, predictLPCOrder);
#endif
+ /* We're getting desperate to hit the target -- pretend there's
+ no dithering to make hitting the target more likely. */
+ if (Lambda_Q10 > 3072) offset_Q10 = 0;
+
for( i = 0; i < length; i++ ) {
/* Generate dither */
NSQ->rand_seed = silk_RAND( NSQ->rand_seed );
@@ -287,6 +291,19 @@ void silk_noise_shape_quantizer(
/* Find two quantization level candidates and measure their rate-distortion */
q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
+ if (Lambda_Q10 > 2048) {
+ /* For aggressive RDO, the bias becomes more than one pulse. */
+ int rdo_offset = Lambda_Q10/2 - 512;
+ if (q1_Q10 > rdo_offset) {
+ q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 );
+ } else if (q1_Q10 < -rdo_offset) {
+ q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 );
+ } else if (q1_Q10 < 0) {
+ q1_Q0 = -1;
+ } else {
+ q1_Q0 = 0;
+ }
+ }
if( q1_Q0 > 0 ) {
q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
diff --git a/silk/NSQ_del_dec.c b/silk/NSQ_del_dec.c
index ab6feeac..c5c77491 100644
--- a/silk/NSQ_del_dec.c
+++ b/silk/NSQ_del_dec.c
@@ -356,6 +356,9 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
NSQ_sample_struct *psSS;
SAVE_STACK;
+ /* We're getting desperate to hit the target -- pretend there's
+ no dithering to make hitting the target more likely. */
+ if (Lambda_Q10 > 3072) offset_Q10 = 0;
silk_assert( nStatesDelayedDecision > 0 );
ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair );
@@ -462,6 +465,19 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
/* Find two quantization level candidates and measure their rate-distortion */
q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
+ if (Lambda_Q10 > 2048) {
+ /* For aggressive RDO, the bias becomes more than one pulse. */
+ int rdo_offset = Lambda_Q10/2 - 512;
+ if (q1_Q10 > rdo_offset) {
+ q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 );
+ } else if (q1_Q10 < -rdo_offset) {
+ q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 );
+ } else if (q1_Q10 < 0) {
+ q1_Q0 = -1;
+ } else {
+ q1_Q0 = 0;
+ }
+ }
if( q1_Q0 > 0 ) {
q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
diff --git a/silk/float/encode_frame_FLP.c b/silk/float/encode_frame_FLP.c
index 2092a4d9..61b9b265 100644
--- a/silk/float/encode_frame_FLP.c
+++ b/silk/float/encode_frame_FLP.c
@@ -223,7 +223,9 @@ opus_int silk_encode_frame_FLP(
if( nBits > maxBits ) {
if( found_lower == 0 && iter >= 2 ) {
/* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */
- sEncCtrl.Lambda *= 1.5f;
+ sEncCtrl.Lambda = silk_max_float(sEncCtrl.Lambda*1.5f, 1.5f);
+ /* Reducing dithering can help us hit the target. */
+ psEnc->sCmn.indices.quantOffsetType = 0;
found_upper = 0;
gainsID_upper = -1;
} else {
@@ -252,13 +254,17 @@ opus_int silk_encode_frame_FLP(
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_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 ) );
+ if (gainMult_Q8 < 16384) {
+ gainMult_Q8 *= 2;
+ } else {
+ gainMult_Q8 = 32767;
+ }
+ } else {
+ opus_int32 gain_factor_Q16;
+ gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
+ gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
}
- gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
} else {
/* Adjust gain by interpolating */
gainMult_Q8 = gainMult_lower + ( ( gainMult_upper - gainMult_lower ) * ( maxBits - nBits_lower ) ) / ( nBits_upper - nBits_lower );