diff options
author | Claudio Freire <klaussfreire@gmail.com> | 2015-10-11 23:00:46 -0300 |
---|---|---|
committer | Claudio Freire <klaussfreire@gmail.com> | 2015-10-11 23:00:46 -0300 |
commit | 07b3b779a9f75c73f8e9e638d67bff1e8d244392 (patch) | |
tree | 0ff4714bebec5ba938091035ae27756f0ea46b0e /libavcodec/aaccoder_twoloop.h | |
parent | d25c033ddd7326d06a2fa91905e10720063952ce (diff) | |
download | ffmpeg-07b3b779a9f75c73f8e9e638d67bff1e8d244392.tar.gz |
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)
Diffstat (limited to 'libavcodec/aaccoder_twoloop.h')
-rw-r--r-- | libavcodec/aaccoder_twoloop.h | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/libavcodec/aaccoder_twoloop.h b/libavcodec/aaccoder_twoloop.h index f4bb01c2a6..a46f8dc809 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]; + } } } } |