[FFmpeg-cvslog] AAC encoder: fix assertion error re SF differences

Claudio Freire git at videolan.org
Mon Oct 12 04:01:10 CEST 2015


ffmpeg | branch: master | Claudio Freire <klaussfreire at gmail.com> | Sun Oct 11 23:00:46 2015 -0300| [07b3b779a9f75c73f8e9e638d67bff1e8d244392] | committer: Claudio Freire

AAC encoder: fix assertion error re SF differences

Intermediate results can indeed violate SF delta. Instead of asserting
there, just make the code safe, and assert on the final result.

Also re-clamp SFs more often in short windows (which tend to violate
the restriction when encoding the switch from one window to the other)

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=07b3b779a9f75c73f8e9e638d67bff1e8d244392
---

 libavcodec/aaccoder_twoloop.h |   24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/libavcodec/aaccoder_twoloop.h b/libavcodec/aaccoder_twoloop.h
index f4bb01c..a46f8dc 100644
--- a/libavcodec/aaccoder_twoloop.h
+++ b/libavcodec/aaccoder_twoloop.h
@@ -110,6 +110,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
     int tbits;
     int cutoff = 1024;
     int pns_start_pos;
+    int prev;
 
     /**
      * zeroscale controls a multiplier of the threshold, if band energy
@@ -353,8 +354,8 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
         int overdist;
         int qstep = its ? 1 : 32;
         do {
-            int prev = -1;
             int changed = 0;
+            prev = -1;
             recomprd = 0;
             tbits = 0;
             for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
@@ -394,8 +395,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
                     dists[w*16+g] = dist - bits;
                     qenergies[w*16+g] = qenergy;
                     if (prev != -1) {
-                        int sfdiff = sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO;
-                        av_assert1(sfdiff >= 0 && sfdiff <= 2*SCALE_MAX_DIFF);
+                        int sfdiff = av_clip(sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO, 0, 2*SCALE_MAX_DIFF);
                         bits += ff_aac_scalefactor_bits[sfdiff];
                     }
                     tbits += bits;
@@ -436,7 +436,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
         for (i = 0; i < 2 && (overdist || recomprd); ++i) {
             if (recomprd) {
                 /** Must recompute distortion */
-                int prev = -1;
+                prev = -1;
                 tbits = 0;
                 for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
                     start = w*128;
@@ -475,8 +475,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
                         dists[w*16+g] = dist - bits;
                         qenergies[w*16+g] = qenergy;
                         if (prev != -1) {
-                            int sfdiff = sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO;
-                            av_assert1(sfdiff >= 0 && sfdiff <= 2*SCALE_MAX_DIFF);
+                            int sfdiff = av_clip(sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO, 0, 2*SCALE_MAX_DIFF);
                             bits += ff_aac_scalefactor_bits[sfdiff];
                         }
                         tbits += bits;
@@ -662,8 +661,8 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
                 start += sce->ics.swb_sizes[g];
             }
         }
-        if (nminscaler < minscaler) {
-            /** Drecreased some scalers below minscaler. Must re-clamp. */
+        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++) {
@@ -675,6 +674,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
         its++;
     } while (fflag && its < maxits);
 
+    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++]) {
@@ -687,6 +687,14 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
             } else {
                 sce->band_type[w*16+g] = 0;
             }
+            /** 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_assert1(sfdiff >= 0 && sfdiff <= 2*SCALE_MAX_DIFF);
+                }
+                prev = sce->sf_idx[w*16+g];
+            }
         }
     }
 }



More information about the ffmpeg-cvslog mailing list