diff options
author | Claudio Freire <klaussfreire@gmail.com> | 2015-11-29 15:03:45 -0300 |
---|---|---|
committer | Claudio Freire <klaussfreire@gmail.com> | 2015-11-29 15:03:45 -0300 |
commit | 88e498a87eb255eca48c40fd5570a42372491f2f (patch) | |
tree | cdce76a83b077f960597aa0799cb222836a098a3 /libavcodec | |
parent | 15206ffdbee3c04e638a01cd4572050cf4cfad42 (diff) | |
download | ffmpeg-88e498a87eb255eca48c40fd5570a42372491f2f.tar.gz |
AAC encoder: make pe.min a local minimum
As noted in a comment, pe.min in the reference encoder
is centered around current pe. The bit reservoir algo
needs pe.min to be a local minimum, because it can only
account for local PE variations. If it's set to a global
minimum as was being done, bit reservoir logic doesn't
work as efficiently.
This patch tries to forget old minimums and converge to
a local minimum without losing the stability of the
previous solution. Listening tests until now suggest this
solves numerous RC issues.
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/aacpsy.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/libavcodec/aacpsy.c b/libavcodec/aacpsy.c index 242df6863a..40b3b41e56 100644 --- a/libavcodec/aacpsy.c +++ b/libavcodec/aacpsy.c @@ -80,6 +80,8 @@ #define PSY_3GPP_AH_THR_LONG 0.5f #define PSY_3GPP_AH_THR_SHORT 0.63f +#define PSY_PE_FORGET_SLOPE 511 + enum { PSY_3GPP_AH_NONE, PSY_3GPP_AH_INACTIVE, @@ -495,7 +497,7 @@ static int calc_bit_demand(AacPsyContext *ctx, float pe, int bits, int size, const float bitspend_add = short_window ? PSY_3GPP_SPEND_ADD_S : PSY_3GPP_SPEND_ADD_L; const float clip_low = short_window ? PSY_3GPP_CLIP_LO_S : PSY_3GPP_CLIP_LO_L; const float clip_high = short_window ? PSY_3GPP_CLIP_HI_S : PSY_3GPP_CLIP_HI_L; - float clipped_pe, bit_save, bit_spend, bit_factor, fill_level; + float clipped_pe, bit_save, bit_spend, bit_factor, fill_level, forgetful_min_pe; ctx->fill_level += ctx->frame_bits - bits; ctx->fill_level = av_clip(ctx->fill_level, 0, size); @@ -512,9 +514,14 @@ static int calc_bit_demand(AacPsyContext *ctx, float pe, int bits, int size, * Hopefully below is correct. */ bit_factor = 1.0f - bit_save + ((bit_spend - bit_save) / (ctx->pe.max - ctx->pe.min)) * (clipped_pe - ctx->pe.min); - /* NOTE: The reference encoder attempts to center pe max/min around the current pe. */ + /* NOTE: The reference encoder attempts to center pe max/min around the current pe. + * Here we do that by slowly forgetting pe.min when pe stays in a range that makes + * it unlikely (ie: above the mean) + */ ctx->pe.max = FFMAX(pe, ctx->pe.max); - ctx->pe.min = FFMIN(pe, ctx->pe.min); + forgetful_min_pe = ((ctx->pe.min * PSY_PE_FORGET_SLOPE) + + FFMAX(ctx->pe.min, pe * (pe / ctx->pe.max))) / (PSY_PE_FORGET_SLOPE + 1); + ctx->pe.min = FFMIN(pe, forgetful_min_pe); /* NOTE: allocate a minimum of 1/8th average frame bits, to avoid * reservoir starvation from producing zero-bit frames |