static void set_special_band_scalefactors(AACEncContext *s, SingleChannelElement *sce)
{
- int w, g, start = 0;
- int minscaler_n = sce->sf_idx[0], minscaler_i = sce->sf_idx[0];
+ int w, g;
+ int prevscaler_n = -255, prevscaler_i = 0;
int bands = 0;
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
- start = 0;
for (g = 0; g < sce->ics.num_swb; g++) {
+ if (sce->zeroes[w*16+g])
+ continue;
if (sce->band_type[w*16+g] == INTENSITY_BT || sce->band_type[w*16+g] == INTENSITY_BT2) {
sce->sf_idx[w*16+g] = av_clip(roundf(log2f(sce->is_ener[w*16+g])*2), -155, 100);
- minscaler_i = FFMIN(minscaler_i, sce->sf_idx[w*16+g]);
bands++;
} else if (sce->band_type[w*16+g] == NOISE_BT) {
sce->sf_idx[w*16+g] = av_clip(3+ceilf(log2f(sce->pns_ener[w*16+g])*2), -100, 155);
- minscaler_n = FFMIN(minscaler_n, sce->sf_idx[w*16+g]);
+ if (prevscaler_n == -255)
+ prevscaler_n = sce->sf_idx[w*16+g];
bands++;
}
- start += sce->ics.swb_sizes[g];
}
}
/* Clip the scalefactor indices */
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])
+ continue;
if (sce->band_type[w*16+g] == INTENSITY_BT || sce->band_type[w*16+g] == INTENSITY_BT2) {
- sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minscaler_i, minscaler_i + SCALE_MAX_DIFF);
+ sce->sf_idx[w*16+g] = prevscaler_i = av_clip(sce->sf_idx[w*16+g], prevscaler_i - SCALE_MAX_DIFF, prevscaler_i + SCALE_MAX_DIFF);
} else if (sce->band_type[w*16+g] == NOISE_BT) {
- sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minscaler_n, minscaler_n + SCALE_MAX_DIFF);
+ sce->sf_idx[w*16+g] = prevscaler_n = av_clip(sce->sf_idx[w*16+g], prevscaler_n - SCALE_MAX_DIFF, prevscaler_n + SCALE_MAX_DIFF);
}
}
}
sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g];
}
-
-static void search_for_quantizers_faac(AVCodecContext *avctx, AACEncContext *s,
- SingleChannelElement *sce,
- const float lambda)
-{
- int start = 0, i, w, w2, g;
- float uplim[128], maxq[128];
- int minq, maxsf;
- float distfact = ((sce->ics.num_windows > 1) ? 85.80 : 147.84) / lambda;
- int last = 0, lastband = 0, curband = 0;
- float avg_energy = 0.0;
- if (sce->ics.num_windows == 1) {
- start = 0;
- for (i = 0; i < 1024; i++) {
- if (i - start >= sce->ics.swb_sizes[curband]) {
- start += sce->ics.swb_sizes[curband];
- curband++;
- }
- if (sce->coeffs[i]) {
- avg_energy += sce->coeffs[i] * sce->coeffs[i];
- last = i;
- lastband = curband;
- }
- }
- } else {
- for (w = 0; w < 8; w++) {
- const float *coeffs = &sce->coeffs[w*128];
- curband = start = 0;
- for (i = 0; i < 128; i++) {
- if (i - start >= sce->ics.swb_sizes[curband]) {
- start += sce->ics.swb_sizes[curband];
- curband++;
- }
- if (coeffs[i]) {
- avg_energy += coeffs[i] * coeffs[i];
- last = FFMAX(last, i);
- lastband = FFMAX(lastband, curband);
- }
- }
- }
- }
- last++;
- avg_energy /= last;
- if (avg_energy == 0.0f) {
- for (i = 0; i < FF_ARRAY_ELEMS(sce->sf_idx); i++)
- sce->sf_idx[i] = SCALE_ONE_POS;
- return;
- }
- 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++) {
- float *coefs = &sce->coeffs[start];
- const int size = sce->ics.swb_sizes[g];
- int start2 = start, end2 = start + size, peakpos = start;
- float maxval = -1, thr = 0.0f, t;
- maxq[w*16+g] = 0.0f;
- if (g > lastband) {
- maxq[w*16+g] = 0.0f;
- start += size;
- for (w2 = 0; w2 < sce->ics.group_len[w]; w2++)
- memset(coefs + w2*128, 0, sizeof(coefs[0])*size);
- continue;
- }
- for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
- for (i = 0; i < size; i++) {
- float t = coefs[w2*128+i]*coefs[w2*128+i];
- maxq[w*16+g] = FFMAX(maxq[w*16+g], fabsf(coefs[w2*128 + i]));
- thr += t;
- if (sce->ics.num_windows == 1 && maxval < t) {
- maxval = t;
- peakpos = start+i;
- }
- }
- }
- if (sce->ics.num_windows == 1) {
- start2 = FFMAX(peakpos - 2, start2);
- end2 = FFMIN(peakpos + 3, end2);
- } else {
- start2 -= start;
- end2 -= start;
- }
- start += size;
- thr = pow(thr / (avg_energy * (end2 - start2)), 0.3 + 0.1*(lastband - g) / lastband);
- t = 1.0 - (1.0 * start2 / last);
- uplim[w*16+g] = distfact / (1.4 * thr + t*t*t + 0.075);
- }
- }
- memset(sce->sf_idx, 0, sizeof(sce->sf_idx));
- 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 *coefs = &sce->coeffs[start];
- const float *scaled = &s->scoefs[start];
- const int size = sce->ics.swb_sizes[g];
- int scf, prev_scf, step;
- int min_scf = -1, max_scf = 256;
- float curdiff;
- if (maxq[w*16+g] < 21.544) {
- sce->zeroes[w*16+g] = 1;
- start += size;
- continue;
- }
- sce->zeroes[w*16+g] = 0;
- scf = prev_scf = av_clip(SCALE_ONE_POS - SCALE_DIV_512 - log2f(1/maxq[w*16+g])*16/3, 60, 218);
- for (;;) {
- float dist = 0.0f;
- int quant_max;
-
- 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],
- scf,
- ESC_BT,
- lambda,
- INFINITY,
- &b, NULL,
- 0);
- dist -= b;
- }
- dist *= 1.0f / 512.0f / lambda;
- quant_max = quant(maxq[w*16+g], ff_aac_pow2sf_tab[POW_SF2_ZERO - scf + SCALE_ONE_POS - SCALE_DIV_512], ROUND_STANDARD);
- if (quant_max >= 8191) { // too much, return to the previous quantizer
- sce->sf_idx[w*16+g] = prev_scf;
- break;
- }
- prev_scf = scf;
- curdiff = fabsf(dist - uplim[w*16+g]);
- if (curdiff <= 1.0f)
- step = 0;
- else
- step = log2f(curdiff);
- if (dist > uplim[w*16+g])
- step = -step;
- scf += step;
- scf = av_clip_uint8(scf);
- step = scf - prev_scf;
- if (FFABS(step) <= 1 || (step > 0 && scf >= max_scf) || (step < 0 && scf <= min_scf)) {
- sce->sf_idx[w*16+g] = av_clip(scf, min_scf, max_scf);
- break;
- }
- if (step > 0)
- min_scf = prev_scf;
- else
- max_scf = prev_scf;
- }
- start += size;
- }
- }
- minq = sce->sf_idx[0] ? sce->sf_idx[0] : INT_MAX;
- for (i = 1; i < 128; i++) {
- if (!sce->sf_idx[i])
- sce->sf_idx[i] = sce->sf_idx[i-1];
- else
- minq = FFMIN(minq, sce->sf_idx[i]);
- }
- if (minq == INT_MAX)
- minq = 0;
- minq = FFMIN(minq, SCALE_MAX_POS);
- maxsf = FFMIN(minq + SCALE_MAX_DIFF, SCALE_MAX_POS);
- for (i = 126; i >= 0; i--) {
- if (!sce->sf_idx[i])
- sce->sf_idx[i] = sce->sf_idx[i+1];
- sce->sf_idx[i] = av_clip(sce->sf_idx[i], minq, maxsf);
- }
-}
-
static void search_for_quantizers_fast(AVCodecContext *avctx, AACEncContext *s,
SingleChannelElement *sce,
const float lambda)
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 || (start-wstart) >= cutoff)
+ if (freq < NOISE_LOW_LIMIT || (start-wstart) >= cutoff) {
+ if (!sce->zeroes[w*16+g])
+ prev_sf = sce->sf_idx[w*16+g];
continue;
+ }
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g];
sfb_energy += band->energy;
start = 0;
for (g = 0; g < sce0->ics.num_swb; g++) {
float bmax = bval2bmax(g * 17.0f / sce0->ics.num_swb) / 0.0045f;
- cpe->ms_mask[w*16+g] = 0;
- if (!sce0->zeroes[w*16+g] && !sce1->zeroes[w*16+g]) {
+ if (!cpe->is_mask[w*16+g])
+ cpe->ms_mask[w*16+g] = 0;
+ if (!sce0->zeroes[w*16+g] && !sce1->zeroes[w*16+g] && !cpe->is_mask[w*16+g]) {
float Mmax = 0.0f, Smax = 0.0f;
/* Must compute mid/side SF and book for the whole window group */
minidx = FFMIN(sce0->sf_idx[w*16+g], sce1->sf_idx[w*16+g]);
mididx = av_clip(minidx, 0, SCALE_MAX_POS - SCALE_DIV_512);
sididx = av_clip(minidx - sid_sf_boost * 3, 0, SCALE_MAX_POS - SCALE_DIV_512);
- if (!cpe->is_mask[w*16+g] && sce0->band_type[w*16+g] != NOISE_BT && sce1->band_type[w*16+g] != NOISE_BT
+ if (sce0->band_type[w*16+g] != NOISE_BT && sce1->band_type[w*16+g] != NOISE_BT
&& ( !ff_sfdelta_can_replace(sce0, nextband0, prev_mid, mididx, w*16+g)
|| !ff_sfdelta_can_replace(sce1, nextband1, prev_side, sididx, w*16+g))) {
/* scalefactor range violation, bad stuff, will decrease quality unacceptably */
dist1 += quantize_band_cost(s, &sce0->coeffs[start + (w+w2)*128],
L34,
sce0->ics.swb_sizes[g],
- sce0->sf_idx[(w+w2)*16+g],
- sce0->band_type[(w+w2)*16+g],
+ sce0->sf_idx[w*16+g],
+ sce0->band_type[w*16+g],
lambda / band0->threshold, INFINITY, &b1, NULL, 0);
dist1 += quantize_band_cost(s, &sce1->coeffs[start + (w+w2)*128],
R34,
sce1->ics.swb_sizes[g],
- sce1->sf_idx[(w+w2)*16+g],
- sce1->band_type[(w+w2)*16+g],
+ sce1->sf_idx[w*16+g],
+ sce1->band_type[w*16+g],
lambda / band1->threshold, INFINITY, &b2, NULL, 0);
dist2 += quantize_band_cost(s, M,
M34,
sce0->ics.swb_sizes[g],
- sce0->sf_idx[(w+w2)*16+g],
- sce0->band_type[(w+w2)*16+g],
+ mididx,
+ midcb,
lambda / minthr, INFINITY, &b3, NULL, 0);
dist2 += quantize_band_cost(s, S,
S34,
sce1->ics.swb_sizes[g],
- sce1->sf_idx[(w+w2)*16+g],
- sce1->band_type[(w+w2)*16+g],
+ sididx,
+ sidcb,
mslambda / (minthr * bmax), INFINITY, &b4, NULL, 0);
B0 += b1+b2;
B1 += b3+b4;
- dist1 -= B0;
- dist2 -= B1;
+ dist1 -= b1+b2;
+ dist2 -= b3+b4;
}
cpe->ms_mask[w*16+g] = dist2 <= dist1 && B1 < B0;
if (cpe->ms_mask[w*16+g]) {
- /* Setting the M/S mask is useful with I/S or PNS, but only the flag */
- if (!cpe->is_mask[w*16+g] && sce0->band_type[w*16+g] != NOISE_BT && sce1->band_type[w*16+g] != NOISE_BT) {
+ if (sce0->band_type[w*16+g] != NOISE_BT && sce1->band_type[w*16+g] != NOISE_BT) {
sce0->sf_idx[w*16+g] = mididx;
sce1->sf_idx[w*16+g] = sididx;
sce0->band_type[w*16+g] = midcb;
sce1->band_type[w*16+g] = sidcb;
+ } else if ((sce0->band_type[w*16+g] != NOISE_BT) ^ (sce1->band_type[w*16+g] != NOISE_BT)) {
+ /* ms_mask unneeded, and it confuses some decoders */
+ cpe->ms_mask[w*16+g] = 0;
}
break;
} else if (B1 > B0) {
}
AACCoefficientsEncoder ff_aac_coders[AAC_CODER_NB] = {
- [AAC_CODER_FAAC] = {
- search_for_quantizers_faac,
- encode_window_bands_info,
- quantize_and_encode_band,
- ff_aac_encode_tns_info,
- ff_aac_encode_ltp_info,
- ff_aac_encode_main_pred,
- ff_aac_adjust_common_pred,
- ff_aac_adjust_common_ltp,
- ff_aac_apply_main_pred,
- ff_aac_apply_tns,
- ff_aac_update_ltp,
- ff_aac_ltp_insert_new_frame,
- set_special_band_scalefactors,
- search_for_pns,
- mark_pns,
- ff_aac_search_for_tns,
- ff_aac_search_for_ltp,
- search_for_ms,
- ff_aac_search_for_is,
- ff_aac_search_for_pred,
- },
[AAC_CODER_ANMR] = {
search_for_quantizers_anmr,
encode_window_bands_info,