diff options
author | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2016-04-17 10:02:59 +0300 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2016-04-17 10:02:59 +0300 |
commit | 145b3d8884301abbe367999bd674de5baf605836 (patch) | |
tree | 1eb4d2ceb9a099d76dfd30f019214cb50130ffe8 | |
parent | 787eee29b87f06390fb3a2f615a525205a84d1f4 (diff) |
Adds an NSQ offset as a last resort to avoid busting with CBR.
-rw-r--r-- | silk/NSQ.c | 9 | ||||
-rw-r--r-- | silk/NSQ_del_dec.c | 9 | ||||
-rw-r--r-- | silk/fixed/encode_frame_FIX.c | 7 | ||||
-rw-r--r-- | silk/float/encode_frame_FLP.c | 7 | ||||
-rw-r--r-- | silk/structs.h | 1 |
5 files changed, 33 insertions, 0 deletions
@@ -310,6 +310,15 @@ void silk_noise_shape_quantizer( /* Find two quantization level candidates and measure their rate-distortion */ q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); + if (NSQ->res_offset) { + if (q1_Q10 > NSQ->res_offset) { + q1_Q10 -= NSQ->res_offset; + } else if (q1_Q10 < -NSQ->res_offset) { + q1_Q10 += NSQ->res_offset; + } else { + q1_Q10 = 0; + } + } q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); if( q1_Q0 > 0 ) { q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); diff --git a/silk/NSQ_del_dec.c b/silk/NSQ_del_dec.c index aff560c2..bfbd8f67 100644 --- a/silk/NSQ_del_dec.c +++ b/silk/NSQ_del_dec.c @@ -469,6 +469,15 @@ 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 ); + if (NSQ->res_offset) { + if (q1_Q10 > NSQ->res_offset) { + q1_Q10 -= NSQ->res_offset; + } else if (q1_Q10 < -NSQ->res_offset) { + q1_Q10 += NSQ->res_offset; + } else { + q1_Q10 = 0; + } + } q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); if( q1_Q0 > 0 ) { q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); diff --git a/silk/fixed/encode_frame_FIX.c b/silk/fixed/encode_frame_FIX.c index 5ef44b03..4d2d3fcb 100644 --- a/silk/fixed/encode_frame_FIX.c +++ b/silk/fixed/encode_frame_FIX.c @@ -118,6 +118,7 @@ opus_int silk_encode_frame_FIX( silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) ); if( !psEnc->sCmn.prefillFlag ) { + int res_offset = 0; VARDECL( opus_int32, xfw_Q3 ); VARDECL( opus_int16, res_pitch ); VARDECL( opus_uint8, ec_buf_copy ); @@ -193,6 +194,7 @@ opus_int silk_encode_frame_FIX( /*****************************************/ /* Noise shaping quantization */ /*****************************************/ + psEnc->sCmn.sNSQ.res_offset = res_offset; if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q3, psEnc->sCmn.pulses, sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, @@ -239,6 +241,11 @@ opus_int silk_encode_frame_FIX( if( found_lower == 0 && iter >= 2 ) { /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */ sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 ); + if (res_offset) { + res_offset *= 2; + } else { + res_offset = 512; + } found_upper = 0; gainsID_upper = -1; } else { diff --git a/silk/float/encode_frame_FLP.c b/silk/float/encode_frame_FLP.c index 2092a4d9..e1e19e5e 100644 --- a/silk/float/encode_frame_FLP.c +++ b/silk/float/encode_frame_FLP.c @@ -126,6 +126,7 @@ opus_int silk_encode_frame_FLP( } if( !psEnc->sCmn.prefillFlag ) { + int res_offset = 0; /*****************************************/ /* Find pitch lags, initial LPC analysis */ /*****************************************/ @@ -188,6 +189,7 @@ opus_int silk_encode_frame_FLP( /*****************************************/ /* Noise shaping quantization */ /*****************************************/ + psEnc->sCmn.sNSQ.res_offset = res_offset; silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, xfw ); /****************************************/ @@ -224,6 +226,11 @@ opus_int silk_encode_frame_FLP( if( found_lower == 0 && iter >= 2 ) { /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */ sEncCtrl.Lambda *= 1.5f; + if (res_offset) { + res_offset *= 2; + } else { + res_offset = 512; + } found_upper = 0; gainsID_upper = -1; } else { diff --git a/silk/structs.h b/silk/structs.h index 827829dc..66c63d6b 100644 --- a/silk/structs.h +++ b/silk/structs.h @@ -54,6 +54,7 @@ typedef struct { opus_int32 rand_seed; opus_int32 prev_gain_Q16; opus_int rewhite_flag; + opus_int16 res_offset; } silk_nsq_state; /********************************/ |