diff options
author | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2013-06-10 11:30:01 +0400 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2013-06-10 11:32:12 +0400 |
commit | 28733d1281b9fde5561a2f5747179c841ef24944 (patch) | |
tree | d22a1a0a25ca9cf3d8240c9de0d793522f96702a | |
parent | 4a7bb1fe9bd09bb67c536ecafdbcdbfecef7cc07 (diff) |
Moves VBR calculations to a separate function.
Does not change the behaviour of the VBR code in most cases. The only
exception is that the VBR offset is now taken into accound in the base_rate,
which will have a (very minor) impact on CVBR at low rate.
-rw-r--r-- | celt/celt_encoder.c | 192 |
1 files changed, 108 insertions, 84 deletions
diff --git a/celt/celt_encoder.c b/celt/celt_encoder.c index 21ad4f8b..37697d95 100644 --- a/celt/celt_encoder.c +++ b/celt/celt_encoder.c @@ -1111,6 +1111,108 @@ static int run_prefilter(CELTEncoder *st, celt_sig *in, celt_sig *prefilter_mem, return pf_on; } +static int compute_vbr(const CELTMode *mode, AnalysisInfo *analysis, opus_int32 base_target, + int LM, opus_int32 bitrate, int lastCodedBands, int C, int intensity, + int constrained_vbr, opus_val16 stereo_saving, int tot_boost, + opus_val16 tf_estimate, int pitch_change, opus_val16 maxDepth, + int variable_duration, int lfe, int has_surround_mask, opus_val16 surround_masking) +{ + /* The target rate in 8th bits per frame */ + opus_int32 target; + int coded_bins; + int coded_bands; + int tf_calibration; + int nbEBands; + const opus_int16 *eBands; + + nbEBands = mode->nbEBands; + eBands = mode->eBands; + + coded_bands = lastCodedBands ? lastCodedBands : nbEBands; + coded_bins = eBands[coded_bands]<<LM; + if (C==2) + coded_bins += eBands[IMIN(intensity, coded_bands)]<<LM; + + target = base_target; + + /*printf("%f %f %f %f %d %d ", st->analysis.activity, st->analysis.tonality, tf_estimate, st->stereo_saving, tot_boost, coded_bands);*/ +#ifndef FIXED_POINT + if (analysis->valid && analysis->activity<.4) + target -= (opus_int32)((coded_bins<<BITRES)*(.4f-analysis->activity)); +#endif + /* Stereo savings */ + if (C==2) + { + int coded_stereo_bands; + int coded_stereo_dof; + opus_val16 max_frac; + coded_stereo_bands = IMIN(intensity, coded_bands); + coded_stereo_dof = (eBands[coded_stereo_bands]<<LM)-coded_stereo_bands; + /* Maximum fraction of the bits we can save if the signal is mono. */ + max_frac = DIV32_16(MULT16_16(QCONST16(0.8f, 15), coded_stereo_dof), coded_bins); + /*printf("%d %d %d ", coded_stereo_dof, coded_bins, tot_boost);*/ + target -= (opus_int32)MIN32(MULT16_32_Q15(max_frac,target), + SHR32(MULT16_16(stereo_saving-QCONST16(0.1f,8),(coded_stereo_dof<<BITRES)),8)); + } + /* Boost the rate according to dynalloc (minus the dynalloc average for calibration). */ + target += tot_boost-(16<<LM); + /* Apply transient boost, compensating for average boost. */ + tf_calibration = variable_duration ? QCONST16(0.02f,14) : QCONST16(0.04f,14); + target += (opus_int32)SHL32(MULT16_32_Q15(tf_estimate-tf_calibration, target),1); + +#ifndef FIXED_POINT + /* Apply tonality boost */ + if (analysis->valid) { + opus_int32 tonal_target; + float tonal; + + /* Tonality boost (compensating for the average). */ + tonal = MAX16(0.f,analysis->tonality-.15f)-0.09f; + tonal_target = target + (opus_int32)((coded_bins<<BITRES)*1.2f*tonal); + if (pitch_change) + tonal_target += (opus_int32)((coded_bins<<BITRES)*.8f); + /*printf("%f %f ", st->analysis.tonality, tonal);*/ + target = tonal_target; + } +#endif + + if (has_surround_mask&&!lfe) + { + opus_int32 surround_target = target + SHR32(MULT16_16(surround_masking,coded_bins<<BITRES), DB_SHIFT); + /*printf("%f %d %d %d %d %d %d ", surround_masking, coded_bins, st->end, st->intensity, surround_target, target, st->bitrate);*/ + target = IMAX(target/4, surround_target); + } + + { + opus_int32 floor_depth; + int bins; + bins = eBands[nbEBands-2]<<LM; + /*floor_depth = SHR32(MULT16_16((C*bins<<BITRES),celt_log2(SHL32(MAX16(1,sample_max),13))), DB_SHIFT);*/ + floor_depth = (opus_int32)SHR32(MULT16_16((C*bins<<BITRES),maxDepth), DB_SHIFT); + floor_depth = IMAX(floor_depth, target>>2); + target = IMIN(target, floor_depth); + /*printf("%f %d\n", maxDepth, floor_depth);*/ + } + + if ((!has_surround_mask||lfe) && (constrained_vbr || bitrate<64000)) + { + opus_val16 rate_factor; +#ifdef FIXED_POINT + rate_factor = MAX16(0,(bitrate-32000)); +#else + rate_factor = MAX16(0,(1.f/32768)*(bitrate-32000)); +#endif + if (constrained_vbr) + rate_factor = MIN16(rate_factor, QCONST16(0.67f, 15)); + target = base_target + (opus_int32)MULT16_32_Q15(rate_factor, target-base_target); + + } + /* Don't allow more than doubling the rate */ + target = IMIN(2*base_target, target); + + return target; +} + int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc) { int i, c, N; @@ -1628,98 +1730,20 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, /* The target rate in 8th bits per frame */ opus_int32 target, base_target; opus_int32 min_allowed; - int coded_bins; - int coded_bands; - int tf_calibration; int lm_diff = mode->maxLM - LM; - coded_bands = st->lastCodedBands ? st->lastCodedBands : nbEBands; - coded_bins = eBands[coded_bands]<<LM; - if (C==2) - coded_bins += eBands[IMIN(st->intensity, coded_bands)]<<LM; /* Don't attempt to use more than 510 kb/s, even for frames smaller than 20 ms. 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; + base_target = vbr_rate - ((40*C+20)<<BITRES); if (st->constrained_vbr) - target += (st->vbr_offset>>lm_diff); - - /*printf("%f %f %f %f %d %d ", st->analysis.activity, st->analysis.tonality, tf_estimate, st->stereo_saving, tot_boost, coded_bands);*/ -#ifndef FIXED_POINT - if (st->analysis.valid && st->analysis.activity<.4) - target -= (opus_int32)((coded_bins<<BITRES)*(.4f-st->analysis.activity)); -#endif - /* Stereo savings */ - if (C==2) - { - int coded_stereo_bands; - int coded_stereo_dof; - opus_val16 max_frac; - coded_stereo_bands = IMIN(st->intensity, coded_bands); - coded_stereo_dof = (eBands[coded_stereo_bands]<<LM)-coded_stereo_bands; - /* Maximum fraction of the bits we can save if the signal is mono. */ - max_frac = DIV32_16(MULT16_16(QCONST16(0.8f, 15), coded_stereo_dof), coded_bins); - /*printf("%d %d %d ", coded_stereo_dof, coded_bins, tot_boost);*/ - target -= (opus_int32)MIN32(MULT16_32_Q15(max_frac,target), - SHR32(MULT16_16(st->stereo_saving-QCONST16(0.1f,8),(coded_stereo_dof<<BITRES)),8)); - } - /* Boost the rate according to dynalloc (minus the dynalloc average for calibration). */ - target += tot_boost-(16<<LM); - /* Apply transient boost, compensating for average boost. */ - tf_calibration = st->variable_duration ? QCONST16(0.02f,14) : QCONST16(0.04f,14); - target += (opus_int32)SHL32(MULT16_32_Q15(tf_estimate-tf_calibration, target),1); - -#ifndef FIXED_POINT - /* Apply tonality boost */ - if (st->analysis.valid) { - opus_int32 tonal_target; - float tonal; - - /* Tonality boost (compensating for the average). */ - tonal = MAX16(0.f,st->analysis.tonality-.15f)-0.09f; - tonal_target = target + (opus_int32)((coded_bins<<BITRES)*1.2f*tonal); - if (pitch_change) - tonal_target += (opus_int32)((coded_bins<<BITRES)*.8f); - /*printf("%f %f ", st->analysis.tonality, tonal);*/ - target = tonal_target; - } -#endif - - if (st->energy_mask&&!st->lfe) - { - opus_int32 surround_target = target + SHR32(MULT16_16(surround_masking,coded_bins<<BITRES), DB_SHIFT); - /*printf("%f %d %d %d %d %d %d ", surround_masking, coded_bins, st->end, st->intensity, surround_target, target, st->bitrate);*/ - target = IMAX(target/4, surround_target); - } - - { - opus_int32 floor_depth; - int bins; - bins = eBands[nbEBands-2]<<LM; - /*floor_depth = SHR32(MULT16_16((C*bins<<BITRES),celt_log2(SHL32(MAX16(1,sample_max),13))), DB_SHIFT);*/ - floor_depth = (opus_int32)SHR32(MULT16_16((C*bins<<BITRES),maxDepth), DB_SHIFT); - floor_depth = IMAX(floor_depth, target>>2); - target = IMIN(target, floor_depth); - /*printf("%f %d\n", maxDepth, floor_depth);*/ - } + base_target += (st->vbr_offset>>lm_diff); - if ((!st->energy_mask||st->lfe) && (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 + (opus_int32)MULT16_32_Q15(rate_factor, target-base_target); - - } - /* Don't allow more than doubling the rate */ - target = IMIN(2*base_target, target); + target = compute_vbr(mode, &st->analysis, base_target, LM, st->bitrate, + st->lastCodedBands, C, st->intensity, st->constrained_vbr, + st->stereo_saving, tot_boost, tf_estimate, pitch_change, maxDepth, + st->variable_duration, st->lfe, st->energy_mask!=NULL, surround_masking); /* The current offset is removed from the target and the space used so far is added*/ |