summaryrefslogtreecommitdiff
path: root/libavcodec/aaccoder_twoloop.h
diff options
context:
space:
mode:
authorClaudio Freire <klaussfreire@gmail.com>2015-10-11 23:00:46 -0300
committerClaudio Freire <klaussfreire@gmail.com>2015-10-11 23:00:46 -0300
commit07b3b779a9f75c73f8e9e638d67bff1e8d244392 (patch)
tree0ff4714bebec5ba938091035ae27756f0ea46b0e /libavcodec/aaccoder_twoloop.h
parentd25c033ddd7326d06a2fa91905e10720063952ce (diff)
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.h24
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];
+ }
}
}
}