]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/aaccoder.c
libkvazaar: Set frame rate as a rational number
[ffmpeg] / libavcodec / aaccoder.c
index 6fcc6a0eab20351d6ebcca076627736e239d81c4..7d85e43b47fed9b697c724017c15e78057b9ae6d 100644 (file)
@@ -195,23 +195,23 @@ typedef struct TrellisPath {
 
 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];
         }
     }
 
@@ -221,10 +221,12 @@ static void set_special_band_scalefactors(AACEncContext *s, SingleChannelElement
     /* 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);
             }
         }
     }
@@ -643,8 +645,11 @@ static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChanne
             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;
@@ -828,8 +833,9 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe)
         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 */
@@ -858,7 +864,7 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe)
                     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 */
@@ -891,40 +897,42 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe)
                         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) {