diff --git a/celt/celt.c b/celt/celt.c index 0dd22b6f1bcd53eb7a00b8c904c7ca68db056bc1..a34774336143658bdf6bd1076349fda372b0128c 100644 --- a/celt/celt.c +++ b/celt/celt.c @@ -1565,16 +1565,16 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f { int effectiveRate; - /* Always use MS for 2.5 ms frames until we can do a better analysis */ - if (LM!=0) - dual_stereo = stereo_analysis(st->mode, X, LM, N); - static const opus_val16 intensity_thresholds[21]= /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 off*/ { 16,21,23,25,27,29,31,33,35,38,42,46,50,54,58,63,68,75,84,102,130}; static const opus_val16 intensity_histeresis[21]= { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 5, 6, 8, 12}; + /* Always use MS for 2.5 ms frames until we can do a better analysis */ + if (LM!=0) + dual_stereo = stereo_analysis(st->mode, X, LM, N); + /* Account for coarse energy */ effectiveRate = (8*effectiveBytes - 80)>>LM; @@ -1600,7 +1600,7 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f opus_val16 alpha; opus_int32 delta; /* The target rate in 8th bits per frame */ - opus_int32 target, new_target; + opus_int32 target, base_target; opus_int32 min_allowed; int coded_bins; int coded_bands; @@ -1614,6 +1614,8 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f The CELT allocator will just not be able to use more than that anyway. */ nbCompressedBytes = IMIN(nbCompressedBytes,1275>>(3-LM)); target = vbr_rate - ((40*C+20)<<BITRES); + base_target = target; + if (st->constrained_vbr) target += (st->vbr_offset>>lm_diff); @@ -1622,6 +1624,7 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f if (st->analysis.valid && st->analysis.activity<.4) target -= (coded_bins<<BITRES)*1*(.4-st->analysis.activity); #endif + /* Stereo savings */ if (C==2) { int coded_stereo_bands; @@ -1638,19 +1641,20 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f target += tot_boost; /* Compensates for the average transient boost */ target = MULT16_32_Q15(QCONST16(0.96f,15),target); - - new_target = SHL32(MULT16_32_Q15(tf_estimate, target),1); + /* Apply transient boost */ + target = SHL32(MULT16_32_Q15(tf_estimate, target),1); #ifndef FIXED_POINT + /* Apply tonality boost */ if (st->analysis.valid) { int tonal_target; float tonal; tonal = MAX16(0,st->analysis.tonality-.2); - tonal_target = new_target + (coded_bins<<BITRES)*2.0f*tonal; + tonal_target = target + (coded_bins<<BITRES)*2.0f*tonal; if (pitch_change) tonal_target += (coded_bins<<BITRES)*.8; /*printf("%f %f ", st->analysis.tonality, tonal);*/ - new_target = IMAX(tonal_target,new_target); + target = IMAX(tonal_target,target); } #endif @@ -1660,13 +1664,30 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f bins = st->mode->eBands[st->mode->nbEBands-2]<<LM; /*floor_depth = SHR32(MULT16_16((C*bins<<BITRES),celt_log2(SHL32(MAX16(1,sample_max),13))), DB_SHIFT);*/ floor_depth = SHR32(MULT16_16((C*bins<<BITRES),maxDepth), DB_SHIFT); - floor_depth = IMAX(floor_depth, new_target>>2); - new_target = IMIN(new_target, floor_depth); + floor_depth = IMAX(floor_depth, target>>2); + target = IMIN(target, floor_depth); /*printf("%f %d\n", maxDepth, floor_depth);*/ } + + if (st->constrained_vbr || st->bitrate<64000) + { + opus_val16 rate_factor; +#ifdef FIXED_POINT + rate_factor = MAX16(0,(st->bitrate-32000)); +#else + rate_factor = MAX16(0,(1.f/32768)*(st->bitrate-32000)); +#endif + if (st->constrained_vbr) + rate_factor = MIN16(rate_factor, QCONST16(0.67f, 15)); + target = base_target + MULT16_32_Q15(rate_factor, target-base_target); + + } + /* Don't allow more than doubling the rate */ + target = IMIN(2*base_target, target); + /* The current offset is removed from the target and the space used so far is added*/ - target=new_target+tell; + target=target+tell; /* In VBR mode the frame size must not be reduced so much that it would result in the encoder running out of bits. The margin of 2 bytes ensures that none of the bust-prevention logic