History

AAC encoder: improve SF range utilization

This patch does 4 things, all of which interact and thus it woudln't be possible to commit them separately without causing either quality regressions or assertion failures. Fate comparison targets don't all reflect improvements in quality, yet listening tests show substantially improved quality and stability. 1. Increase SF range utilization. The spec requires SF delta values to be constrained within the range -60..60. The previous code was applying that range to the whole SF array and not only the deltas of consecutive values, because doing so requires smarter code: zeroing or otherwise skipping a band may invalidate lots of SF choices. This patch implements that logic to allow the coders to utilize the full dynamic range of scalefactors, increasing quality quite considerably, and fixing delta-SF-related assertion failures, since now the limitation is enforced rather than asserted. 2. PNS tweaks The previous modification makes big improvements in twoloop's efficiency, and every time that happens PNS logic needs to be tweaked accordingly to avoid it from stepping all over twoloop's decisions. This patch includes modifications of the sort. 3. Account for lowpass cutoff during PSY analysis The closer PSY's allocation is to final allocation the better the quality is, and given these modifications, twoloop is now very efficient at avoiding holes. Thus, to compute accurate thresholds, PSY needs to account for the lowpass applied implicitly during twoloop (by zeroing high bands). This patch makes twoloop set the cutoff in psymodel's context the first time it runs, and makes PSY account for it during threshold computation, making PE and threshold computations closer to the final allocation and thus achieving better subjective quality. 4. Tweaks to RC lambda tracking loop in relation to PNS Without this tweak some corner cases cause quality regressions. Basically, lambda needs to react faster to overall bitrate efficiency changes since now PNS can be quite successful in enforcing maximum bitrates, when PSY allocates too many bits to the lower bands, suppressing the signals RC logic uses to lower lambda in those cases and causing aggressive PNS. This tweak makes PNS much less aggressive, though it can still use some further tweaks. Also update MIPS specializations and adjust fuzz Also in lavc/mips/aacpsy_mips.h: remove trailing whitespace

Claudio Freire committed 10 years ago

Commit ca203e91 parent ec83efd11 files · +393 −177Browse files

Unified · Split

11 files
  1. libavcodec/aaccoder.c +41 −19
  2. libavcodec/aaccoder_twoloop.h +93 −43
  3. libavcodec/aacenc.c +1 −1
  4. libavcodec/aacenc_is.c +9 −2
  5. libavcodec/aacenc_utils.h +63 −0
  6. libavcodec/aacpsy.c +13 −7
  7. libavcodec/mips/aaccoder_mips.c +117 −55
  8. libavcodec/mips/aacpsy_mips.h +41 −37
  9. libavcodec/psymodel.c +1 −0
  10. libavcodec/psymodel.h +1 −0
  11. tests/fate/aac.mak +13 −13
libavcodec/aaccoder.c+41−19
@@ -54,7 +54,7 @@ · 53 unmodified lines
5454
5555 /* Parameter of f(x) = a*(lambda/100), defines the maximum fourier spread
5656 * beyond which no PNS is used (since the SFBs contain tone rather than noise) */
57−#define NOISE_SPREAD_THRESHOLD 0.5073f
57+#define NOISE_SPREAD_THRESHOLD 0.9f
5858
5959 /* Parameter of f(x) = a*(100/lambda), defines how much PNS is allowed to
6060 * replace low energy non zero bands */
@@ -591,6 +591,7 @@ static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChanne · 530 unmodified lines
591591 int bandwidth, cutoff;
592592 float *PNS = &s->scoefs[0*128], *PNS34 = &s->scoefs[1*128];
593593 float *NOR34 = &s->scoefs[3*128];
594+ uint8_t nextband[128];
594595 const float lambda = s->lambda;
595596 const float freq_mult = avctx->sample_rate*0.5f/wlen;
596597 const float thr_mult = NOISE_LAMBDA_REPLACE*(100.0f/lambda);
@@ -604,6 +605,7 @@ static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChanne · 7 unmodified lines
604605
605606 /** Keep this in sync with twoloop's cutoff selection */
606607 float rate_bandwidth_multiplier = 1.5f;
608+ int prev = -1000, prev_sf = -1;
607609 int frame_bit_rate = (avctx->flags & CODEC_FLAG_QSCALE)
608610 ? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024)
609611 : (avctx->bit_rate / avctx->channels);
@@ -619,6 +621,7 @@ static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChanne · 9 unmodified lines
619621 cutoff = bandwidth * 2 * wlen / avctx->sample_rate;
620622
621623 memcpy(sce->band_alt, sce->band_type, sizeof(sce->band_type));
624+ ff_init_nextband_map(sce, nextband);
622625 for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
623626 int wstart = w*128;
624627 for (g = 0; g < sce->ics.num_swb; g++) {
@@ -655,16 +658,27 @@ static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChanne · 30 unmodified lines
655658 *
656659 * At this stage, point 2 is relaxed for zeroed bands near the noise threshold (hole avoidance is more important)
657660 */
658− if (((sce->zeroes[w*16+g] || !sce->band_alt[w*16+g]) && sfb_energy < threshold*sqrtf(1.5f/freq_boost)) || spread < spread_threshold ||
661+ if ((!sce->zeroes[w*16+g] && !ff_sfdelta_can_remove_band(sce, nextband, prev_sf, w*16+g)) ||
662+ ((sce->zeroes[w*16+g] || !sce->band_alt[w*16+g]) && sfb_energy < threshold*sqrtf(1.0f/freq_boost)) || spread < spread_threshold ||
659663 (!sce->zeroes[w*16+g] && sce->band_alt[w*16+g] && sfb_energy > threshold*thr_mult*freq_boost) ||
660664 min_energy < pns_transient_energy_r * max_energy ) {
661665 sce->pns_ener[w*16+g] = sfb_energy;
666+ if (!sce->zeroes[w*16+g])
667+ prev_sf = sce->sf_idx[w*16+g];
662668 continue;
663669 }
664670
665671 pns_tgt_energy = sfb_energy*FFMIN(1.0f, spread*spread);
666672 noise_sfi = av_clip(roundf(log2f(pns_tgt_energy)*2), -100, 155); /* Quantize */
667673 noise_amp = -ff_aac_pow2sf_tab[noise_sfi + POW_SF2_ZERO]; /* Dequantize */
674+ if (prev != -1000) {
675+ int noise_sfdiff = noise_sfi - prev + SCALE_DIFF_ZERO;
676+ if (noise_sfdiff < 0 || noise_sfdiff > 2*SCALE_MAX_DIFF) {
677+ if (!sce->zeroes[w*16+g])
678+ prev_sf = sce->sf_idx[w*16+g];
679+ continue;
680+ }
681+ }
668682 for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
669683 float band_energy, scale, pns_senergy;
670684 const int start_c = (w+w2)*128+sce->ics.swb_offset[g];
@@ -697,7 +711,10 @@ static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChanne · 26 unmodified lines
697711 if (sce->zeroes[w*16+g] || !sce->band_alt[w*16+g] || (energy_ratio > 0.85f && energy_ratio < 1.25f && dist2 < dist1)) {
698712 sce->band_type[w*16+g] = NOISE_BT;
699713 sce->zeroes[w*16+g] = 0;
714+ prev = noise_sfi;
700715 }
716+ if (!sce->zeroes[w*16+g])
717+ prev_sf = sce->sf_idx[w*16+g];
701718 }
702719 }
703720 }
@@ -775,7 +792,8 @@ static void mark_pns(AACEncContext *s, AVCodecContext *avctx, SingleChannelEleme · 71 unmodified lines
775792
776793 static void search_for_ms(AACEncContext *s, ChannelElement *cpe)
777794 {
778− int start = 0, i, w, w2, g, sid_sf_boost;
795+ int start = 0, i, w, w2, g, sid_sf_boost, prev_mid, prev_side;
796+ uint8_t nextband0[128], nextband1[128];
779797 float M[128], S[128];
780798 float *L34 = s->scoefs, *R34 = s->scoefs + 128, *M34 = s->scoefs + 128*2, *S34 = s->scoefs + 128*3;
781799 const float lambda = s->lambda;
@@ -784,21 +802,19 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe) · 2 unmodified lines
784802 SingleChannelElement *sce1 = &cpe->ch[1];
785803 if (!cpe->common_window)
786804 return;
787− for (w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]) {
788− int min_sf_idx_mid = SCALE_MAX_POS;
789− int min_sf_idx_side = SCALE_MAX_POS;
790− for (g = 0; g < sce0->ics.num_swb; g++) {
791− if (!sce0->zeroes[w*16+g] && sce0->band_type[w*16+g] < RESERVED_BT)
792− min_sf_idx_mid = FFMIN(min_sf_idx_mid, sce0->sf_idx[w*16+g]);
793− if (!sce1->zeroes[w*16+g] && sce1->band_type[w*16+g] < RESERVED_BT)
794− min_sf_idx_side = FFMIN(min_sf_idx_side, sce1->sf_idx[w*16+g]);
795− }
796805
806+ /** Scout out next nonzero bands */
807+ ff_init_nextband_map(sce0, nextband0);
808+ ff_init_nextband_map(sce1, nextband1);
809+
810+ prev_mid = sce0->sf_idx[0];
811+ prev_side = sce1->sf_idx[0];
812+ for (w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]) {
797813 start = 0;
798814 for (g = 0; g < sce0->ics.num_swb; g++) {
799815 float bmax = bval2bmax(g * 17.0f / sce0->ics.num_swb) / 0.0045f;
800816 cpe->ms_mask[w*16+g] = 0;
801− if (!cpe->ch[0].zeroes[w*16+g] && !cpe->ch[1].zeroes[w*16+g]) {
817+ if (!sce0->zeroes[w*16+g] && !sce1->zeroes[w*16+g]) {
802818 float Mmax = 0.0f, Smax = 0.0f;
803819
804820 /* Must compute mid/side SF and book for the whole window group */
@@ -825,16 +841,18 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe) · 20 unmodified lines
825841 int midcb, sidcb;
826842
827843 minidx = FFMIN(sce0->sf_idx[w*16+g], sce1->sf_idx[w*16+g]);
828− mididx = av_clip(minidx, min_sf_idx_mid, min_sf_idx_mid + SCALE_MAX_DIFF);
829− sididx = av_clip(minidx - sid_sf_boost * 3, min_sf_idx_side, min_sf_idx_side + SCALE_MAX_DIFF);
830− midcb = find_min_book(Mmax, mididx);
831− sidcb = find_min_book(Smax, sididx);
832−
833− if ((mididx > minidx) || (sididx > minidx)) {
844+ mididx = av_clip(minidx, 0, SCALE_MAX_POS - SCALE_DIV_512);
845+ sididx = av_clip(minidx - sid_sf_boost * 3, 0, SCALE_MAX_POS - SCALE_DIV_512);
846+ if (!cpe->is_mask[w*16+g] && sce0->band_type[w*16+g] != NOISE_BT && sce1->band_type[w*16+g] != NOISE_BT
847+ && ( !ff_sfdelta_can_replace(sce0, nextband0, prev_mid, mididx, w*16+g)
848+ || !ff_sfdelta_can_replace(sce1, nextband1, prev_side, sididx, w*16+g))) {
834849 /* scalefactor range violation, bad stuff, will decrease quality unacceptably */
835850 continue;
836851 }
837852
853+ midcb = find_min_book(Mmax, mididx);
854+ sidcb = find_min_book(Smax, sididx);
855+
838856 /* No CB can be zero */
839857 midcb = FFMAX(1,midcb);
840858 sidcb = FFMAX(1,sidcb);
@@ -900,6 +918,10 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe) · 59 unmodified lines
900918 }
901919 }
902920 }
921+ if (!sce0->zeroes[w*16+g] && sce0->band_type[w*16+g] < RESERVED_BT)
922+ prev_mid = sce0->sf_idx[w*16+g];
923+ if (!sce1->zeroes[w*16+g] && !cpe->is_mask[w*16+g] && sce1->band_type[w*16+g] < RESERVED_BT)
924+ prev_side = sce1->sf_idx[w*16+g];
903925 start += sce0->ics.swb_sizes[g];
904926 }
905927 }
libavcodec/aaccoder_twoloop.h+93−43
@@ -76,6 +76,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx, · 75 unmodified lines
7676 int refbits = destbits;
7777 int toomanybits, toofewbits;
7878 char nzs[128];
79+ uint8_t nextband[128];
7980 int maxsf[128];
8081 float dists[128] = { 0 }, qenergies[128] = { 0 }, uplims[128], euplims[128], energies[128];
8182 float maxvals[128], spread_thr_r[128];
@@ -102,7 +103,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx, · 20 unmodified lines
102103 */
103104 float sfoffs = av_clipf(log2f(120.0f / lambda) * 4.0f, -5, 10);
104105
105− int fflag, minscaler, maxscaler, nminscaler, minrdsf;
106+ int fflag, minscaler, maxscaler, nminscaler;
106107 int its = 0;
107108 int maxits = 30;
108109 int allz = 0;
@@ -158,9 +159,13 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx, · 49 unmodified lines
158159 /** search further */
159160 maxits *= 2;
160161 } else {
161− /** When using ABR, be strict */
162− toomanybits = destbits + destbits/16;
163− toofewbits = destbits - destbits/4;
162+ /* When using ABR, be strict, but a reasonable leeway is
163+ * critical to allow RC to smoothly track desired bitrate
164+ * without sudden quality drops that cause audible artifacts.
165+ * Symmetry is also desirable, to avoid systematic bias.
166+ */
167+ toomanybits = destbits + destbits/8;
168+ toofewbits = destbits - destbits/8;
164169
165170 sfoffs = 0;
166171 rdlambda = sqrtf(rdlambda);
@@ -191,6 +196,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx, · 24 unmodified lines
191196 bandwidth = avctx->cutoff;
192197 } else {
193198 bandwidth = FFMAX(3000, AAC_CUTOFF_FROM_BITRATE(frame_bit_rate, 1, avctx->sample_rate));
199+ s->psy.cutoff = bandwidth;
194200 }
195201
196202 cutoff = bandwidth * 2 * wlen / avctx->sample_rate;
@@ -241,7 +247,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx, · 44 unmodified lines
241247 nzs[w*16+g] = nz;
242248 sce->zeroes[w*16+g] = !nz;
243249 allz |= nz;
244− if (nz) {
250+ if (nz && sce->can_pns[w*16+g]) {
245251 spread_thr_r[w*16+g] = energy * nz / (uplim * spread);
246252 if (min_spread_thr_r < 0) {
247253 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, · 185 unmodified lines
433439 } while (qstep);
434440
435441 overdist = 1;
442+ fflag = tbits < toofewbits;
436443 for (i = 0; i < 2 && (overdist || recomprd); ++i) {
437444 if (recomprd) {
438445 /** Must recompute distortion */
@@ -484,13 +491,13 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx, · 45 unmodified lines
484491 }
485492 }
486493 }
487− if (!i && s->options.pns && its > maxits/2) {
494+ if (!i && s->options.pns && its > maxits/2 && tbits > toofewbits) {
488495 float maxoverdist = 0.0f;
496+ float ovrfactor = 1.f+(maxits-its)*16.f/maxits;
489497 overdist = recomprd = 0;
490498 for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
491− float ovrfactor = 2.f+(maxits-its)*16.f/maxits;
492499 for (g = start = 0; g < sce->ics.num_swb; start += sce->ics.swb_sizes[g++]) {
493− if (!sce->zeroes[w*16+g] && dists[w*16+g] > uplims[w*16+g]*ovrfactor) {
500+ if (!sce->zeroes[w*16+g] && sce->sf_idx[w*16+g] > SCALE_ONE_POS && dists[w*16+g] > uplims[w*16+g]*ovrfactor) {
494501 float ovrdist = dists[w*16+g] / FFMAX(uplims[w*16+g],euplims[w*16+g]);
495502 maxoverdist = FFMAX(maxoverdist, ovrdist);
496503 overdist++;
@@ -506,7 +513,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx, · 9 unmodified lines
506513 float zspread;
507514 int zeroable = 0;
508515 int zeroed = 0;
509− int maxzeroed;
516+ int maxzeroed, zloop;
510517 for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
511518 for (g = start = 0; g < sce->ics.num_swb; start += sce->ics.swb_sizes[g++]) {
512519 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, · 4 unmodified lines
517524 }
518525 }
519526 zspread = (maxspread-minspread) * 0.0125f + minspread;
520− zspread = FFMIN(maxoverdist, zspread);
521− maxzeroed = zeroable * its / (2 * maxits);
522− for (g = sce->ics.num_swb-1; g > 0 && zeroed < maxzeroed; g--) {
523− if (sce->ics.swb_offset[g] < pns_start_pos)
524− continue;
525− for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
526− if (!sce->zeroes[w*16+g] && sce->can_pns[w*16+g] && spread_thr_r[w*16+g] <= zspread) {
527− sce->zeroes[w*16+g] = 1;
528− sce->band_type[w*16+g] = 0;
529− zeroed++;
527+ /* Don't PNS everything even if allowed. It suppresses bit starvation signals from RC,
528+ * and forced the hand of the later search_for_pns step.
529+ * Instead, PNS a fraction of the spread_thr_r range depending on how starved for bits we are,
530+ * and leave further PNSing to search_for_pns if worthwhile.
531+ */
532+ zspread = FFMIN3(min_spread_thr_r * 8.f, zspread,
533+ ((toomanybits - tbits) * min_spread_thr_r + (tbits - toofewbits) * max_spread_thr_r) / (toomanybits - toofewbits + 1));
534+ maxzeroed = FFMIN(zeroable, FFMAX(1, (zeroable * its + maxits - 1) / (2 * maxits)));
535+ for (zloop = 0; zloop < 2; zloop++) {
536+ /* Two passes: first distorted stuff - two birds in one shot and all that,
537+ * then anything viable. Viable means not zero, but either CB=zero-able
538+ * (too high SF), not SF <= 1 (that means we'd be operating at very high
539+ * quality, we don't want PNS when doing VHQ), PNS allowed, and within
540+ * the lowest ranking percentile.
541+ */
542+ float loopovrfactor = (zloop) ? 1.0f : ovrfactor;
543+ int loopminsf = (zloop) ? (SCALE_ONE_POS - SCALE_DIV_512) : SCALE_ONE_POS;
544+ int mcb;
545+ for (g = sce->ics.num_swb-1; g > 0 && zeroed < maxzeroed; g--) {
546+ if (sce->ics.swb_offset[g] < pns_start_pos)
547+ continue;
548+ for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
549+ if (!sce->zeroes[w*16+g] && sce->can_pns[w*16+g] && spread_thr_r[w*16+g] <= zspread
550+ && sce->sf_idx[w*16+g] > loopminsf
551+ && (dists[w*16+g] > loopovrfactor*uplims[w*16+g] || !(mcb = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]))
552+ || (mcb <= 1 && dists[w*16+g] > FFMIN(uplims[w*16+g], euplims[w*16+g]))) ) {
553+ sce->zeroes[w*16+g] = 1;
554+ sce->band_type[w*16+g] = 0;
555+ zeroed++;
556+ }
530557 }
531558 }
532559 }
533560 if (zeroed)
534− recomprd = 1;
561+ recomprd = fflag = 1;
535562 } else {
536563 overdist = 0;
537564 }
@@ -549,9 +576,8 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx, · 11 unmodified lines
549576 }
550577 }
551578
552− fflag = 0;
553579 minscaler = nminscaler = av_clip(minscaler, SCALE_ONE_POS - SCALE_DIV_512, SCALE_MAX_POS - SCALE_DIV_512);
554− minrdsf = FFMAX3(60, minscaler - 1, maxscaler - SCALE_MAX_DIFF - 1);
580+ prev = -1;
555581 for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
556582 /** Start with big steps, end up fine-tunning */
557583 int depth = (its > maxits/2) ? ((its > maxits*2/3) ? 1 : 3) : 10;
@@ -561,19 +587,22 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx, · 3 unmodified lines
561587 start = w * 128;
562588 for (g = 0; g < sce->ics.num_swb; g++) {
563589 int prevsc = sce->sf_idx[w*16+g];
564− int minrdsfboost = (sce->ics.num_windows > 1) ? av_clip(g-4, -2, 0) : av_clip(g-16, -4, 0);
590+ if (prev < 0 && !sce->zeroes[w*16+g])
591+ prev = sce->sf_idx[0];
565592 if (!sce->zeroes[w*16+g]) {
566593 const float *coefs = sce->coeffs + start;
567594 const float *scaled = s->scoefs + start;
568595 int cmb = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]);
569− if ((!cmb || dists[w*16+g] > uplims[w*16+g]) && sce->sf_idx[w*16+g] > minrdsf) {
596+ int mindeltasf = FFMAX(0, prev - SCALE_MAX_DIFF);
597+ int maxdeltasf = FFMIN(SCALE_MAX_POS - SCALE_DIV_512, prev + SCALE_MAX_DIFF);
598+ if ((!cmb || dists[w*16+g] > uplims[w*16+g]) && sce->sf_idx[w*16+g] > mindeltasf) {
570599 /* Try to make sure there is some energy in every nonzero band
571600 * NOTE: This algorithm must be forcibly imbalanced, pushing harder
572601 * on holes or more distorted bands at first, otherwise there's
573602 * no net gain (since the next iteration will offset all bands
574603 * on the opposite direction to compensate for extra bits)
575604 */
576− for (i = 0; i < edepth; ++i) {
605+ for (i = 0; i < edepth && sce->sf_idx[w*16+g] > mindeltasf; ++i) {
577606 int cb, bits;
578607 float dist, qenergy;
579608 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, · 5 unmodified lines
585614 } else if (i >= depth && dists[w*16+g] < euplims[w*16+g]) {
586615 break;
587616 }
617+ /* !g is the DC band, it's important, since quantization error here
618+ * applies to less than a cycle, it creates horrible intermodulation
619+ * distortion if it doesn't stick to what psy requests
620+ */
621+ if (!g && sce->ics.num_windows > 1 && dists[w*16+g] >= euplims[w*16+g])
622+ maxsf[w*16+g] = FFMIN(sce->sf_idx[w*16+g], maxsf[w*16+g]);
588623 for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
589624 int b;
590625 float sqenergy;
@@ -603,19 +638,19 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx, · 12 unmodified lines
603638 sce->sf_idx[w*16+g]--;
604639 dists[w*16+g] = dist - bits;
605640 qenergies[w*16+g] = qenergy;
606− if (mb && (sce->sf_idx[w*16+g] < (minrdsf+minrdsfboost) || (
641+ if (mb && (sce->sf_idx[w*16+g] < mindeltasf || (
607642 (dists[w*16+g] < FFMIN(uplmax*uplims[w*16+g], euplims[w*16+g]))
608643 && (fabsf(qenergies[w*16+g]-energies[w*16+g]) < euplims[w*16+g])
609644 ) )) {
610645 break;
611646 }
612647 }
613− } else if (tbits > toofewbits && sce->sf_idx[w*16+g] < maxscaler
648+ } else if (tbits > toofewbits && sce->sf_idx[w*16+g] < FFMIN(maxdeltasf, maxsf[w*16+g])
614649 && (dists[w*16+g] < FFMIN(euplims[w*16+g], uplims[w*16+g]))
615650 && (fabsf(qenergies[w*16+g]-energies[w*16+g]) < euplims[w*16+g])
616651 ) {
617652 /** Um... over target. Save bits for more important stuff. */
618− for (i = 0; i < depth; ++i) {
653+ for (i = 0; i < depth && sce->sf_idx[w*16+g] < maxdeltasf; ++i) {
619654 int cb, bits;
620655 float dist, qenergy;
621656 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, · 29 unmodified lines
651686 }
652687 }
653688 }
689+ prev = sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], mindeltasf, maxdeltasf);
690+ if (sce->sf_idx[w*16+g] != prevsc)
691+ fflag = 1;
692+ nminscaler = FFMIN(nminscaler, sce->sf_idx[w*16+g]);
693+ sce->band_type[w*16+g] = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]);
654694 }
655− sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minrdsf, minscaler + SCALE_MAX_DIFF);
656− sce->sf_idx[w*16+g] = FFMIN(sce->sf_idx[w*16+g], SCALE_MAX_POS - SCALE_DIV_512);
657− if (sce->sf_idx[w*16+g] != prevsc)
658− fflag = 1;
659− nminscaler = FFMIN(nminscaler, sce->sf_idx[w*16+g]);
660− sce->band_type[w*16+g] = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]);
661695 start += sce->ics.swb_sizes[g];
662696 }
663697 }
664− if (nminscaler < minscaler || sce->ics.num_windows > 1) {
665− /** SF difference limit violation risk. Must re-clamp. */
666− minscaler = nminscaler;
667− for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
668− for (g = 0; g < sce->ics.num_swb; g++) {
669− sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minscaler, minscaler + SCALE_MAX_DIFF);
698+
699+ /** SF difference limit violation risk. Must re-clamp. */
700+ prev = -1;
701+ for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
702+ for (g = 0; g < sce->ics.num_swb; g++) {
703+ if (!sce->zeroes[w*16+g]) {
704+ int prevsf = sce->sf_idx[w*16+g];
705+ if (prev < 0)
706+ prev = prevsf;
707+ sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], prev - SCALE_MAX_DIFF, prev + SCALE_MAX_DIFF);
670708 sce->band_type[w*16+g] = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]);
709+ prev = sce->sf_idx[w*16+g];
710+ if (!fflag && prevsf != sce->sf_idx[w*16+g])
711+ fflag = 1;
671712 }
672713 }
673714 }
715+
674716 its++;
675717 } while (fflag && its < maxits);
676718
719+ /** Scout out next nonzero bands */
720+ ff_init_nextband_map(sce, nextband);
721+
677722 prev = -1;
678723 for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
679724 /** Make sure proper codebooks are set */
680− for (g = start = 0; g < sce->ics.num_swb; start += sce->ics.swb_sizes[g++]) {
725+ for (g = 0; g < sce->ics.num_swb; g++) {
681726 if (!sce->zeroes[w*16+g]) {
682727 sce->band_type[w*16+g] = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]);
683728 if (sce->band_type[w*16+g] <= 0) {
684− sce->zeroes[w*16+g] = 1;
685− sce->band_type[w*16+g] = 0;
729+ if (!ff_sfdelta_can_remove_band(sce, nextband, prev, w*16+g)) {
730+ /** Cannot zero out, make sure it's not attempted */
731+ sce->band_type[w*16+g] = 1;
732+ } else {
733+ sce->zeroes[w*16+g] = 1;
734+ sce->band_type[w*16+g] = 0;
735+ }
686736 }
687737 } else {
688738 sce->band_type[w*16+g] = 0;
libavcodec/aacenc.c+1−1
@@ -793,7 +793,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, · 792 unmodified lines
793793 s->lambda = FFMIN(s->lambda * ratio, 65536.f);
794794
795795 /* Keep iterating if we must reduce and lambda is in the sky */
796− if ((s->lambda < 300.f || ratio > 0.9f) && (s->lambda > 10.f || ratio < 1.1f)) {
796+ if (ratio > 0.9f && ratio < 1.1f) {
797797 break;
798798 } else {
799799 if (is_mode || ms_mode || tns_mode || pred_mode) {
libavcodec/aacenc_is.c+9−2
@@ -99,18 +99,23 @@ void ff_aac_search_for_is(AACEncContext *s, AVCodecContext *avctx, ChannelElemen · 98 unmodified lines
9999 {
100100 SingleChannelElement *sce0 = &cpe->ch[0];
101101 SingleChannelElement *sce1 = &cpe->ch[1];
102− int start = 0, count = 0, w, w2, g, i;
102+ int start = 0, count = 0, w, w2, g, i, prev_sf1 = -1;
103103 const float freq_mult = avctx->sample_rate/(1024.0f/sce0->ics.num_windows)/2.0f;
104+ uint8_t nextband1[128];
104105
105106 if (!cpe->common_window)
106107 return;
107108
109+ /** Scout out next nonzero bands */
110+ ff_init_nextband_map(sce1, nextband1);
111+
108112 for (w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]) {
109113 start = 0;
110114 for (g = 0; g < sce0->ics.num_swb; g++) {
111115 if (start*freq_mult > INT_STEREO_LOW_LIMIT*(s->lambda/170.0f) &&
112116 cpe->ch[0].band_type[w*16+g] != NOISE_BT && !cpe->ch[0].zeroes[w*16+g] &&
113− cpe->ch[1].band_type[w*16+g] != NOISE_BT && !cpe->ch[1].zeroes[w*16+g]) {
117+ cpe->ch[1].band_type[w*16+g] != NOISE_BT && !cpe->ch[1].zeroes[w*16+g] &&
118+ ff_sfdelta_can_remove_band(sce1, nextband1, prev_sf1, w*16+g)) {
114119 float ener0 = 0.0f, ener1 = 0.0f, ener01 = 0.0f, ener01p = 0.0f;
115120 struct AACISError ph_err1, ph_err2, *erf;
116121 if (sce0->band_type[w*16+g] == NOISE_BT ||
@@ -142,6 +147,8 @@ void ff_aac_search_for_is(AACEncContext *s, AVCodecContext *avctx, ChannelElemen · 25 unmodified lines
142147 count++;
143148 }
144149 }
150+ if (!sce1->zeroes[w*16+g] && sce1->band_type[w*16+g] < RESERVED_BT)
151+ prev_sf1 = sce1->sf_idx[w*16+g];
145152 start += sce0->ics.swb_sizes[g];
146153 }
147154 }
libavcodec/aacenc_utils.h+63−0
@@ -191,6 +191,69 @@ static inline int lcg_random(unsigned previous_val) · 190 unmodified lines
191191 return v.s;
192192 }
193193
194+
195+/*
196+ * Compute a nextband map to be used with SF delta constraint utilities.
197+ * The nextband array should contain 128 elements, and positions that don't
198+ * map to valid, nonzero bands of the form w*16+g (with w being the initial
199+ * window of the window group, only) are left indetermined.
200+ */
201+static inline void ff_init_nextband_map(const SingleChannelElement *sce, uint8_t *nextband)
202+{
203+ unsigned char prevband = 0;
204+ int w, g;
205+ /** Just a safe default */
206+ for (g = 0; g < 128; g++)
207+ nextband[g] = g;
208+
209+ /** Now really navigate the nonzero band chain */
210+ for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
211+ for (g = 0; g < sce->ics.num_swb; g++) {
212+ if (!sce->zeroes[w*16+g] && sce->band_type[w*16+g] < RESERVED_BT)
213+ prevband = nextband[prevband] = w*16+g;
214+ }
215+ }
216+ nextband[prevband] = prevband; /* terminate */
217+}
218+
219+/*
220+ * Updates nextband to reflect a removed band (equivalent to
221+ * calling ff_init_nextband_map after marking a band as zero)
222+ */
223+static inline void ff_nextband_remove(uint8_t *nextband, int prevband, int band)
224+{
225+ nextband[prevband] = nextband[band];
226+}
227+
228+/*
229+ * Checks whether the specified band could be removed without inducing
230+ * scalefactor delta that violates SF delta encoding constraints.
231+ * prev_sf has to be the scalefactor of the previous nonzero, nonspecial
232+ * band, in encoding order, or negative if there was no such band.
233+ */
234+static inline int ff_sfdelta_can_remove_band(const SingleChannelElement *sce,
235+ const uint8_t *nextband, int prev_sf, int band)
236+{
237+ return prev_sf >= 0
238+ && sce->sf_idx[nextband[band]] >= (prev_sf - SCALE_MAX_DIFF)
239+ && sce->sf_idx[nextband[band]] <= (prev_sf + SCALE_MAX_DIFF);
240+}
241+
242+/*
243+ * Checks whether the specified band's scalefactor could be replaced
244+ * with another one without violating SF delta encoding constraints.
245+ * prev_sf has to be the scalefactor of the previous nonzero, nonsepcial
246+ * band, in encoding order, or negative if there was no such band.
247+ */
248+static inline int ff_sfdelta_can_replace(const SingleChannelElement *sce,
249+ const uint8_t *nextband, int prev_sf, int new_sf, int band)
250+{
251+ return new_sf >= (prev_sf - SCALE_MAX_DIFF)
252+ && new_sf <= (prev_sf + SCALE_MAX_DIFF)
253+ && sce->sf_idx[nextband[band]] >= (new_sf - SCALE_MAX_DIFF)
254+ && sce->sf_idx[nextband[band]] <= (new_sf + SCALE_MAX_DIFF);
255+}
256+
194257 #define ERROR_IF(cond, ...) \
195258 if (cond) { \
196259 av_log(avctx, AV_LOG_ERROR, __VA_ARGS__); \
libavcodec/aacpsy.c+13−7
@@ -305,7 +305,7 @@ static av_cold int psy_3gpp_init(FFPsyContext *ctx) { · 304 unmodified lines
305305 float prev, minscale, minath, minsnr, pe_min;
306306 int chan_bitrate = ctx->avctx->bit_rate / ((ctx->avctx->flags & CODEC_FLAG_QSCALE) ? 2.0f : ctx->avctx->channels);
307307
308− const int bandwidth = ctx->avctx->cutoff ? ctx->avctx->cutoff : AAC_CUTOFF(ctx->avctx);
308+ const int bandwidth = ctx->cutoff ? ctx->cutoff : AAC_CUTOFF(ctx->avctx);
309309 const float num_bark = calc_bark((float)bandwidth);
310310
311311 ctx->model_priv_data = av_mallocz(sizeof(AacPsyContext));
@@ -595,26 +595,30 @@ static float calc_reduced_thr_3gpp(AacPsyBand *band, float min_snr, · 283 unmodified lines
595595
596596 #ifndef calc_thr_3gpp
597597 static void calc_thr_3gpp(const FFPsyWindowInfo *wi, const int num_bands, AacPsyChannel *pch,
598− const uint8_t *band_sizes, const float *coefs)
598+ const uint8_t *band_sizes, const float *coefs, const int cutoff)
599599 {
600600 int i, w, g;
601− int start = 0;
601+ int start = 0, wstart = 0;
602602 for (w = 0; w < wi->num_windows*16; w += 16) {
603+ wstart = 0;
603604 for (g = 0; g < num_bands; g++) {
604605 AacPsyBand *band = &pch->band[w+g];
605606
606607 float form_factor = 0.0f;
607608 float Temp;
608609 band->energy = 0.0f;
609− for (i = 0; i < band_sizes[g]; i++) {
610− band->energy += coefs[start+i] * coefs[start+i];
611− form_factor += sqrtf(fabs(coefs[start+i]));
610+ if (wstart < cutoff) {
611+ for (i = 0; i < band_sizes[g]; i++) {
612+ band->energy += coefs[start+i] * coefs[start+i];
613+ form_factor += sqrtf(fabs(coefs[start+i]));
614+ }
612615 }
613616 Temp = band->energy > 0 ? sqrtf((float)band_sizes[g] / band->energy) : 0;
614617 band->thr = band->energy * 0.001258925f;
615618 band->nz_lines = form_factor * sqrtf(Temp);
616619
617620 start += band_sizes[g];
621+ wstart += band_sizes[g];
618622 }
619623 }
620624 }
@@ -655,9 +659,11 @@ static void psy_3gpp_analyze_channel(FFPsyContext *ctx, int channel, · 34 unmodified lines
655659 const uint8_t *band_sizes = ctx->bands[wi->num_windows == 8];
656660 AacPsyCoeffs *coeffs = pctx->psy_coef[wi->num_windows == 8];
657661 const float avoid_hole_thr = wi->num_windows == 8 ? PSY_3GPP_AH_THR_SHORT : PSY_3GPP_AH_THR_LONG;
662+ const int bandwidth = ctx->cutoff ? ctx->cutoff : AAC_CUTOFF(ctx->avctx);
663+ const int cutoff = bandwidth * 2048 / wi->num_windows / ctx->avctx->sample_rate;
658664
659665 //calculate energies, initial thresholds and related values - 5.4.2 "Threshold Calculation"
660− calc_thr_3gpp(wi, num_bands, pch, band_sizes, coefs);
666+ calc_thr_3gpp(wi, num_bands, pch, band_sizes, coefs, cutoff);
661667
662668 //modify thresholds and energies - spread, threshold in quiet, pre-echo control
663669 for (w = 0; w < wi->num_windows*16; w += 16) {
libavcodec/mips/aaccoder_mips.c+117−55
@@ -2336,74 +2336,136 @@ static float quantize_band_cost(struct AACEncContext *s, const float *in, · 2335 unmodified lines
23362336
23372337 static void search_for_ms_mips(AACEncContext *s, ChannelElement *cpe)
23382338 {
2339− int start = 0, i, w, w2, g;
2339+ int start = 0, i, w, w2, g, sid_sf_boost, prev_mid, prev_side;
2340+ uint8_t nextband0[128], nextband1[128];
23402341 float M[128], S[128];
23412342 float *L34 = s->scoefs, *R34 = s->scoefs + 128, *M34 = s->scoefs + 128*2, *S34 = s->scoefs + 128*3;
23422343 const float lambda = s->lambda;
2344+ const float mslambda = FFMIN(1.0f, lambda / 120.f);
23432345 SingleChannelElement *sce0 = &cpe->ch[0];
23442346 SingleChannelElement *sce1 = &cpe->ch[1];
23452347 if (!cpe->common_window)
23462348 return;
2349+
2350+ /** Scout out next nonzero bands */
2351+ ff_init_nextband_map(sce0, nextband0);
2352+ ff_init_nextband_map(sce1, nextband1);
2353+
2354+ prev_mid = sce0->sf_idx[0];
2355+ prev_side = sce1->sf_idx[0];
23472356 for (w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]) {
23482357 start = 0;
23492358 for (g = 0; g < sce0->ics.num_swb; g++) {
2350− if (!cpe->ch[0].zeroes[w*16+g] && !cpe->ch[1].zeroes[w*16+g]) {
2351− float dist1 = 0.0f, dist2 = 0.0f;
2359+ float bmax = bval2bmax(g * 17.0f / sce0->ics.num_swb) / 0.0045f;
2360+ cpe->ms_mask[w*16+g] = 0;
2361+ if (!sce0->zeroes[w*16+g] && !sce1->zeroes[w*16+g]) {
2362+ float Mmax = 0.0f, Smax = 0.0f;
2363+
2364+ /* Must compute mid/side SF and book for the whole window group */
23522365 for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) {
2353− FFPsyBand *band0 = &s->psy.ch[s->cur_channel+0].psy_bands[(w+w2)*16+g];
2354− FFPsyBand *band1 = &s->psy.ch[s->cur_channel+1].psy_bands[(w+w2)*16+g];
2355− float minthr = FFMIN(band0->threshold, band1->threshold);
2356− float maxthr = FFMAX(band0->threshold, band1->threshold);
2357− for (i = 0; i < sce0->ics.swb_sizes[g]; i+=4) {
2358− M[i ] = (sce0->coeffs[start+w2*128+i ]
2359− + sce1->coeffs[start+w2*128+i ]) * 0.5;
2360− M[i+1] = (sce0->coeffs[start+w2*128+i+1]
2361− + sce1->coeffs[start+w2*128+i+1]) * 0.5;
2362− M[i+2] = (sce0->coeffs[start+w2*128+i+2]
2363− + sce1->coeffs[start+w2*128+i+2]) * 0.5;
2364− M[i+3] = (sce0->coeffs[start+w2*128+i+3]
2365− + sce1->coeffs[start+w2*128+i+3]) * 0.5;
2366−
2367− S[i ] = M[i ]
2368− - sce1->coeffs[start+w2*128+i ];
2369− S[i+1] = M[i+1]
2370− - sce1->coeffs[start+w2*128+i+1];
2371− S[i+2] = M[i+2]
2372− - sce1->coeffs[start+w2*128+i+2];
2373− S[i+3] = M[i+3]
2374− - sce1->coeffs[start+w2*128+i+3];
2375− }
2376− abs_pow34_v(L34, sce0->coeffs+start+(w+w2)*128, sce0->ics.swb_sizes[g]);
2377− abs_pow34_v(R34, sce1->coeffs+start+(w+w2)*128, sce0->ics.swb_sizes[g]);
2378− abs_pow34_v(M34, M, sce0->ics.swb_sizes[g]);
2379− abs_pow34_v(S34, S, sce0->ics.swb_sizes[g]);
2380− dist1 += quantize_band_cost(s, &sce0->coeffs[start + (w+w2)*128],
2381− L34,
2382− sce0->ics.swb_sizes[g],
2383− sce0->sf_idx[(w+w2)*16+g],
2384− sce0->band_type[(w+w2)*16+g],
2385− lambda / band0->threshold, INFINITY, NULL, NULL, 0);
2386− dist1 += quantize_band_cost(s, &sce1->coeffs[start + (w+w2)*128],
2387− R34,
2388− sce1->ics.swb_sizes[g],
2389− sce1->sf_idx[(w+w2)*16+g],
2390− sce1->band_type[(w+w2)*16+g],
2391− lambda / band1->threshold, INFINITY, NULL, NULL, 0);
2392− dist2 += quantize_band_cost(s, M,
2393− M34,
2394− sce0->ics.swb_sizes[g],
2395− sce0->sf_idx[(w+w2)*16+g],
2396− sce0->band_type[(w+w2)*16+g],
2397− lambda / maxthr, INFINITY, NULL, NULL, 0);
2398− dist2 += quantize_band_cost(s, S,
2399− S34,
2400− sce1->ics.swb_sizes[g],
2401− sce1->sf_idx[(w+w2)*16+g],
2402− sce1->band_type[(w+w2)*16+g],
2403− lambda / minthr, INFINITY, NULL, NULL, 0);
2366+ for (i = 0; i < sce0->ics.swb_sizes[g]; i++) {
2367+ M[i] = (sce0->coeffs[start+(w+w2)*128+i]
2368+ + sce1->coeffs[start+(w+w2)*128+i]) * 0.5;
2369+ S[i] = M[i]
2370+ - sce1->coeffs[start+(w+w2)*128+i];
2371+ }
2372+ abs_pow34_v(M34, M, sce0->ics.swb_sizes[g]);
2373+ abs_pow34_v(S34, S, sce0->ics.swb_sizes[g]);
2374+ for (i = 0; i < sce0->ics.swb_sizes[g]; i++ ) {
2375+ Mmax = FFMAX(Mmax, M34[i]);
2376+ Smax = FFMAX(Smax, S34[i]);
2377+ }
2378+ }
2379+
2380+ for (sid_sf_boost = 0; sid_sf_boost < 4; sid_sf_boost++) {
2381+ float dist1 = 0.0f, dist2 = 0.0f;
2382+ int B0 = 0, B1 = 0;
2383+ int minidx;
2384+ int mididx, sididx;
2385+ int midcb, sidcb;
2386+
2387+ minidx = FFMIN(sce0->sf_idx[w*16+g], sce1->sf_idx[w*16+g]);
2388+ mididx = av_clip(minidx, 0, SCALE_MAX_POS - SCALE_DIV_512);
2389+ sididx = av_clip(minidx - sid_sf_boost * 3, 0, SCALE_MAX_POS - SCALE_DIV_512);
2390+ if (!cpe->is_mask[w*16+g] && sce0->band_type[w*16+g] != NOISE_BT && sce1->band_type[w*16+g] != NOISE_BT
2391+ && ( !ff_sfdelta_can_replace(sce0, nextband0, prev_mid, mididx, w*16+g)
2392+ || !ff_sfdelta_can_replace(sce1, nextband1, prev_side, sididx, w*16+g))) {
2393+ /* scalefactor range violation, bad stuff, will decrease quality unacceptably */
2394+ continue;
2395+ }
2396+
2397+ midcb = find_min_book(Mmax, mididx);
2398+ sidcb = find_min_book(Smax, sididx);
2399+
2400+ /* No CB can be zero */
2401+ midcb = FFMAX(1,midcb);
2402+ sidcb = FFMAX(1,sidcb);
2403+
2404+ for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) {
2405+ FFPsyBand *band0 = &s->psy.ch[s->cur_channel+0].psy_bands[(w+w2)*16+g];
2406+ FFPsyBand *band1 = &s->psy.ch[s->cur_channel+1].psy_bands[(w+w2)*16+g];
2407+ float minthr = FFMIN(band0->threshold, band1->threshold);
2408+ int b1,b2,b3,b4;
2409+ for (i = 0; i < sce0->ics.swb_sizes[g]; i++) {
2410+ M[i] = (sce0->coeffs[start+(w+w2)*128+i]
2411+ + sce1->coeffs[start+(w+w2)*128+i]) * 0.5;
2412+ S[i] = M[i]
2413+ - sce1->coeffs[start+(w+w2)*128+i];
2414+ }
2415+
2416+ abs_pow34_v(L34, sce0->coeffs+start+(w+w2)*128, sce0->ics.swb_sizes[g]);
2417+ abs_pow34_v(R34, sce1->coeffs+start+(w+w2)*128, sce0->ics.swb_sizes[g]);
2418+ abs_pow34_v(M34, M, sce0->ics.swb_sizes[g]);
2419+ abs_pow34_v(S34, S, sce0->ics.swb_sizes[g]);
2420+ dist1 += quantize_band_cost(s, &sce0->coeffs[start + (w+w2)*128],
2421+ L34,
2422+ sce0->ics.swb_sizes[g],
2423+ sce0->sf_idx[(w+w2)*16+g],
2424+ sce0->band_type[(w+w2)*16+g],
2425+ lambda / band0->threshold, INFINITY, &b1, NULL, 0);
2426+ dist1 += quantize_band_cost(s, &sce1->coeffs[start + (w+w2)*128],
2427+ R34,
2428+ sce1->ics.swb_sizes[g],
2429+ sce1->sf_idx[(w+w2)*16+g],
2430+ sce1->band_type[(w+w2)*16+g],
2431+ lambda / band1->threshold, INFINITY, &b2, NULL, 0);
2432+ dist2 += quantize_band_cost(s, M,
2433+ M34,
2434+ sce0->ics.swb_sizes[g],
2435+ sce0->sf_idx[(w+w2)*16+g],
2436+ sce0->band_type[(w+w2)*16+g],
2437+ lambda / minthr, INFINITY, &b3, NULL, 0);
2438+ dist2 += quantize_band_cost(s, S,
2439+ S34,
2440+ sce1->ics.swb_sizes[g],
2441+ sce1->sf_idx[(w+w2)*16+g],
2442+ sce1->band_type[(w+w2)*16+g],
2443+ mslambda / (minthr * bmax), INFINITY, &b4, NULL, 0);
2444+ B0 += b1+b2;
2445+ B1 += b3+b4;
2446+ dist1 -= B0;
2447+ dist2 -= B1;
2448+ }
2449+ cpe->ms_mask[w*16+g] = dist2 <= dist1 && B1 < B0;
2450+ if (cpe->ms_mask[w*16+g]) {
2451+ /* Setting the M/S mask is useful with I/S or PNS, but only the flag */
2452+ if (!cpe->is_mask[w*16+g] && sce0->band_type[w*16+g] != NOISE_BT && sce1->band_type[w*16+g] != NOISE_BT) {
2453+ sce0->sf_idx[w*16+g] = mididx;
2454+ sce1->sf_idx[w*16+g] = sididx;
2455+ sce0->band_type[w*16+g] = midcb;
2456+ sce1->band_type[w*16+g] = sidcb;
2457+ }
2458+ break;
2459+ } else if (B1 > B0) {
2460+ /* More boost won't fix this */
2461+ break;
2462+ }
24042463 }
2405− cpe->ms_mask[w*16+g] = dist2 < dist1;
24062464 }
2465+ if (!sce0->zeroes[w*16+g] && sce0->band_type[w*16+g] < RESERVED_BT)
2466+ prev_mid = sce0->sf_idx[w*16+g];
2467+ if (!sce1->zeroes[w*16+g] && !cpe->is_mask[w*16+g] && sce1->band_type[w*16+g] < RESERVED_BT)
2468+ prev_side = sce1->sf_idx[w*16+g];
24072469 start += sce0->ics.swb_sizes[g];
24082470 }
24092471 }
libavcodec/mips/aacpsy_mips.h+41−37
@@ -61,58 +61,62 @@ · 60 unmodified lines
6161 #if HAVE_INLINE_ASM && HAVE_MIPSFPU && ( PSY_LAME_FIR_LEN == 21 )
6262 static void calc_thr_3gpp_mips(const FFPsyWindowInfo *wi, const int num_bands,
6363 AacPsyChannel *pch, const uint8_t *band_sizes,
64− const float *coefs)
64+ const float *coefs, const int cutoff)
6565 {
6666 int i, w, g;
67− int start = 0;
67+ int start = 0, wstart = 0;
6868 for (w = 0; w < wi->num_windows*16; w += 16) {
69+ wstart = 0;
6970 for (g = 0; g < num_bands; g++) {
7071 AacPsyBand *band = &pch->band[w+g];
7172
7273 float form_factor = 0.0f;
7374 float Temp;
7475 band->energy = 0.0f;
75− for (i = 0; i < band_sizes[g]; i+=4) {
76− float a, b, c, d;
77− float ax, bx, cx, dx;
78− float *cf = (float *)&coefs[start+i];
79−
80− __asm__ volatile (
81− "lwc1 %[a], 0(%[cf]) \n\t"
82− "lwc1 %[b], 4(%[cf]) \n\t"
83− "lwc1 %[c], 8(%[cf]) \n\t"
84− "lwc1 %[d], 12(%[cf]) \n\t"
85− "abs.s %[a], %[a] \n\t"
86− "abs.s %[b], %[b] \n\t"
87− "abs.s %[c], %[c] \n\t"
88− "abs.s %[d], %[d] \n\t"
89− "sqrt.s %[ax], %[a] \n\t"
90− "sqrt.s %[bx], %[b] \n\t"
91− "sqrt.s %[cx], %[c] \n\t"
92− "sqrt.s %[dx], %[d] \n\t"
93− "madd.s %[e], %[e], %[a], %[a] \n\t"
94− "madd.s %[e], %[e], %[b], %[b] \n\t"
95− "madd.s %[e], %[e], %[c], %[c] \n\t"
96− "madd.s %[e], %[e], %[d], %[d] \n\t"
97− "add.s %[f], %[f], %[ax] \n\t"
98− "add.s %[f], %[f], %[bx] \n\t"
99− "add.s %[f], %[f], %[cx] \n\t"
100− "add.s %[f], %[f], %[dx] \n\t"
101−
102− : [a]"=&f"(a), [b]"=&f"(b),
103− [c]"=&f"(c), [d]"=&f"(d),
104− [e]"+f"(band->energy), [f]"+f"(form_factor),
105− [ax]"=&f"(ax), [bx]"=&f"(bx),
106− [cx]"=&f"(cx), [dx]"=&f"(dx)
107− : [cf]"r"(cf)
108− : "memory"
109− );
76+ if (wstart < cutoff) {
77+ for (i = 0; i < band_sizes[g]; i+=4) {
78+ float a, b, c, d;
79+ float ax, bx, cx, dx;
80+ float *cf = (float *)&coefs[start+i];
81+
82+ __asm__ volatile (
83+ "lwc1 %[a], 0(%[cf]) \n\t"
84+ "lwc1 %[b], 4(%[cf]) \n\t"
85+ "lwc1 %[c], 8(%[cf]) \n\t"
86+ "lwc1 %[d], 12(%[cf]) \n\t"
87+ "abs.s %[a], %[a] \n\t"
88+ "abs.s %[b], %[b] \n\t"
89+ "abs.s %[c], %[c] \n\t"
90+ "abs.s %[d], %[d] \n\t"
91+ "sqrt.s %[ax], %[a] \n\t"
92+ "sqrt.s %[bx], %[b] \n\t"
93+ "sqrt.s %[cx], %[c] \n\t"
94+ "sqrt.s %[dx], %[d] \n\t"
95+ "madd.s %[e], %[e], %[a], %[a] \n\t"
96+ "madd.s %[e], %[e], %[b], %[b] \n\t"
97+ "madd.s %[e], %[e], %[c], %[c] \n\t"
98+ "madd.s %[e], %[e], %[d], %[d] \n\t"
99+ "add.s %[f], %[f], %[ax] \n\t"
100+ "add.s %[f], %[f], %[bx] \n\t"
101+ "add.s %[f], %[f], %[cx] \n\t"
102+ "add.s %[f], %[f], %[dx] \n\t"
103+
104+ : [a]"=&f"(a), [b]"=&f"(b),
105+ [c]"=&f"(c), [d]"=&f"(d),
106+ [e]"+f"(band->energy), [f]"+f"(form_factor),
107+ [ax]"=&f"(ax), [bx]"=&f"(bx),
108+ [cx]"=&f"(cx), [dx]"=&f"(dx)
109+ : [cf]"r"(cf)
110+ : "memory"
111+ );
112+ }
110113 }
111114
112115 Temp = sqrtf((float)band_sizes[g] / band->energy);
113116 band->thr = band->energy * 0.001258925f;
114117 band->nz_lines = form_factor * sqrtf(Temp);
115118 start += band_sizes[g];
119+ wstart += band_sizes[g];
116120 }
117121 }
118122 }
libavcodec/psymodel.c+1−0
@@ -39,6 +39,7 @@ av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx, int num_lens, · 38 unmodified lines
3939 ctx->group = av_mallocz_array(sizeof(ctx->group[0]), num_groups);
4040 ctx->bands = av_malloc_array (sizeof(ctx->bands[0]), num_lens);
4141 ctx->num_bands = av_malloc_array (sizeof(ctx->num_bands[0]), num_lens);
42+ ctx->cutoff = avctx->cutoff;
4243
4344 if (!ctx->ch || !ctx->group || !ctx->bands || !ctx->num_bands) {
4445 ff_psy_end(ctx);
libavcodec/psymodel.h+1−0
@@ -93,6 +93,7 @@ typedef struct FFPsyContext { · 92 unmodified lines
9393 FFPsyChannel *ch; ///< single channel information
9494 FFPsyChannelGroup *group; ///< channel group information
9595 int num_groups; ///< number of channel groups
96+ int cutoff; ///< lowpass frequency cutoff for analysis
9697
9798 uint8_t **bands; ///< scalefactor band sizes for possible frame sizes
9899 int *num_bands; ///< number of scalefactor bands for possible frame sizes
tests/fate/aac.mak+13−13
@@ -146,16 +146,16 @@ fate-aac-aref-encode: CMD = enc_dec_pcm adts wav s16le $(REF) -strict -2 -c:a aa · 145 unmodified lines
146146 fate-aac-aref-encode: CMP = stddev
147147 fate-aac-aref-encode: REF = ./tests/data/asynth-44100-2.wav
148148 fate-aac-aref-encode: CMP_SHIFT = -4096
149−fate-aac-aref-encode: CMP_TARGET = 1139
149+fate-aac-aref-encode: CMP_TARGET = 670
150150 fate-aac-aref-encode: SIZE_TOLERANCE = 2464
151−fate-aac-aref-encode: FUZZ = 6
151+fate-aac-aref-encode: FUZZ = 89
152152
153153 FATE_AAC_ENCODE += fate-aac-ln-encode
154154 fate-aac-ln-encode: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav -strict -2 -c:a aac -aac_is 0 -aac_pns 0 -aac_ms 0 -aac_tns 0 -b:a 512k
155155 fate-aac-ln-encode: CMP = stddev
156156 fate-aac-ln-encode: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav
157157 fate-aac-ln-encode: CMP_SHIFT = -4096
158−fate-aac-ln-encode: CMP_TARGET = 80
158+fate-aac-ln-encode: CMP_TARGET = 50
159159 fate-aac-ln-encode: SIZE_TOLERANCE = 3560
160160 fate-aac-ln-encode: FUZZ = 30
161161
@@ -164,7 +164,7 @@ fate-aac-ln-encode-128k: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audi · 2 unmodified lines
164164 fate-aac-ln-encode-128k: CMP = stddev
165165 fate-aac-ln-encode-128k: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav
166166 fate-aac-ln-encode-128k: CMP_SHIFT = -4096
167−fate-aac-ln-encode-128k: CMP_TARGET = 745
167+fate-aac-ln-encode-128k: CMP_TARGET = 798
168168 fate-aac-ln-encode-128k: SIZE_TOLERANCE = 3560
169169 fate-aac-ln-encode-128k: FUZZ = 5
170170
@@ -173,16 +173,16 @@ fate-aac-pns-encode: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audio-re · 2 unmodified lines
173173 fate-aac-pns-encode: CMP = stddev
174174 fate-aac-pns-encode: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav
175175 fate-aac-pns-encode: CMP_SHIFT = -4096
176−fate-aac-pns-encode: CMP_TARGET = 695
176+fate-aac-pns-encode: CMP_TARGET = 663
177177 fate-aac-pns-encode: SIZE_TOLERANCE = 3560
178−fate-aac-pns-encode: FUZZ = 25
178+fate-aac-pns-encode: FUZZ = 72
179179
180180 FATE_AAC_ENCODE += fate-aac-tns-encode
181181 fate-aac-tns-encode: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav -strict -2 -c:a aac -aac_tns 1 -aac_is 0 -aac_pns 0 -aac_ms 0 -b:a 128k -cutoff 22050
182182 fate-aac-tns-encode: CMP = stddev
183183 fate-aac-tns-encode: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav
184184 fate-aac-tns-encode: CMP_SHIFT = -4096
185−fate-aac-tns-encode: CMP_TARGET = 766
185+fate-aac-tns-encode: CMP_TARGET = 857
186186 fate-aac-tns-encode: FUZZ = 6
187187 fate-aac-tns-encode: SIZE_TOLERANCE = 3560
188188
@@ -191,25 +191,25 @@ fate-aac-is-encode: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audio-ref · 2 unmodified lines
191191 fate-aac-is-encode: CMP = stddev
192192 fate-aac-is-encode: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav
193193 fate-aac-is-encode: CMP_SHIFT = -4096
194−fate-aac-is-encode: CMP_TARGET = 584
194+fate-aac-is-encode: CMP_TARGET = 725
195195 fate-aac-is-encode: SIZE_TOLERANCE = 3560
196−fate-aac-is-encode: FUZZ = 1
196+fate-aac-is-encode: FUZZ = 5
197197
198198 FATE_AAC_ENCODE += fate-aac-ms-encode
199199 fate-aac-ms-encode: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav -strict -2 -c:a aac -aac_pns 0 -aac_is 0 -aac_ms 1 -aac_tns 0 -b:a 128k -cutoff 22050
200200 fate-aac-ms-encode: CMP = stddev
201201 fate-aac-ms-encode: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav
202202 fate-aac-ms-encode: CMP_SHIFT = -4096
203−fate-aac-ms-encode: CMP_TARGET = 615
203+fate-aac-ms-encode: CMP_TARGET = 682
204204 fate-aac-ms-encode: SIZE_TOLERANCE = 3560
205−fate-aac-ms-encode: FUZZ = 10
205+fate-aac-ms-encode: FUZZ = 15
206206
207207 FATE_AAC_ENCODE += fate-aac-ltp-encode
208208 fate-aac-ltp-encode: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav -strict -2 -c:a aac -profile:a aac_ltp -aac_pns 0 -aac_is 0 -aac_ms 0 -aac_tns 0 -b:a 36k -fflags +bitexact -flags +bitexact
209209 fate-aac-ltp-encode: CMP = stddev
210210 fate-aac-ltp-encode: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav
211211 fate-aac-ltp-encode: CMP_SHIFT = -4096
212−fate-aac-ltp-encode: CMP_TARGET = 1120
212+fate-aac-ltp-encode: CMP_TARGET = 1284
213213 fate-aac-ltp-encode: SIZE_TOLERANCE = 3560
214214 fate-aac-ltp-encode: FUZZ = 17
215215
@@ -218,7 +218,7 @@ fate-aac-pred-encode: CMD = enc_dec_pcm adts wav s16le $(TARGET_SAMPLES)/audio-r · 2 unmodified lines
218218 fate-aac-pred-encode: CMP = stddev
219219 fate-aac-pred-encode: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav
220220 fate-aac-pred-encode: CMP_SHIFT = -4096
221−fate-aac-pred-encode: CMP_TARGET = 790
221+fate-aac-pred-encode: CMP_TARGET = 835
222222 fate-aac-pred-encode: FUZZ = 12
223223 fate-aac-pred-encode: SIZE_TOLERANCE = 3560
224224

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t