From: Baptiste Coudurier <baptiste.coudur...@gmail.com>

Signed-off-by: Michael Niedermayer <michae...@gmx.at>
---
 libavcodec/adpcm.c            |   60 ++++++++++++++++++++++++++++++----------
 tests/ref/acodec/adpcm_ima_qt |    4 +-
 tests/ref/fate/qt-ima4-mono   |    2 +-
 tests/ref/fate/qt-ima4-stereo |    2 +-
 4 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index 99fc743..0d48a29 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -151,6 +151,32 @@ static inline short 
adpcm_ima_expand_nibble(ADPCMChannelStatus *c, char nibble,
     return (short)c->predictor;
 }
 
+static inline int adpcm_ima_qt_expand_nibble(ADPCMChannelStatus *c, int 
nibble, int shift)
+{
+    int step_index;
+    int predictor;
+    int diff, step;
+
+    step = ff_adpcm_step_table[c->step_index];
+    step_index = c->step_index + ff_adpcm_index_table[nibble];
+    step_index = av_clip(step_index, 0, 88);
+
+    diff = step >> 3;
+    if (nibble & 4) diff += step;
+    if (nibble & 2) diff += step >> 1;
+    if (nibble & 1) diff += step >> 2;
+
+    if (nibble & 8)
+        predictor = c->predictor - diff;
+    else
+        predictor = c->predictor + diff;
+
+    c->predictor = av_clip_int16(predictor);
+    c->step_index = step_index;
+
+    return c->predictor;
+}
+
 static inline short adpcm_ms_expand_nibble(ADPCMChannelStatus *c, char nibble)
 {
     int predictor;
@@ -353,35 +379,39 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
     case CODEC_ID_ADPCM_IMA_QT:
         n = buf_size - 2*avctx->channels;
         for (channel = 0; channel < avctx->channels; channel++) {
+            int16_t predictor;
+            int step_index;
             cs = &(c->status[channel]);
             /* (pppppp) (piiiiiii) */
 
             /* Bits 15-7 are the _top_ 9 bits of the 16-bit initial predictor 
value */
-            cs->predictor = (*src++) << 8;
-            cs->predictor |= (*src & 0x80);
-            cs->predictor &= 0xFF80;
-
-            /* sign extension */
-            if(cs->predictor & 0x8000)
-                cs->predictor -= 0x10000;
-
-            cs->predictor = av_clip_int16(cs->predictor);
-
-            cs->step_index = (*src++) & 0x7F;
+            predictor  = AV_RB16(src);
+            step_index = predictor & 0x7F;
+            predictor &= 0xFF80;
+            src += 2;
+
+            if (cs->step_index == step_index) {
+                int diff = (int)predictor - cs->predictor;
+                if (diff < 0)
+                    diff = - diff;
+                if (diff > 0x7f)
+                    cs->predictor = predictor;
+            } else {
+                cs->step_index = step_index;
+                cs->predictor = predictor;
+            }
 
             if (cs->step_index > 88){
                 av_log(avctx, AV_LOG_ERROR, "ERROR: step_index = %i\n", 
cs->step_index);
                 cs->step_index = 88;
             }
 
-            cs->step = ff_adpcm_step_table[cs->step_index];
-
             samples = (short*)data + channel;
 
             for(m=32; n>0 && m>0; n--, m--) { /* in QuickTime, IMA is encoded 
by chuncks of 34 bytes (=64 samples) */
-                *samples = adpcm_ima_expand_nibble(cs, src[0] & 0x0F, 3);
+                *samples = adpcm_ima_qt_expand_nibble(cs, src[0] & 0x0F, 3);
                 samples += avctx->channels;
-                *samples = adpcm_ima_expand_nibble(cs, src[0] >> 4  , 3);
+                *samples = adpcm_ima_qt_expand_nibble(cs, src[0] >> 4  , 3);
                 samples += avctx->channels;
                 src ++;
             }
diff --git a/tests/ref/acodec/adpcm_ima_qt b/tests/ref/acodec/adpcm_ima_qt
index 6e44156..89ef60e 100644
--- a/tests/ref/acodec/adpcm_ima_qt
+++ b/tests/ref/acodec/adpcm_ima_qt
@@ -1,4 +1,4 @@
 3c06fd2f7831e3e8735b936e23ca220c *./tests/data/acodec/adpcm_qt.aiff
 281252 ./tests/data/acodec/adpcm_qt.aiff
-9580492803ba1c1a3746367b24b751c8 *./tests/data/adpcm_ima_qt.acodec.out.wav
-stddev:  914.65 PSNR: 37.10 MAXDIFF:34026 bytes:  1058560/  1058400
+fe69de3d3eae063ddbc4f0d125f23d27 *./tests/data/adpcm_ima_qt.acodec.out.wav
+stddev:  916.65 PSNR: 37.09 MAXDIFF:34029 bytes:  1058560/  1058400
diff --git a/tests/ref/fate/qt-ima4-mono b/tests/ref/fate/qt-ima4-mono
index 66767d5..b8fc5f9 100644
--- a/tests/ref/fate/qt-ima4-mono
+++ b/tests/ref/fate/qt-ima4-mono
@@ -1 +1 @@
-721b51fd66c3bb3dc49dd88d404188eb
+e178ed520edf2f46492ae740d88f5815
diff --git a/tests/ref/fate/qt-ima4-stereo b/tests/ref/fate/qt-ima4-stereo
index 5e6b123..84c9f46 100644
--- a/tests/ref/fate/qt-ima4-stereo
+++ b/tests/ref/fate/qt-ima4-stereo
@@ -1 +1 @@
-c9e4c21fb62eca34a533f3a9ad2e394a
+d22be0e193dcbba1068a1ca6ab04cf77
-- 
1.7.1

_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to