]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/aaccoder_twoloop.h
Merge commit '458e53f51fc75d08df884f8e9eb3d7ded23e97b3'
[ffmpeg] / libavcodec / aaccoder_twoloop.h
index e53257fbaa35b46d9605ef98c87cf7a13b3e711c..397a4db5e5a568b00a0375a83057fdd67c5d42ac 100644 (file)
@@ -49,7 +49,6 @@
 #include "aacenc.h"
 #include "aactab.h"
 #include "aacenctab.h"
-#include "aac_tablegen_decl.h"
 
 /** Frequency in Hz for lower limit of noise substitution **/
 #define NOISE_LOW_LIMIT 4000
@@ -77,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];
@@ -103,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;
@@ -159,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);
@@ -192,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;
@@ -242,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];
@@ -434,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 */
@@ -485,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++;
@@ -507,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]) {
@@ -518,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;
                 }
@@ -550,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;
@@ -562,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);
@@ -586,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;
@@ -604,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);
@@ -652,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;
@@ -691,8 +740,11 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
             /** Check that there's no SF delta range violations */
             if (!sce->zeroes[w*16+g]) {
                 if (prev != -1) {
-                    int sfdiff = sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO;
+                    av_unused int sfdiff = sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO;
                     av_assert1(sfdiff >= 0 && sfdiff <= 2*SCALE_MAX_DIFF);
+                } else if (sce->zeroes[0]) {
+                    /** Set global gain to something useful */
+                    sce->sf_idx[0] = sce->sf_idx[w*16+g];
                 }
                 prev = sce->sf_idx[w*16+g];
             }