|
|
@@ -76,6 +76,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
|
|
int refbits = destbits;
|
|
|
int toomanybits, toofewbits;
|
|
|
char nzs[128];
|
|
|
+ uint8_t nextband[128];
|
|
|
int maxsf[128];
|
|
|
float dists[128] = { 0 }, qenergies[128] = { 0 }, uplims[128], euplims[128], energies[128];
|
|
|
float maxvals[128], spread_thr_r[128];
|
|
|
@@ -102,7 +103,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
|
|
*/
|
|
|
float sfoffs = av_clipf(log2f(120.0f / lambda) * 4.0f, -5, 10);
|
|
|
|
|
|
- int fflag, minscaler, maxscaler, nminscaler, minrdsf;
|
|
|
+ int fflag, minscaler, maxscaler, nminscaler;
|
|
|
int its = 0;
|
|
|
int maxits = 30;
|
|
|
int allz = 0;
|
|
|
@@ -158,9 +159,13 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
|
|
/** search further */
|
|
|
maxits *= 2;
|
|
|
} else {
|
|
|
- /** When using ABR, be strict */
|
|
|
- toomanybits = destbits + destbits/16;
|
|
|
- toofewbits = destbits - destbits/4;
|
|
|
+ /* When using ABR, be strict, but a reasonable leeway is
|
|
|
+ * critical to allow RC to smoothly track desired bitrate
|
|
|
+ * without sudden quality drops that cause audible artifacts.
|
|
|
+ * Symmetry is also desirable, to avoid systematic bias.
|
|
|
+ */
|
|
|
+ toomanybits = destbits + destbits/8;
|
|
|
+ toofewbits = destbits - destbits/8;
|
|
|
|
|
|
sfoffs = 0;
|
|
|
rdlambda = sqrtf(rdlambda);
|
|
|
@@ -191,6 +196,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
|
|
bandwidth = avctx->cutoff;
|
|
|
} else {
|
|
|
bandwidth = FFMAX(3000, AAC_CUTOFF_FROM_BITRATE(frame_bit_rate, 1, avctx->sample_rate));
|
|
|
+ s->psy.cutoff = bandwidth;
|
|
|
}
|
|
|
|
|
|
cutoff = bandwidth * 2 * wlen / avctx->sample_rate;
|
|
|
@@ -241,7 +247,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
|
|
nzs[w*16+g] = nz;
|
|
|
sce->zeroes[w*16+g] = !nz;
|
|
|
allz |= nz;
|
|
|
- if (nz) {
|
|
|
+ if (nz && sce->can_pns[w*16+g]) {
|
|
|
spread_thr_r[w*16+g] = energy * nz / (uplim * spread);
|
|
|
if (min_spread_thr_r < 0) {
|
|
|
min_spread_thr_r = max_spread_thr_r = spread_thr_r[w*16+g];
|
|
|
@@ -433,6 +439,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
|
|
} while (qstep);
|
|
|
|
|
|
overdist = 1;
|
|
|
+ fflag = tbits < toofewbits;
|
|
|
for (i = 0; i < 2 && (overdist || recomprd); ++i) {
|
|
|
if (recomprd) {
|
|
|
/** Must recompute distortion */
|
|
|
@@ -484,13 +491,13 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- if (!i && s->options.pns && its > maxits/2) {
|
|
|
+ if (!i && s->options.pns && its > maxits/2 && tbits > toofewbits) {
|
|
|
float maxoverdist = 0.0f;
|
|
|
+ float ovrfactor = 1.f+(maxits-its)*16.f/maxits;
|
|
|
overdist = recomprd = 0;
|
|
|
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
|
|
- float ovrfactor = 2.f+(maxits-its)*16.f/maxits;
|
|
|
for (g = start = 0; g < sce->ics.num_swb; start += sce->ics.swb_sizes[g++]) {
|
|
|
- if (!sce->zeroes[w*16+g] && dists[w*16+g] > uplims[w*16+g]*ovrfactor) {
|
|
|
+ if (!sce->zeroes[w*16+g] && sce->sf_idx[w*16+g] > SCALE_ONE_POS && dists[w*16+g] > uplims[w*16+g]*ovrfactor) {
|
|
|
float ovrdist = dists[w*16+g] / FFMAX(uplims[w*16+g],euplims[w*16+g]);
|
|
|
maxoverdist = FFMAX(maxoverdist, ovrdist);
|
|
|
overdist++;
|
|
|
@@ -506,7 +513,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
|
|
float zspread;
|
|
|
int zeroable = 0;
|
|
|
int zeroed = 0;
|
|
|
- int maxzeroed;
|
|
|
+ int maxzeroed, zloop;
|
|
|
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
|
|
for (g = start = 0; g < sce->ics.num_swb; start += sce->ics.swb_sizes[g++]) {
|
|
|
if (start >= pns_start_pos && !sce->zeroes[w*16+g] && sce->can_pns[w*16+g]) {
|
|
|
@@ -517,21 +524,41 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
|
|
}
|
|
|
}
|
|
|
zspread = (maxspread-minspread) * 0.0125f + minspread;
|
|
|
- zspread = FFMIN(maxoverdist, zspread);
|
|
|
- maxzeroed = zeroable * its / (2 * maxits);
|
|
|
- for (g = sce->ics.num_swb-1; g > 0 && zeroed < maxzeroed; g--) {
|
|
|
- if (sce->ics.swb_offset[g] < pns_start_pos)
|
|
|
- continue;
|
|
|
- for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
|
|
- if (!sce->zeroes[w*16+g] && sce->can_pns[w*16+g] && spread_thr_r[w*16+g] <= zspread) {
|
|
|
- sce->zeroes[w*16+g] = 1;
|
|
|
- sce->band_type[w*16+g] = 0;
|
|
|
- zeroed++;
|
|
|
+ /* Don't PNS everything even if allowed. It suppresses bit starvation signals from RC,
|
|
|
+ * and forced the hand of the later search_for_pns step.
|
|
|
+ * Instead, PNS a fraction of the spread_thr_r range depending on how starved for bits we are,
|
|
|
+ * and leave further PNSing to search_for_pns if worthwhile.
|
|
|
+ */
|
|
|
+ zspread = FFMIN3(min_spread_thr_r * 8.f, zspread,
|
|
|
+ ((toomanybits - tbits) * min_spread_thr_r + (tbits - toofewbits) * max_spread_thr_r) / (toomanybits - toofewbits + 1));
|
|
|
+ maxzeroed = FFMIN(zeroable, FFMAX(1, (zeroable * its + maxits - 1) / (2 * maxits)));
|
|
|
+ for (zloop = 0; zloop < 2; zloop++) {
|
|
|
+ /* Two passes: first distorted stuff - two birds in one shot and all that,
|
|
|
+ * then anything viable. Viable means not zero, but either CB=zero-able
|
|
|
+ * (too high SF), not SF <= 1 (that means we'd be operating at very high
|
|
|
+ * quality, we don't want PNS when doing VHQ), PNS allowed, and within
|
|
|
+ * the lowest ranking percentile.
|
|
|
+ */
|
|
|
+ float loopovrfactor = (zloop) ? 1.0f : ovrfactor;
|
|
|
+ int loopminsf = (zloop) ? (SCALE_ONE_POS - SCALE_DIV_512) : SCALE_ONE_POS;
|
|
|
+ int mcb;
|
|
|
+ for (g = sce->ics.num_swb-1; g > 0 && zeroed < maxzeroed; g--) {
|
|
|
+ if (sce->ics.swb_offset[g] < pns_start_pos)
|
|
|
+ continue;
|
|
|
+ for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
|
|
+ if (!sce->zeroes[w*16+g] && sce->can_pns[w*16+g] && spread_thr_r[w*16+g] <= zspread
|
|
|
+ && sce->sf_idx[w*16+g] > loopminsf
|
|
|
+ && (dists[w*16+g] > loopovrfactor*uplims[w*16+g] || !(mcb = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]))
|
|
|
+ || (mcb <= 1 && dists[w*16+g] > FFMIN(uplims[w*16+g], euplims[w*16+g]))) ) {
|
|
|
+ sce->zeroes[w*16+g] = 1;
|
|
|
+ sce->band_type[w*16+g] = 0;
|
|
|
+ zeroed++;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (zeroed)
|
|
|
- recomprd = 1;
|
|
|
+ recomprd = fflag = 1;
|
|
|
} else {
|
|
|
overdist = 0;
|
|
|
}
|
|
|
@@ -549,9 +576,8 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fflag = 0;
|
|
|
minscaler = nminscaler = av_clip(minscaler, SCALE_ONE_POS - SCALE_DIV_512, SCALE_MAX_POS - SCALE_DIV_512);
|
|
|
- minrdsf = FFMAX3(60, minscaler - 1, maxscaler - SCALE_MAX_DIFF - 1);
|
|
|
+ prev = -1;
|
|
|
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
|
|
/** Start with big steps, end up fine-tunning */
|
|
|
int depth = (its > maxits/2) ? ((its > maxits*2/3) ? 1 : 3) : 10;
|
|
|
@@ -561,19 +587,22 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
|
|
start = w * 128;
|
|
|
for (g = 0; g < sce->ics.num_swb; g++) {
|
|
|
int prevsc = sce->sf_idx[w*16+g];
|
|
|
- int minrdsfboost = (sce->ics.num_windows > 1) ? av_clip(g-4, -2, 0) : av_clip(g-16, -4, 0);
|
|
|
+ if (prev < 0 && !sce->zeroes[w*16+g])
|
|
|
+ prev = sce->sf_idx[0];
|
|
|
if (!sce->zeroes[w*16+g]) {
|
|
|
const float *coefs = sce->coeffs + start;
|
|
|
const float *scaled = s->scoefs + start;
|
|
|
int cmb = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]);
|
|
|
- if ((!cmb || dists[w*16+g] > uplims[w*16+g]) && sce->sf_idx[w*16+g] > minrdsf) {
|
|
|
+ int mindeltasf = FFMAX(0, prev - SCALE_MAX_DIFF);
|
|
|
+ int maxdeltasf = FFMIN(SCALE_MAX_POS - SCALE_DIV_512, prev + SCALE_MAX_DIFF);
|
|
|
+ if ((!cmb || dists[w*16+g] > uplims[w*16+g]) && sce->sf_idx[w*16+g] > mindeltasf) {
|
|
|
/* Try to make sure there is some energy in every nonzero band
|
|
|
* NOTE: This algorithm must be forcibly imbalanced, pushing harder
|
|
|
* on holes or more distorted bands at first, otherwise there's
|
|
|
* no net gain (since the next iteration will offset all bands
|
|
|
* on the opposite direction to compensate for extra bits)
|
|
|
*/
|
|
|
- for (i = 0; i < edepth; ++i) {
|
|
|
+ for (i = 0; i < edepth && sce->sf_idx[w*16+g] > mindeltasf; ++i) {
|
|
|
int cb, bits;
|
|
|
float dist, qenergy;
|
|
|
int mb = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]-1);
|
|
|
@@ -585,6 +614,12 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
|
|
} else if (i >= depth && dists[w*16+g] < euplims[w*16+g]) {
|
|
|
break;
|
|
|
}
|
|
|
+ /* !g is the DC band, it's important, since quantization error here
|
|
|
+ * applies to less than a cycle, it creates horrible intermodulation
|
|
|
+ * distortion if it doesn't stick to what psy requests
|
|
|
+ */
|
|
|
+ if (!g && sce->ics.num_windows > 1 && dists[w*16+g] >= euplims[w*16+g])
|
|
|
+ maxsf[w*16+g] = FFMIN(sce->sf_idx[w*16+g], maxsf[w*16+g]);
|
|
|
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
|
|
int b;
|
|
|
float sqenergy;
|
|
|
@@ -603,19 +638,19 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
|
|
sce->sf_idx[w*16+g]--;
|
|
|
dists[w*16+g] = dist - bits;
|
|
|
qenergies[w*16+g] = qenergy;
|
|
|
- if (mb && (sce->sf_idx[w*16+g] < (minrdsf+minrdsfboost) || (
|
|
|
+ if (mb && (sce->sf_idx[w*16+g] < mindeltasf || (
|
|
|
(dists[w*16+g] < FFMIN(uplmax*uplims[w*16+g], euplims[w*16+g]))
|
|
|
&& (fabsf(qenergies[w*16+g]-energies[w*16+g]) < euplims[w*16+g])
|
|
|
) )) {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- } else if (tbits > toofewbits && sce->sf_idx[w*16+g] < maxscaler
|
|
|
+ } else if (tbits > toofewbits && sce->sf_idx[w*16+g] < FFMIN(maxdeltasf, maxsf[w*16+g])
|
|
|
&& (dists[w*16+g] < FFMIN(euplims[w*16+g], uplims[w*16+g]))
|
|
|
&& (fabsf(qenergies[w*16+g]-energies[w*16+g]) < euplims[w*16+g])
|
|
|
) {
|
|
|
/** Um... over target. Save bits for more important stuff. */
|
|
|
- for (i = 0; i < depth; ++i) {
|
|
|
+ for (i = 0; i < depth && sce->sf_idx[w*16+g] < maxdeltasf; ++i) {
|
|
|
int cb, bits;
|
|
|
float dist, qenergy;
|
|
|
cb = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]+1);
|
|
|
@@ -651,38 +686,53 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ prev = sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], mindeltasf, maxdeltasf);
|
|
|
+ if (sce->sf_idx[w*16+g] != prevsc)
|
|
|
+ fflag = 1;
|
|
|
+ nminscaler = FFMIN(nminscaler, sce->sf_idx[w*16+g]);
|
|
|
+ sce->band_type[w*16+g] = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]);
|
|
|
}
|
|
|
- sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minrdsf, minscaler + SCALE_MAX_DIFF);
|
|
|
- sce->sf_idx[w*16+g] = FFMIN(sce->sf_idx[w*16+g], SCALE_MAX_POS - SCALE_DIV_512);
|
|
|
- if (sce->sf_idx[w*16+g] != prevsc)
|
|
|
- fflag = 1;
|
|
|
- nminscaler = FFMIN(nminscaler, sce->sf_idx[w*16+g]);
|
|
|
- sce->band_type[w*16+g] = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]);
|
|
|
start += sce->ics.swb_sizes[g];
|
|
|
}
|
|
|
}
|
|
|
- if (nminscaler < minscaler || sce->ics.num_windows > 1) {
|
|
|
- /** SF difference limit violation risk. Must re-clamp. */
|
|
|
- minscaler = nminscaler;
|
|
|
- for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
|
|
- for (g = 0; g < sce->ics.num_swb; g++) {
|
|
|
- sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minscaler, minscaler + SCALE_MAX_DIFF);
|
|
|
+
|
|
|
+ /** SF difference limit violation risk. Must re-clamp. */
|
|
|
+ prev = -1;
|
|
|
+ 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]) {
|
|
|
+ int prevsf = sce->sf_idx[w*16+g];
|
|
|
+ if (prev < 0)
|
|
|
+ prev = prevsf;
|
|
|
+ sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], prev - SCALE_MAX_DIFF, prev + SCALE_MAX_DIFF);
|
|
|
sce->band_type[w*16+g] = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]);
|
|
|
+ prev = sce->sf_idx[w*16+g];
|
|
|
+ if (!fflag && prevsf != sce->sf_idx[w*16+g])
|
|
|
+ fflag = 1;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
its++;
|
|
|
} while (fflag && its < maxits);
|
|
|
|
|
|
+ /** Scout out next nonzero bands */
|
|
|
+ ff_init_nextband_map(sce, nextband);
|
|
|
+
|
|
|
prev = -1;
|
|
|
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
|
|
/** Make sure proper codebooks are set */
|
|
|
- for (g = start = 0; g < sce->ics.num_swb; start += sce->ics.swb_sizes[g++]) {
|
|
|
+ for (g = 0; g < sce->ics.num_swb; g++) {
|
|
|
if (!sce->zeroes[w*16+g]) {
|
|
|
sce->band_type[w*16+g] = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]);
|
|
|
if (sce->band_type[w*16+g] <= 0) {
|
|
|
- sce->zeroes[w*16+g] = 1;
|
|
|
- sce->band_type[w*16+g] = 0;
|
|
|
+ if (!ff_sfdelta_can_remove_band(sce, nextband, prev, w*16+g)) {
|
|
|
+ /** Cannot zero out, make sure it's not attempted */
|
|
|
+ sce->band_type[w*16+g] = 1;
|
|
|
+ } else {
|
|
|
+ sce->zeroes[w*16+g] = 1;
|
|
|
+ sce->band_type[w*16+g] = 0;
|
|
|
+ }
|
|
|
}
|
|
|
} else {
|
|
|
sce->band_type[w*16+g] = 0;
|