changeset 1535:bcb30ec7e86f libavcodec

activate the XA and ADX ADPCM codecs
author melanson
date Wed, 15 Oct 2003 03:20:40 +0000
parents 5bdf2017d854
children 992526a710e2
files Makefile adpcm.c allcodecs.c avcodec.h
diffstat 4 files changed, 122 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Wed Oct 15 03:14:14 2003 +0000
+++ b/Makefile	Wed Oct 15 03:20:40 2003 +0000
@@ -18,7 +18,7 @@
       fft.o mdct.o mace.o huffyuv.o cyuv.o opts.o raw.o h264.o golomb.o \
       vp3.o asv1.o 4xm.o cabac.o ffv1.o ra144.o ra288.o vcr1.o cljr.o \
       roqvideo.o dpcm.o interplayvideo.o xan.o rpza.o cinepak.o msrle.o \
-      msvideo1.o vqavideo.o idcinvideo.o
+      msvideo1.o vqavideo.o idcinvideo.o adx.o
 
 ifeq ($(AMR_NB),yes)
 ifeq ($(AMR_NB_FIXED),yes)
--- a/adpcm.c	Wed Oct 15 03:14:14 2003 +0000
+++ b/adpcm.c	Wed Oct 15 03:20:40 2003 +0000
@@ -21,9 +21,10 @@
 /**
  * @file adpcm.c
  * ADPCM codecs.
- * First version by Francois Revol revol@free.fr
+ * First version by Francois Revol (revol@free.fr)
  * Fringe ADPCM codecs (e.g., DK3, DK4, Westwood)
  *   by Mike Melanson (melanson@pcisys.net)
+ * CD-ROM XA ADPCM codec by BERO
  *
  * Features and limitations:
  *
@@ -34,6 +35,11 @@
  * 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
+ *
+ * CD-ROM XA:
+ * http://ku-www.ss.titech.ac.jp/~yatsushi/xaadpcm.html
+ * vagpack & depack http://homepages.compuserve.de/bITmASTER32/psx-index.html
+ * readstr http://www.geocities.co.jp/Playtown/2004/
  */
 
 #define BLKSIZE 1024
@@ -67,7 +73,7 @@
     15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
 };
 
-/* Those are for MS-ADPCM */
+/* These are for MS-ADPCM */
 /* AdaptationTable[], AdaptCoeff1[], and AdaptCoeff2[] are from libsndfile */
 static const int AdaptationTable[] = {
         230, 230, 230, 230, 307, 409, 512, 614,
@@ -82,6 +88,15 @@
         0, -256, 0, 64, 0, -208, -232
 };
 
+/* These are for CD-ROM XA ADPCM */
+const static int xa_adpcm_table[5][2] = {
+   {   0,   0 },
+   {  60,   0 },
+   { 115, -52 },
+   {  98, -55 },
+   { 122, -60 }
+};
+
 /* end of tables */
 
 typedef struct ADPCMChannelStatus {
@@ -355,6 +370,74 @@
     return (short)predictor;
 }
 
+static void xa_decode(short *out, const unsigned char *in, 
+    ADPCMChannelStatus *left, ADPCMChannelStatus *right, int inc)
+{
+    int i, j;
+    int shift,filter,f0,f1;
+    int s_1,s_2;
+    int d,s,t;
+
+    for(i=0;i<4;i++) {
+
+        shift  = 12 - (in[4+i*2] & 15);
+        filter = in[4+i*2] >> 4;
+        f0 = xa_adpcm_table[filter][0];
+        f1 = xa_adpcm_table[filter][1];
+
+        s_1 = left->sample1;
+        s_2 = left->sample2;
+
+        for(j=0;j<28;j++) {
+            d = in[16+i+j*4];
+
+            t = (signed char)(d<<4)>>4;
+            s = ( t<<shift ) + ((s_1*f0 + s_2*f1+32)>>6);
+            CLAMP_TO_SHORT(s);
+            *out = s;
+            out += inc;
+            s_2 = s_1;
+            s_1 = s;
+        }
+
+        if (inc==2) { /* stereo */
+            left->sample1 = s_1;
+            left->sample2 = s_2;
+            s_1 = right->sample1;
+            s_2 = right->sample2;
+            out = out + 1 - 28*2;
+        }
+
+        shift  = 12 - (in[5+i*2] & 15);
+        filter = in[5+i*2] >> 4;
+
+        f0 = xa_adpcm_table[filter][0];
+        f1 = xa_adpcm_table[filter][1];
+
+        for(j=0;j<28;j++) {
+            d = in[16+i+j*4];
+
+            t = (signed char)d >> 4;
+            s = ( t<<shift ) + ((s_1*f0 + s_2*f1+32)>>6);
+            CLAMP_TO_SHORT(s);
+            *out = s;
+            out += inc;
+            s_2 = s_1;
+            s_1 = s;
+        }
+
+        if (inc==2) { /* stereo */
+            right->sample1 = s_1;
+            right->sample2 = s_2;
+            out -= 1;
+        } else {
+            left->sample1 = s_1;
+            left->sample2 = s_2;
+        }
+    }
+}
+
+
 /* DK3 ADPCM support macro */
 #define DK3_GET_NEXT_NIBBLE() \
     if (decode_top_nibble_next) \
@@ -679,6 +762,17 @@
             src++;
         }
         break;
+    case CODEC_ID_ADPCM_XA:
+        c->status[0].sample1 = c->status[0].sample2 = 
+        c->status[1].sample1 = c->status[1].sample2 = 0;
+        while (buf_size >= 128) {
+            xa_decode(samples, src, &c->status[0], &c->status[1], 
+                avctx->channels);
+            src += 128;
+            samples += 28 * 8;
+            buf_size -= 128;
+        }
+        break;
     default:
         *data_size = 0;
         return -1;
@@ -731,5 +825,7 @@
 ADPCM_CODEC(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws);
 ADPCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms);
 ADPCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm);
+ADPCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa);
+ADPCM_CODEC(CODEC_ID_ADPCM_ADX, adpcm_adx);
 
 #undef ADPCM_CODEC
--- a/allcodecs.c	Wed Oct 15 03:14:14 2003 +0000
+++ b/allcodecs.c	Wed Oct 15 03:20:40 2003 +0000
@@ -146,20 +146,30 @@
 
 #ifdef AMR_NB
     register_avcodec(&amr_nb_decoder);
+#ifdef CONFIG_ENCODERS
     register_avcodec(&amr_nb_encoder);
+#endif //CONFIG_ENCODERS
 #endif /* AMR_NB */
 
 #ifdef AMR_WB
     register_avcodec(&amr_wb_decoder);
+#ifdef CONFIG_ENCODERS
     register_avcodec(&amr_wb_encoder);
+#endif //CONFIG_ENCODERS
 #endif /* AMR_WB */
 
     /* pcm codecs */
 
+#ifdef CONFIG_ENCODERS
 #define PCM_CODEC(id, name) \
     register_avcodec(& name ## _encoder); \
     register_avcodec(& name ## _decoder); \
 
+#else
+#define PCM_CODEC(id, name) \
+    register_avcodec(& name ## _decoder);
+#endif
+
 PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le);
 PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be);
 PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le);
@@ -177,6 +187,8 @@
 PCM_CODEC(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws);
 PCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms);
 PCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm);
+PCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa);
+PCM_CODEC(CODEC_ID_ADPCM_ADX, adpcm_adx);
 
 #undef PCM_CODEC
 }
--- a/avcodec.h	Wed Oct 15 03:14:14 2003 +0000
+++ b/avcodec.h	Wed Oct 15 03:20:40 2003 +0000
@@ -101,6 +101,8 @@
     CODEC_ID_ADPCM_IMA_WS,
     CODEC_ID_ADPCM_MS,
     CODEC_ID_ADPCM_4XM,
+    CODEC_ID_ADPCM_XA,
+    CODEC_ID_ADPCM_ADX,
 
 	/* AMR */
     CODEC_ID_AMR_NB,
@@ -138,7 +140,10 @@
  * image data is stored in AVFrame.data[0]. The palette is transported in
  * AVFrame.data[1] and, is 1024 bytes long (256 4-byte entries) and is
  * formatted the same as in PIX_FMT_RGBA32 described above (i.e., it is
- * also endian-specific).
+ * also endian-specific). Note also that the individual RGB palette
+ * components stored in AVFrame.data[1] should be in the range 0..255.
+ * This is important as many custom PAL8 video codecs that were designed
+ * to run on the IBM VGA graphics adapter use 6-bit palette components.
  */
 enum PixelFormat {
     PIX_FMT_YUV420P,   ///< Planar YUV 4:2:0 (1 Cr & Cb sample per 2x2 Y samples)
@@ -1488,6 +1493,8 @@
 PCM_CODEC(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws);
 PCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms);
 PCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm);
+PCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa);
+PCM_CODEC(CODEC_ID_ADPCM_ADX, adpcm_adx);
 
 #undef PCM_CODEC
 
@@ -1741,6 +1748,9 @@
 void *__av_mallocz_static(void** location, unsigned int size);
 #define av_mallocz_static(p, s) __av_mallocz_static((void **)(p), s)
 
+/* add by bero : in adx.c */
+int is_adx(const unsigned char *buf,size_t bufsize);
+
 #ifdef __cplusplus
 }
 #endif