#include "aacenc_tns.h"
#include "aacenc_pred.h"
+#include "libavcodec/aaccoder_twoloop.h"
+
/** Frequency in Hz for lower limit of noise substitution **/
#define NOISE_LOW_LIMIT 4000
* replace low energy non zero bands */
#define NOISE_LAMBDA_REPLACE 1.948f
+#include "libavcodec/aaccoder_trellis.h"
+
/**
* structure used in optimal codebook search
*/
}
}
-static void codebook_trellis_rate(AACEncContext *s, SingleChannelElement *sce,
- int win, int group_len, const float lambda)
-{
- BandCodingPath path[120][CB_TOT_ALL];
- int w, swb, cb, start, size;
- int i, j;
- const int max_sfb = sce->ics.max_sfb;
- const int run_bits = sce->ics.num_windows == 1 ? 5 : 3;
- const int run_esc = (1 << run_bits) - 1;
- int idx, ppos, count;
- int stackrun[120], stackcb[120], stack_len;
- float next_minbits = INFINITY;
- int next_mincb = 0;
-
- abs_pow34_v(s->scoefs, sce->coeffs, 1024);
- start = win*128;
- for (cb = 0; cb < CB_TOT_ALL; cb++) {
- path[0][cb].cost = run_bits+4;
- path[0][cb].prev_idx = -1;
- path[0][cb].run = 0;
- }
- for (swb = 0; swb < max_sfb; swb++) {
- size = sce->ics.swb_sizes[swb];
- if (sce->zeroes[win*16 + swb]) {
- float cost_stay_here = path[swb][0].cost;
- float cost_get_here = next_minbits + run_bits + 4;
- if ( run_value_bits[sce->ics.num_windows == 8][path[swb][0].run]
- != run_value_bits[sce->ics.num_windows == 8][path[swb][0].run+1])
- cost_stay_here += run_bits;
- if (cost_get_here < cost_stay_here) {
- path[swb+1][0].prev_idx = next_mincb;
- path[swb+1][0].cost = cost_get_here;
- path[swb+1][0].run = 1;
- } else {
- path[swb+1][0].prev_idx = 0;
- path[swb+1][0].cost = cost_stay_here;
- path[swb+1][0].run = path[swb][0].run + 1;
- }
- next_minbits = path[swb+1][0].cost;
- next_mincb = 0;
- for (cb = 1; cb < CB_TOT_ALL; cb++) {
- path[swb+1][cb].cost = 61450;
- path[swb+1][cb].prev_idx = -1;
- path[swb+1][cb].run = 0;
- }
- } else {
- float minbits = next_minbits;
- int mincb = next_mincb;
- int startcb = sce->band_type[win*16+swb];
- startcb = aac_cb_in_map[startcb];
- next_minbits = INFINITY;
- next_mincb = 0;
- for (cb = 0; cb < startcb; cb++) {
- path[swb+1][cb].cost = 61450;
- path[swb+1][cb].prev_idx = -1;
- path[swb+1][cb].run = 0;
- }
- for (cb = startcb; cb < CB_TOT_ALL; cb++) {
- float cost_stay_here, cost_get_here;
- float bits = 0.0f;
- if (cb >= 12 && sce->band_type[win*16+swb] != aac_cb_out_map[cb]) {
- path[swb+1][cb].cost = 61450;
- path[swb+1][cb].prev_idx = -1;
- path[swb+1][cb].run = 0;
- continue;
- }
- for (w = 0; w < group_len; w++) {
- bits += quantize_band_cost(s, &sce->coeffs[start + w*128],
- &s->scoefs[start + w*128], size,
- sce->sf_idx[win*16+swb],
- aac_cb_out_map[cb],
- 0, INFINITY, NULL, 0);
- }
- cost_stay_here = path[swb][cb].cost + bits;
- cost_get_here = minbits + bits + run_bits + 4;
- if ( run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run]
- != run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run+1])
- cost_stay_here += run_bits;
- if (cost_get_here < cost_stay_here) {
- path[swb+1][cb].prev_idx = mincb;
- path[swb+1][cb].cost = cost_get_here;
- path[swb+1][cb].run = 1;
- } else {
- path[swb+1][cb].prev_idx = cb;
- path[swb+1][cb].cost = cost_stay_here;
- path[swb+1][cb].run = path[swb][cb].run + 1;
- }
- if (path[swb+1][cb].cost < next_minbits) {
- next_minbits = path[swb+1][cb].cost;
- next_mincb = cb;
- }
- }
- }
- start += sce->ics.swb_sizes[swb];
- }
-
- //convert resulting path from backward-linked list
- stack_len = 0;
- idx = 0;
- for (cb = 1; cb < CB_TOT_ALL; cb++)
- if (path[max_sfb][cb].cost < path[max_sfb][idx].cost)
- idx = cb;
- ppos = max_sfb;
- while (ppos > 0) {
- av_assert1(idx >= 0);
- cb = idx;
- stackrun[stack_len] = path[ppos][cb].run;
- stackcb [stack_len] = cb;
- idx = path[ppos-path[ppos][cb].run+1][cb].prev_idx;
- ppos -= path[ppos][cb].run;
- stack_len++;
- }
- //perform actual band info encoding
- start = 0;
- for (i = stack_len - 1; i >= 0; i--) {
- cb = aac_cb_out_map[stackcb[i]];
- put_bits(&s->pb, 4, cb);
- count = stackrun[i];
- memset(sce->zeroes + win*16 + start, !cb, count);
- //XXX: memset when band_type is also uint8_t
- for (j = 0; j < count; j++) {
- sce->band_type[win*16 + start] = cb;
- start++;
- }
- while (count >= run_esc) {
- put_bits(&s->pb, run_bits, run_esc);
- count -= run_esc;
- }
- put_bits(&s->pb, run_bits, count);
- }
-}
typedef struct TrellisPath {
float cost;
sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g];
}
-/**
- * two-loop quantizers search taken from ISO 13818-7 Appendix C
- */
-static void search_for_quantizers_twoloop(AVCodecContext *avctx,
- AACEncContext *s,
- SingleChannelElement *sce,
- const float lambda)
-{
- int start = 0, i, w, w2, g;
- int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels * (lambda / 120.f);
- float dists[128] = { 0 }, uplims[128] = { 0 };
- float maxvals[128];
- int fflag, minscaler;
- int its = 0;
- int allz = 0;
- float minthr = INFINITY;
-
- // for values above this the decoder might end up in an endless loop
- // due to always having more bits than what can be encoded.
- destbits = FFMIN(destbits, 5800);
- //XXX: some heuristic to determine initial quantizers will reduce search time
- //determine zero bands and upper limits
- for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
- for (g = 0; g < sce->ics.num_swb; g++) {
- int nz = 0;
- float uplim = 0.0f, energy = 0.0f;
- for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
- FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g];
- uplim += band->threshold;
- energy += band->energy;
- if (band->energy <= band->threshold || band->threshold == 0.0f) {
- sce->zeroes[(w+w2)*16+g] = 1;
- continue;
- }
- nz = 1;
- }
- uplims[w*16+g] = uplim *512;
- sce->zeroes[w*16+g] = !nz;
- if (nz)
- minthr = FFMIN(minthr, uplim);
- allz |= nz;
- }
- }
- for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
- for (g = 0; g < sce->ics.num_swb; g++) {
- if (sce->zeroes[w*16+g]) {
- sce->sf_idx[w*16+g] = SCALE_ONE_POS;
- continue;
- }
- sce->sf_idx[w*16+g] = SCALE_ONE_POS + FFMIN(log2f(uplims[w*16+g]/minthr)*4,59);
- }
- }
-
- if (!allz)
- return;
- abs_pow34_v(s->scoefs, sce->coeffs, 1024);
-
- for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
- start = w*128;
- for (g = 0; g < sce->ics.num_swb; g++) {
- const float *scaled = s->scoefs + start;
- maxvals[w*16+g] = find_max_val(sce->ics.group_len[w], sce->ics.swb_sizes[g], scaled);
- start += sce->ics.swb_sizes[g];
- }
- }
-
- //perform two-loop search
- //outer loop - improve quality
- do {
- int tbits, qstep;
- minscaler = sce->sf_idx[0];
- //inner loop - quantize spectrum to fit into given number of bits
- qstep = its ? 1 : 32;
- do {
- int prev = -1;
- tbits = 0;
- for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
- start = w*128;
- for (g = 0; g < sce->ics.num_swb; g++) {
- const float *coefs = &sce->coeffs[start];
- const float *scaled = &s->scoefs[start];
- int bits = 0;
- int cb;
- float dist = 0.0f;
-
- if (sce->zeroes[w*16+g] || sce->sf_idx[w*16+g] >= 218) {
- start += sce->ics.swb_sizes[g];
- continue;
- }
- minscaler = FFMIN(minscaler, sce->sf_idx[w*16+g]);
- cb = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]);
- for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
- int b;
- dist += quantize_band_cost(s, coefs + w2*128,
- scaled + w2*128,
- sce->ics.swb_sizes[g],
- sce->sf_idx[w*16+g],
- cb,
- 1.0f,
- INFINITY,
- &b,
- 0);
- bits += b;
- }
- dists[w*16+g] = dist - bits;
- if (prev != -1) {
- bits += ff_aac_scalefactor_bits[sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO];
- }
- tbits += bits;
- start += sce->ics.swb_sizes[g];
- prev = sce->sf_idx[w*16+g];
- }
- }
- if (tbits > destbits) {
- for (i = 0; i < 128; i++)
- if (sce->sf_idx[i] < 218 - qstep)
- sce->sf_idx[i] += qstep;
- } else {
- for (i = 0; i < 128; i++)
- if (sce->sf_idx[i] > 60 - qstep)
- sce->sf_idx[i] -= qstep;
- }
- qstep >>= 1;
- if (!qstep && tbits > destbits*1.02 && sce->sf_idx[0] < 217)
- qstep = 1;
- } while (qstep);
-
- fflag = 0;
- minscaler = av_clip(minscaler, 60, 255 - SCALE_MAX_DIFF);
-
- for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
- for (g = 0; g < sce->ics.num_swb; g++) {
- int prevsc = sce->sf_idx[w*16+g];
- if (dists[w*16+g] > uplims[w*16+g] && sce->sf_idx[w*16+g] > 60) {
- if (find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]-1))
- sce->sf_idx[w*16+g]--;
- else //Try to make sure there is some energy in every band
- sce->sf_idx[w*16+g]-=2;
- }
- sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minscaler, minscaler + SCALE_MAX_DIFF);
- sce->sf_idx[w*16+g] = FFMIN(sce->sf_idx[w*16+g], 219);
- if (sce->sf_idx[w*16+g] != prevsc)
- fflag = 1;
- sce->band_type[w*16+g] = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]);
- }
- }
- its++;
- } while (fflag && its < 10);
-}
static void search_for_quantizers_faac(AVCodecContext *avctx, AACEncContext *s,
SingleChannelElement *sce,
const float lambda = s->lambda;
const float freq_mult = avctx->sample_rate/(1024.0f/sce->ics.num_windows)/2.0f;
const float thr_mult = NOISE_LAMBDA_REPLACE*(100.0f/lambda);
- const float spread_threshold = NOISE_SPREAD_THRESHOLD*(lambda/100.f);
-
- if (sce->ics.window_sequence[0] == EIGHT_SHORT_SEQUENCE)
- return;
+ const float spread_threshold = NOISE_SPREAD_THRESHOLD*FFMAX(0.5f, lambda/100.f);
+ memcpy(sce->band_alt, sce->band_type, sizeof(sce->band_type));
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
+ int wstart = w*128;
for (g = 0; g < sce->ics.num_swb; g++) {
int noise_sfi;
float dist1 = 0.0f, dist2 = 0.0f, noise_amp;
- float pns_energy = 0.0f, energy_ratio, dist_thresh;
+ float pns_energy = 0.0f, pns_tgt_energy, energy_ratio, dist_thresh;
float sfb_energy = 0.0f, threshold = 0.0f, spread = 0.0f;
- const int start = sce->ics.swb_offset[w*16+g];
- const float freq = start*freq_mult;
+ const int start = wstart+sce->ics.swb_offset[g];
+ const float freq = (start-wstart)*freq_mult;
const float freq_boost = FFMAX(0.88f*freq/NOISE_LOW_LIMIT, 1.0f);
if (freq < NOISE_LOW_LIMIT || avctx->cutoff && freq >= avctx->cutoff)
continue;
}
/* Ramps down at ~8000Hz and loosens the dist threshold */
- dist_thresh = FFMIN(2.5f*NOISE_LOW_LIMIT/freq, 1.27f);
+ dist_thresh = FFMIN(2.5f*NOISE_LOW_LIMIT/freq, 2.5f);
- if (sce->zeroes[w*16+g] || spread < spread_threshold ||
- sfb_energy > threshold*thr_mult*freq_boost) {
+ /* zero and energy close to threshold usually means hole avoidance,
+ * we do want to remain avoiding holes with PNS
+ */
+ if (((sce->zeroes[w*16+g] || !sce->band_alt[w*16+g]) && sfb_energy < threshold*sqrtf(1.5f/freq_boost)) || spread < spread_threshold ||
+ (sce->band_alt[w*16+g] && sfb_energy > threshold*thr_mult*freq_boost)) {
sce->pns_ener[w*16+g] = sfb_energy;
continue;
}
- noise_sfi = av_clip(roundf(log2f(sfb_energy)*2), -100, 155); /* Quantize */
+ pns_tgt_energy = sfb_energy*spread*spread/sce->ics.group_len[w];
+ noise_sfi = av_clip(roundf(log2f(pns_tgt_energy)*2), -100, 155); /* Quantize */
noise_amp = -ff_aac_pow2sf_tab[noise_sfi + POW_SF2_ZERO]; /* Dequantize */
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
- float band_energy, scale;
- const int start_c = sce->ics.swb_offset[(w+w2)*16+g];
+ float band_energy, scale, pns_senergy;
+ const int start_c = (w+w2)*128+sce->ics.swb_offset[g];
band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g];
for (i = 0; i < sce->ics.swb_sizes[g]; i++)
PNS[i] = s->random_state = lcg_random(s->random_state);
band_energy = s->fdsp->scalarproduct_float(PNS, PNS, sce->ics.swb_sizes[g]);
scale = noise_amp/sqrtf(band_energy);
s->fdsp->vector_fmul_scalar(PNS, PNS, scale, sce->ics.swb_sizes[g]);
- pns_energy += s->fdsp->scalarproduct_float(PNS, PNS, sce->ics.swb_sizes[g]);
+ pns_senergy = s->fdsp->scalarproduct_float(PNS, PNS, sce->ics.swb_sizes[g]);
+ pns_energy += pns_senergy;
abs_pow34_v(NOR34, &sce->coeffs[start_c], sce->ics.swb_sizes[g]);
abs_pow34_v(PNS34, PNS, sce->ics.swb_sizes[g]);
dist1 += quantize_band_cost(s, &sce->coeffs[start_c],
sce->sf_idx[(w+w2)*16+g],
sce->band_alt[(w+w2)*16+g],
lambda/band->threshold, INFINITY, NULL, 0);
- dist2 += quantize_band_cost(s, PNS,
- PNS34,
- sce->ics.swb_sizes[g],
- noise_sfi,
- NOISE_BT,
- lambda/band->threshold, INFINITY, NULL, 0);
+ /* Estimate rd on average as 9 bits for CB and sf + spread energy * lambda/thr */
+ dist2 += 9+band->energy/(band->spread*band->spread)*lambda/band->threshold;
}
- energy_ratio = sfb_energy/pns_energy; /* Compensates for quantization error */
- sce->pns_ener[w*16+g] = energy_ratio*sfb_energy;
- if (energy_ratio > 0.85f && energy_ratio < 1.25f && dist1/dist2 > dist_thresh) {
+ energy_ratio = pns_tgt_energy/pns_energy; /* Compensates for quantization error */
+ sce->pns_ener[w*16+g] = energy_ratio*pns_tgt_energy;
+ if (energy_ratio > 0.85f && energy_ratio < 1.25f && (sce->zeroes[w*16+g] || !sce->band_alt[w*16+g] || dist2*dist_thresh < dist1)) {
sce->band_type[w*16+g] = NOISE_BT;
sce->zeroes[w*16+g] = 0;
- if (sce->band_type[w*16+g-1] != NOISE_BT && /* Prevent holes */
- sce->band_type[w*16+g-2] == NOISE_BT) {
- sce->band_type[w*16+g-1] = NOISE_BT;
- sce->zeroes[w*16+g-1] = 0;
- }
}
}
}