]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/adpcm.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavcodec / adpcm.c
index 3cb62e31ed5b49184f6ceafff21ddbdd666e2fc3..a0cd5cc77e390081b8006e61ab2b9f03e9cabd14 100644 (file)
  * Features and limitations:
  *
  * Reference documents:
- * http://www.pcisys.net/~melanson/codecs/simpleaudio.html
- * http://www.geocities.com/SiliconValley/8682/aud3.txt
- * http://openquicktime.sourceforge.net/plugins.htm
- * XAnim sources (xa_codec.c) http://www.rasnaimaging.com/people/lapus/download.html
- * http://www.cs.ucla.edu/~leec/mediabench/applications.html
- * SoX source code http://home.sprynet.com/~cbagwell/sox.html
+ * http://wiki.multimedia.cx/index.php?title=Category:ADPCM_Audio_Codecs
+ * http://www.pcisys.net/~melanson/codecs/simpleaudio.html [dead]
+ * http://www.geocities.com/SiliconValley/8682/aud3.txt [dead]
+ * http://openquicktime.sourceforge.net/
+ * XAnim sources (xa_codec.c) http://xanim.polter.net/
+ * http://www.cs.ucla.edu/~leec/mediabench/applications.html [dead]
+ * SoX source code http://sox.sourceforge.net/
  *
  * CD-ROM XA:
- * http://ku-www.ss.titech.ac.jp/~yatsushi/xaadpcm.html
- * vagpack & depack http://homepages.compuserve.de/bITmASTER32/psx-index.html
+ * http://ku-www.ss.titech.ac.jp/~yatsushi/xaadpcm.html [dead]
+ * vagpack & depack http://homepages.compuserve.de/bITmASTER32/psx-index.html [dead]
  * readstr http://www.geocities.co.jp/Playtown/2004/
  */
 
 /* These are for CD-ROM XA ADPCM */
 static const int xa_adpcm_table[5][2] = {
-   {   0,   0 },
-   {  60,   0 },
-   { 115, -52 },
-   {  98, -55 },
-   { 122, -60 }
+    {   0,   0 },
+    {  60,   0 },
+    { 115, -52 },
+    {  98, -55 },
+    { 122, -60 }
 };
 
 static const int ea_adpcm_table[] = {
-    0, 240, 460, 392, 0, 0, -208, -220, 0, 1,
-    3, 4, 7, 8, 10, 11, 0, -1, -3, -4
+    0,  240,  460,  392,
+    0,    0, -208, -220,
+    0,    1,    3,    4,
+    7,    8,   10,   11,
+    0,   -1,   -3,   -4
 };
 
 // padded to zero where table size is less then 16
@@ -336,27 +340,12 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
     ADPCMDecodeContext *c = avctx->priv_data;
     ADPCMChannelStatus *cs;
     int n, m, channel, i;
-    int block_predictor[2];
     short *samples;
     short *samples_end;
     const uint8_t *src;
     int st; /* stereo */
-
-    /* DK3 ADPCM accounting variables */
-    unsigned char last_byte = 0;
-    unsigned char nibble;
-    int decode_top_nibble_next = 0;
-    int diff_channel;
-
-    /* EA ADPCM state variables */
     uint32_t samples_in_chunk;
-    int32_t previous_left_sample, previous_right_sample;
-    int32_t current_left_sample, current_right_sample;
-    int32_t next_left_sample, next_right_sample;
-    int32_t coeff1l, coeff2l, coeff1r, coeff2r;
-    uint8_t shift_left, shift_right;
     int count1, count2;
-    int coeff[2][2], shift[2];//used in EA MAXIS ADPCM
 
     if (!buf_size)
         return 0;
@@ -376,7 +365,12 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
 
     switch(avctx->codec->id) {
     case CODEC_ID_ADPCM_IMA_QT:
-        n = buf_size - 2*avctx->channels;
+        /* In QuickTime, IMA is encoded by chunks of 34 bytes (=64 samples).
+           Channel data is interleaved per-chunk. */
+        if (buf_size / 34 < avctx->channels) {
+            av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
+            return AVERROR(EINVAL);
+        }
         for (channel = 0; channel < avctx->channels; channel++) {
             int16_t predictor;
             int step_index;
@@ -409,7 +403,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
 
             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) */
+            for (m = 0; m < 32; m++) {
                 *samples = adpcm_ima_qt_expand_nibble(cs, src[0] & 0x0F, 3);
                 samples += avctx->channels;
                 *samples = adpcm_ima_qt_expand_nibble(cs, src[0] >> 4  , 3);
@@ -439,60 +433,66 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
         }
 
         while(src < buf + buf_size){
-            for(m=0; m<4; m++){
-                for(i=0; i<=st; i++)
-                    *samples++ = adpcm_ima_expand_nibble(&c->status[i], src[4*i] & 0x0F, 3);
-                for(i=0; i<=st; i++)
-                    *samples++ = adpcm_ima_expand_nibble(&c->status[i], src[4*i] >> 4  , 3);
-                src++;
+            for (i = 0; i < avctx->channels; i++) {
+                cs = &c->status[i];
+                for (m = 0; m < 4; m++) {
+                    uint8_t v = *src++;
+                    *samples = adpcm_ima_expand_nibble(cs, v & 0x0F, 3);
+                    samples += avctx->channels;
+                    *samples = adpcm_ima_expand_nibble(cs, v >> 4  , 3);
+                    samples += avctx->channels;
+                }
+                samples -= 8 * avctx->channels - 1;
             }
-            src += 4*st;
+            samples += 7 * avctx->channels;
         }
         break;
     case CODEC_ID_ADPCM_4XM:
-        cs = &(c->status[0]);
-        c->status[0].predictor= (int16_t)bytestream_get_le16(&src);
-        if(st){
-            c->status[1].predictor= (int16_t)bytestream_get_le16(&src);
-        }
-        c->status[0].step_index= (int16_t)bytestream_get_le16(&src);
-        if(st){
-            c->status[1].step_index= (int16_t)bytestream_get_le16(&src);
-        }
-        if (cs->step_index < 0) cs->step_index = 0;
-        if (cs->step_index > 88) cs->step_index = 88;
+        for (i = 0; i < avctx->channels; i++)
+            c->status[i].predictor= (int16_t)bytestream_get_le16(&src);
 
-        m= (buf_size - (src - buf))>>st;
-        for(i=0; i<m; i++) {
-            *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[i] & 0x0F, 4);
-            if (st)
-                *samples++ = adpcm_ima_expand_nibble(&c->status[1], src[i+m] & 0x0F, 4);
-            *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[i] >> 4, 4);
-            if (st)
-                *samples++ = adpcm_ima_expand_nibble(&c->status[1], src[i+m] >> 4, 4);
+        for (i = 0; i < avctx->channels; i++) {
+            c->status[i].step_index= (int16_t)bytestream_get_le16(&src);
+            c->status[i].step_index = av_clip(c->status[i].step_index, 0, 88);
         }
 
-        src += m<<st;
+        m= (buf_size - (src - buf))>>st;
 
+        for (i = 0; i < avctx->channels; i++) {
+            samples = (short*)data + i;
+            cs = &c->status[i];
+            for (n = 0; n < m; n++) {
+                uint8_t v = *src++;
+                *samples = adpcm_ima_expand_nibble(cs, v & 0x0F, 4);
+                samples += avctx->channels;
+                *samples = adpcm_ima_expand_nibble(cs, v >> 4  , 4);
+                samples += avctx->channels;
+            }
+        }
+        samples -= (avctx->channels - 1);
         break;
     case CODEC_ID_ADPCM_MS:
+    {
+        int block_predictor;
+
         if (avctx->block_align != 0 && buf_size > avctx->block_align)
             buf_size = avctx->block_align;
         n = buf_size - 7 * avctx->channels;
         if (n < 0)
             return -1;
-        block_predictor[0] = av_clip(*src++, 0, 6);
-        block_predictor[1] = 0;
-        if (st)
-            block_predictor[1] = av_clip(*src++, 0, 6);
+
+        block_predictor = av_clip(*src++, 0, 6);
+        c->status[0].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor];
+        c->status[0].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor];
+        if (st) {
+            block_predictor = av_clip(*src++, 0, 6);
+            c->status[1].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor];
+            c->status[1].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor];
+        }
         c->status[0].idelta = (int16_t)bytestream_get_le16(&src);
         if (st){
             c->status[1].idelta = (int16_t)bytestream_get_le16(&src);
         }
-        c->status[0].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor[0]];
-        c->status[0].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor[0]];
-        c->status[1].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor[1]];
-        c->status[1].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor[1]];
 
         c->status[0].sample1 = bytestream_get_le16(&src);
         if (st) c->status[1].sample1 = bytestream_get_le16(&src);
@@ -509,39 +509,37 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
             src ++;
         }
         break;
+    }
     case CODEC_ID_ADPCM_IMA_DK4:
         if (avctx->block_align != 0 && buf_size > avctx->block_align)
             buf_size = avctx->block_align;
 
-        c->status[0].predictor  = (int16_t)bytestream_get_le16(&src);
-        c->status[0].step_index = *src++;
-        src++;
-        *samples++ = c->status[0].predictor;
-        if (st) {
-            c->status[1].predictor  = (int16_t)bytestream_get_le16(&src);
-            c->status[1].step_index = *src++;
-            src++;
-            *samples++ = c->status[1].predictor;
+        n = buf_size - 4 * avctx->channels;
+        if (n < 0) {
+            av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
+            return AVERROR(EINVAL);
         }
-        while (src < buf + buf_size) {
-
-            /* take care of the top nibble (always left or mono channel) */
-            *samples++ = adpcm_ima_expand_nibble(&c->status[0],
-                src[0] >> 4, 3);
-
-            /* take care of the bottom nibble, which is right sample for
-             * stereo, or another mono sample */
-            if (st)
-                *samples++ = adpcm_ima_expand_nibble(&c->status[1],
-                    src[0] & 0x0F, 3);
-            else
-                *samples++ = adpcm_ima_expand_nibble(&c->status[0],
-                    src[0] & 0x0F, 3);
 
+        for (channel = 0; channel < avctx->channels; channel++) {
+            cs = &c->status[channel];
+            cs->predictor  = (int16_t)bytestream_get_le16(&src);
+            cs->step_index = *src++;
             src++;
+            *samples++ = cs->predictor;
+        }
+        while (n-- > 0) {
+            uint8_t v = *src++;
+            *samples++ = adpcm_ima_expand_nibble(&c->status[0 ], v >> 4  , 3);
+            *samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3);
         }
         break;
     case CODEC_ID_ADPCM_IMA_DK3:
+    {
+        unsigned char last_byte = 0;
+        unsigned char nibble;
+        int decode_top_nibble_next = 0;
+        int diff_channel;
+
         if (avctx->block_align != 0 && buf_size > avctx->block_align)
             buf_size = avctx->block_align;
 
@@ -586,50 +584,41 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
             *samples++ = c->status[0].predictor - c->status[1].predictor;
         }
         break;
+    }
     case CODEC_ID_ADPCM_IMA_ISS:
-        c->status[0].predictor  = (int16_t)AV_RL16(src + 0);
-        c->status[0].step_index = src[2];
-        src += 4;
-        if(st) {
-            c->status[1].predictor  = (int16_t)AV_RL16(src + 0);
-            c->status[1].step_index = src[2];
-            src += 4;
+        n = buf_size - 4 * avctx->channels;
+        if (n < 0) {
+            av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
+            return AVERROR(EINVAL);
         }
 
-        while (src < buf + buf_size) {
+        for (channel = 0; channel < avctx->channels; channel++) {
+            cs = &c->status[channel];
+            cs->predictor  = (int16_t)bytestream_get_le16(&src);
+            cs->step_index = *src++;
+            src++;
+        }
 
+        while (n-- > 0) {
+            uint8_t v1, v2;
+            uint8_t v = *src++;
+            /* nibbles are swapped for mono */
             if (st) {
-                *samples++ = adpcm_ima_expand_nibble(&c->status[0],
-                    src[0] >> 4  , 3);
-                *samples++ = adpcm_ima_expand_nibble(&c->status[1],
-                    src[0] & 0x0F, 3);
+                v1 = v >> 4;
+                v2 = v & 0x0F;
             } else {
-                *samples++ = adpcm_ima_expand_nibble(&c->status[0],
-                    src[0] & 0x0F, 3);
-                *samples++ = adpcm_ima_expand_nibble(&c->status[0],
-                    src[0] >> 4  , 3);
+                v2 = v >> 4;
+                v1 = v & 0x0F;
             }
-
-            src++;
+            *samples++ = adpcm_ima_expand_nibble(&c->status[0 ], v1, 3);
+            *samples++ = adpcm_ima_expand_nibble(&c->status[st], v2, 3);
         }
         break;
     case CODEC_ID_ADPCM_IMA_WS:
-        /* no per-block initialization; just start decoding the data */
         while (src < buf + buf_size) {
-
-            if (st) {
-                *samples++ = adpcm_ima_expand_nibble(&c->status[0],
-                    src[0] >> 4  , 3);
-                *samples++ = adpcm_ima_expand_nibble(&c->status[1],
-                    src[0] & 0x0F, 3);
-            } else {
-                *samples++ = adpcm_ima_expand_nibble(&c->status[0],
-                    src[0] >> 4  , 3);
-                *samples++ = adpcm_ima_expand_nibble(&c->status[0],
-                    src[0] & 0x0F, 3);
-            }
-
-            src++;
+            uint8_t v = *src++;
+            *samples++ = adpcm_ima_expand_nibble(&c->status[0],  v >> 4  , 3);
+            *samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3);
         }
         break;
     case CODEC_ID_ADPCM_XA:
@@ -641,10 +630,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
             buf_size -= 128;
         }
         break;
-    case CODEC_ID_ADPCM_IMA_EA_EACS:
+    case CODEC_ID_ADPCM_IMA_EA_EACS: {
+        unsigned header_size = 4 + (8<<st);
         samples_in_chunk = bytestream_get_le32(&src) >> (1-st);
 
-        if (samples_in_chunk > buf_size-4-(8<<st)) {
+        if (buf_size < header_size || samples_in_chunk > buf_size - header_size) {
             src += buf_size - 4;
             break;
         }
@@ -659,6 +649,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
             *samples++ = adpcm_ima_expand_nibble(&c->status[st], *src&0x0F, 3);
         }
         break;
+    }
     case CODEC_ID_ADPCM_IMA_EA_SEAD:
         for (; src < buf+buf_size; src++) {
             *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[0] >> 4, 6);
@@ -666,6 +657,13 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
         }
         break;
     case CODEC_ID_ADPCM_EA:
+    {
+        int32_t previous_left_sample, previous_right_sample;
+        int32_t current_left_sample, current_right_sample;
+        int32_t next_left_sample, next_right_sample;
+        int32_t coeff1l, coeff2l, coeff1r, coeff2r;
+        uint8_t shift_left, shift_right;
+
         /* Each EA ADPCM frame has a 12-byte header followed by 30-byte pieces,
            each coding 28 stereo samples. */
         if (buf_size < 12) {
@@ -719,7 +717,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
             src += 2; // Skip terminating 0x0000
 
         break;
+    }
     case CODEC_ID_ADPCM_EA_MAXIS_XA:
+    {
+        int coeff[2][2], shift[2];
+
         for(channel = 0; channel < avctx->channels; channel++) {
             for (i=0; i<2; i++)
                 coeff[channel][i] = ea_adpcm_table[(*src >> 4) + 4*i];
@@ -741,6 +743,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
             src+=avctx->channels;
         }
         break;
+    }
     case CODEC_ID_ADPCM_EA_R1:
     case CODEC_ID_ADPCM_EA_R2:
     case CODEC_ID_ADPCM_EA_R3: {
@@ -883,18 +886,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
         break;
     case CODEC_ID_ADPCM_CT:
         while (src < buf + buf_size) {
-            if (st) {
-                *samples++ = adpcm_ct_expand_nibble(&c->status[0],
-                    src[0] >> 4);
-                *samples++ = adpcm_ct_expand_nibble(&c->status[1],
-                    src[0] & 0x0F);
-            } else {
-                *samples++ = adpcm_ct_expand_nibble(&c->status[0],
-                    src[0] >> 4);
-                *samples++ = adpcm_ct_expand_nibble(&c->status[0],
-                    src[0] & 0x0F);
-            }
-            src++;
+            uint8_t v = *src++;
+            *samples++ = adpcm_ct_expand_nibble(&c->status[0 ], v >> 4  );
+            *samples++ = adpcm_ct_expand_nibble(&c->status[st], v & 0x0F);
         }
         break;
     case CODEC_ID_ADPCM_SBPRO_4:
@@ -1002,18 +996,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
     }
     case CODEC_ID_ADPCM_YAMAHA:
         while (src < buf + buf_size) {
-            if (st) {
-                *samples++ = adpcm_yamaha_expand_nibble(&c->status[0],
-                        src[0] & 0x0F);
-                *samples++ = adpcm_yamaha_expand_nibble(&c->status[1],
-                        src[0] >> 4  );
-            } else {
-                *samples++ = adpcm_yamaha_expand_nibble(&c->status[0],
-                        src[0] & 0x0F);
-                *samples++ = adpcm_yamaha_expand_nibble(&c->status[0],
-                        src[0] >> 4  );
-            }
-            src++;
+            uint8_t v = *src++;
+            *samples++ = adpcm_yamaha_expand_nibble(&c->status[0 ], v & 0x0F);
+            *samples++ = adpcm_yamaha_expand_nibble(&c->status[st], v >> 4  );
         }
         break;
     case CODEC_ID_ADPCM_THP: