summaryrefslogtreecommitdiff
path: root/libavcodec/adpcm.c
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2010-12-01 08:57:45 +0000
committerMartin Storsjö <martin@martin.st>2010-12-01 08:57:45 +0000
commitcfff297d9890a43a51b2f3f0efbfcdd12964b5fe (patch)
tree1a227363a3d34fea4b8a1306f6e90d86ba41844d /libavcodec/adpcm.c
parenta42bb9d624b6a08242d4227ed121dda5f98ecded (diff)
adpcm: Skip samples whose ssd calculation has wrapped around
Wraparound in ssd is mainly avoided by subtracting the ssd of the best node from all the others once it has grown large enough. If using very large trellis sizes (e.g. -trellis 15), the frontier is so large that the difference between the best and the worst is large enough to cause wraparound, even if the ssd of the best one is subtracted regularly. When using -trellis 10 on a 30 second sample, this causes only a slight slowdown, from 61 to 64 seconds. Originally committed as revision 25858 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/adpcm.c')
-rw-r--r--libavcodec/adpcm.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index 1e9ab5b943..ee2ce54ff1 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -382,6 +382,12 @@ static void adpcm_compress_trellis(AVCodecContext *avctx, const short *samples,
dec_sample = av_clip_int16(dec_sample);\
d = sample - dec_sample;\
ssd = nodes[j]->ssd + d*d;\
+ /* Check for wraparound, skip such samples completely. \
+ * Note, changing ssd to a 64 bit variable would be \
+ * simpler, avoiding this check, but it's slower on \
+ * x86 32 bit at the moment. */\
+ if (ssd < nodes[j]->ssd)\
+ goto next_##NAME;\
/* Collapse any two states with the same previous sample value. \
* One could also distinguish states by step and by 2nd to last
* sample, but the effects of that are negligible.