diff options
author | Mike Melanson <mike@multimedia.cx> | 2003-10-15 03:20:40 +0000 |
---|---|---|
committer | Mike Melanson <mike@multimedia.cx> | 2003-10-15 03:20:40 +0000 |
commit | fc3847771595fb52e01363d64b0b6b996ef0dfdc (patch) | |
tree | cd460d7005a53b11615beaf894bf8ecf4cdf10b8 | |
parent | f19af812a32c1398d48c3550d11dbc6aafbb2bfc (diff) | |
download | ffmpeg-fc3847771595fb52e01363d64b0b6b996ef0dfdc.tar.gz |
activate the XA and ADX ADPCM codecs
Originally committed as revision 2385 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavcodec/Makefile | 2 | ||||
-rw-r--r-- | libavcodec/adpcm.c | 100 | ||||
-rw-r--r-- | libavcodec/allcodecs.c | 12 | ||||
-rw-r--r-- | libavcodec/avcodec.h | 12 |
4 files changed, 122 insertions, 4 deletions
diff --git a/libavcodec/Makefile b/libavcodec/Makefile index eb1bf0fb58..9aed32c968 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -18,7 +18,7 @@ OBJS= common.o utils.o mem.o allcodecs.o \ 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) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 68a5c6f22f..9e5312663c 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -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 @@ static const int step_table[89] = { 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 @@ static const int AdaptCoeff2[] = { 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 @@ static inline short adpcm_ms_expand_nibble(ADPCMChannelStatus *c, char nibble) 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 @@ static int adpcm_decode_frame(AVCodecContext *avctx, 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_DK4, adpcm_ima_dk4); 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 diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index b9f6d2b914..2626f944e6 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -146,20 +146,30 @@ void avcodec_register_all(void) #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_DK4, adpcm_ima_dk4); 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 } diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 279489b9eb..fe40ce90c7 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -101,6 +101,8 @@ enum CodecID { 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 @@ enum CodecType { * 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_DK4, adpcm_ima_dk4); 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_free_static(void); 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 |