Commit 88e498a8 authored by Claudio Freire's avatar Claudio Freire

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.
parent 15206ffd
...@@ -80,6 +80,8 @@ ...@@ -80,6 +80,8 @@
#define PSY_3GPP_AH_THR_LONG 0.5f #define PSY_3GPP_AH_THR_LONG 0.5f
#define PSY_3GPP_AH_THR_SHORT 0.63f #define PSY_3GPP_AH_THR_SHORT 0.63f
#define PSY_PE_FORGET_SLOPE 511
enum { enum {
PSY_3GPP_AH_NONE, PSY_3GPP_AH_NONE,
PSY_3GPP_AH_INACTIVE, PSY_3GPP_AH_INACTIVE,
...@@ -495,7 +497,7 @@ static int calc_bit_demand(AacPsyContext *ctx, float pe, int bits, int size, ...@@ -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 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_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; 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 += ctx->frame_bits - bits;
ctx->fill_level = av_clip(ctx->fill_level, 0, size); 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, ...@@ -512,9 +514,14 @@ static int calc_bit_demand(AacPsyContext *ctx, float pe, int bits, int size,
* Hopefully below is correct. * 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); 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.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 /* NOTE: allocate a minimum of 1/8th average frame bits, to avoid
* reservoir starvation from producing zero-bit frames * reservoir starvation from producing zero-bit frames
......
...@@ -146,7 +146,7 @@ fate-aac-aref-encode: CMD = enc_dec_pcm adts wav s16le $(REF) -strict -2 -c:a aa ...@@ -146,7 +146,7 @@ fate-aac-aref-encode: CMD = enc_dec_pcm adts wav s16le $(REF) -strict -2 -c:a aa
fate-aac-aref-encode: CMP = stddev fate-aac-aref-encode: CMP = stddev
fate-aac-aref-encode: REF = ./tests/data/asynth-44100-2.wav fate-aac-aref-encode: REF = ./tests/data/asynth-44100-2.wav
fate-aac-aref-encode: CMP_SHIFT = -4096 fate-aac-aref-encode: CMP_SHIFT = -4096
fate-aac-aref-encode: CMP_TARGET = 1127 fate-aac-aref-encode: CMP_TARGET = 1139
fate-aac-aref-encode: SIZE_TOLERANCE = 2464 fate-aac-aref-encode: SIZE_TOLERANCE = 2464
fate-aac-aref-encode: FUZZ = 6 fate-aac-aref-encode: FUZZ = 6
...@@ -191,7 +191,7 @@ fate-aac-is-encode: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audio-ref ...@@ -191,7 +191,7 @@ fate-aac-is-encode: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audio-ref
fate-aac-is-encode: CMP = stddev fate-aac-is-encode: CMP = stddev
fate-aac-is-encode: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav fate-aac-is-encode: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav
fate-aac-is-encode: CMP_SHIFT = -4096 fate-aac-is-encode: CMP_SHIFT = -4096
fate-aac-is-encode: CMP_TARGET = 582 fate-aac-is-encode: CMP_TARGET = 584
fate-aac-is-encode: SIZE_TOLERANCE = 3560 fate-aac-is-encode: SIZE_TOLERANCE = 3560
fate-aac-is-encode: FUZZ = 1 fate-aac-is-encode: FUZZ = 1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment