Macros | Functions
aaccoder_twoloop.h File Reference
#include <float.h>
#include "libavutil/mathematics.h"
#include "mathops.h"
#include "avcodec.h"
#include "put_bits.h"
#include "aac.h"
#include "aacenc.h"
#include "aactab.h"
#include "aacenctab.h"

Go to the source code of this file.


#define NOISE_LOW_LIMIT   4000
 This file contains a template for the twoloop coder function. More...


static int ff_pns_bits (SingleChannelElement *sce, int w, int g)
static void search_for_quantizers_twoloop (AVCodecContext *avctx, AACEncContext *s, SingleChannelElement *sce, const float lambda)
 two-loop quantizers search taken from ISO 13818-7 Appendix C More...

Detailed Description

AAC encoder twoloop coder

Konstantin Shishkov, Claudio Freire

Definition in file aaccoder_twoloop.h.

Macro Definition Documentation


#define NOISE_LOW_LIMIT   4000

This file contains a template for the twoloop coder function.

It needs to be provided, externally, as an already included declaration, the following functions from aacenc_quantization/util.h. They're not included explicitly here to make it possible to provide alternative implementations:

  • quantize_band_cost
  • abs_pow34_v
  • find_max_val
  • find_min_book
  • find_form_factor Frequency in Hz for lower limit of noise substitution

Definition at line 54 of file aaccoder_twoloop.h.

Function Documentation

◆ ff_pns_bits()

static int ff_pns_bits ( SingleChannelElement sce,
int  w,
int  g 

Definition at line 57 of file aaccoder_twoloop.h.

Referenced by search_for_quantizers_twoloop().

◆ search_for_quantizers_twoloop()

static void search_for_quantizers_twoloop ( AVCodecContext avctx,
AACEncContext s,
SingleChannelElement sce,
const float  lambda 

two-loop quantizers search taken from ISO 13818-7 Appendix C

rdlambda controls the maximum tolerated distortion. Twoloop will keep iterating until it fails to lower it or it reaches ulimit * rdlambda. Keeping it low increases quality on difficult signals, but lower it too much, and bits will be taken from weak signals, creating "holes". A balance is necessary. rdmax and rdmin specify the relative deviation from rdlambda allowed for tonality compensation

sfoffs controls an offset of optmium allocation that will be applied based on lambda. Keep it real and modest, the loop will take care of the rest, this just accelerates convergence

zeroscale controls a multiplier of the threshold, if band energy is below this, a zero is forced. Keep it lower than 1, unless low lambda is used, because energy < threshold doesn't mean there's no audible signal outright, it's just energy. Also make it rise slower than rdlambda, as rdscale has due compensation with noisy band depriorization below, whereas zeroing logic is rather dumb

Psy granted us extra bits to use, from the reservoire adjust for lambda except what psy already did

Constant Q-scale doesn't compensate MS coding on its own No need to be overly precise, this only controls RD adjustment CB limits when going overboard

When using a constant Q-scale, don't adjust bits, just use RD Don't let it go overboard, though... 8x psy target is enough

Don't offset scalers, just RD

search further

and zero out above cutoff frequency

Scale, psy gives us constant quality, this LP only scales bitrate by lambda, so we save bits on subjectively unimportant HF rather than increase quantization noise. Adjust nominal bitrate to effective bitrate according to encoding parameters, AAC_CUTOFF_FROM_BITRATE is calibrated for effective bitrate.

Compensate for extensions that increase efficiency

for values above this the decoder might end up in an endless loop due to always having more bits than what can be encoded.

XXX: some heuristic to determine initial quantizers will reduce search time determine zero bands and upper distortion limits

Compute initial scalers

log2f-to-distortion ratio is, technically, 2 (1.5db = 4, but it's power vs level so it's 2). But, as offsets are applied, low-frequency signals are too sensitive to the induced distortion, so we make scaling more conservative by choosing a lower log2f-to-distortion ratio, and thus more robust.


Scale uplims to match rate distortion to quality bu applying noisy band depriorization and tonal band priorization. Maxval-energy ratio gives us an idea of how noisy/tonal the band is. If maxval^2 ~ energy, then that band is mostly noise, and we can relax rate distortion requirements.

psy already priorizes transients to some extent

In ABR, we need to priorize less and let rate control do its thing

In ABR, we need to priorize less and let rate control do its thing

PNS isn't free

Must recompute distortion

PNS isn't free

Start with big steps, end up fine-tunning

Um... over target. Save bits for more important stuff.

SF difference limit violation risk. Must re-clamp.

Scout out next nonzero bands

Make sure proper codebooks are set

Cannot zero out, make sure it's not attempted

Check that there's no SF delta range violations

Set global gain to something useful

Definition at line 65 of file aaccoder_twoloop.h.