# HG changeset patch # User diego # Date 1175961803 0 # Node ID d6b2ddac2c5e7733697092b10c6c595308beb938 # Parent 812f759a7c599195e02052ddd6ef2432adb0062b THP PCM decoder, used on the Nintendo GameCube. patch by Marco Gerards, mgerards xs4all nl diff -r 812f759a7c59 -r d6b2ddac2c5e Makefile --- a/Makefile Sat Apr 07 15:15:45 2007 +0000 +++ b/Makefile Sat Apr 07 16:03:23 2007 +0000 @@ -250,6 +250,7 @@ OBJS-$(CONFIG_ADPCM_SBPRO_4_ENCODER) += adpcm.o OBJS-$(CONFIG_ADPCM_SWF_DECODER) += adpcm.o OBJS-$(CONFIG_ADPCM_SWF_ENCODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_THP_DECODER) += adpcm.o OBJS-$(CONFIG_ADPCM_XA_DECODER) += adpcm.o OBJS-$(CONFIG_ADPCM_XA_ENCODER) += adpcm.o OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER) += adpcm.o diff -r 812f759a7c59 -r d6b2ddac2c5e adpcm.c --- a/adpcm.c Sat Apr 07 15:15:45 2007 +0000 +++ b/adpcm.c Sat Apr 07 16:03:23 2007 +0000 @@ -29,6 +29,7 @@ * by Mike Melanson (melanson@pcisys.net) * CD-ROM XA ADPCM codec by BERO * EA ADPCM decoder by Robin Kay (komadori@myrealbox.com) + * THP ADPCM decoder by Marco Gerards (mgerards@xs4all.nl) * * Features and limitations: * @@ -1308,6 +1309,72 @@ src++; } break; + case CODEC_ID_ADPCM_THP: + { + GetBitContext gb; + int table[16][2]; + unsigned int samplecnt; + int prev1[2], prev2[2]; + int ch; + + if (buf_size < 80) { + av_log(avctx, AV_LOG_ERROR, "frame too small\n"); + return -1; + } + + init_get_bits(&gb, src, buf_size * 8); + src += buf_size; + + get_bits_long(&gb, 32); /* Channel size */ + samplecnt = get_bits_long(&gb, 32); + + for (ch = 0; ch < 2; ch++) + for (i = 0; i < 16; i++) + table[i][ch] = get_sbits(&gb, 16); + + /* Initialize the previous sample. */ + for (ch = 0; ch < 2; ch++) { + prev1[ch] = get_sbits(&gb, 16); + prev2[ch] = get_sbits(&gb, 16); + } + + if (samplecnt >= (samples_end - samples) / (st + 1)) { + av_log(avctx, AV_LOG_ERROR, "allocated output buffer is too small\n"); + return -1; + } + + for (ch = 0; ch <= st; ch++) { + samples = (unsigned short *) data + ch; + + /* Read in every sample for this channel. */ + for (i = 0; i < samplecnt / 14; i++) { + uint8_t index = get_bits (&gb, 4) & 7; + unsigned int exp = get_bits (&gb, 4); + int factor1 = table[index * 2][ch]; + int factor2 = table[index * 2 + 1][ch]; + + /* Decode 14 samples. */ + for (n = 0; n < 14; n++) { + int sampledat = get_sbits (&gb, 4); + + *samples = ((prev1[ch]*factor1 + + prev2[ch]*factor2) >> 11) + (sampledat << exp); + prev2[ch] = prev1[ch]; + prev1[ch] = *samples++; + + /* In case of stereo, skip one sample, this sample + is for the other channel. */ + samples += st; + } + } + } + + /* In the previous loop, in case stereo is used, samples is + increased exactly one time too often. */ + samples -= st; + break; + } + default: return -1; } @@ -1368,5 +1435,6 @@ ADPCM_CODEC(CODEC_ID_ADPCM_SBPRO_4, adpcm_sbpro_4); ADPCM_CODEC(CODEC_ID_ADPCM_SBPRO_3, adpcm_sbpro_3); ADPCM_CODEC(CODEC_ID_ADPCM_SBPRO_2, adpcm_sbpro_2); +ADPCM_CODEC(CODEC_ID_ADPCM_THP, adpcm_thp); #undef ADPCM_CODEC diff -r 812f759a7c59 -r d6b2ddac2c5e allcodecs.c --- a/allcodecs.c Sat Apr 07 15:15:45 2007 +0000 +++ b/allcodecs.c Sat Apr 07 16:03:23 2007 +0000 @@ -244,6 +244,7 @@ REGISTER_ENCDEC (ADPCM_SBPRO_3, adpcm_sbpro_3); REGISTER_ENCDEC (ADPCM_SBPRO_4, adpcm_sbpro_4); REGISTER_ENCDEC (ADPCM_SWF, adpcm_swf); + REGISTER_DECODER(ADPCM_THP, adpcm_thp); REGISTER_ENCDEC (ADPCM_XA, adpcm_xa); REGISTER_ENCDEC (ADPCM_YAMAHA, adpcm_yamaha); diff -r 812f759a7c59 -r d6b2ddac2c5e avcodec.h --- a/avcodec.h Sat Apr 07 15:15:45 2007 +0000 +++ b/avcodec.h Sat Apr 07 16:03:23 2007 +0000 @@ -200,6 +200,7 @@ CODEC_ID_ADPCM_SBPRO_4, CODEC_ID_ADPCM_SBPRO_3, CODEC_ID_ADPCM_SBPRO_2, + CODEC_ID_ADPCM_THP, /* AMR */ CODEC_ID_AMR_NB= 0x12000, @@ -2417,6 +2418,7 @@ PCM_CODEC(CODEC_ID_ADPCM_SBPRO_4, adpcm_sbpro_4); PCM_CODEC(CODEC_ID_ADPCM_SMJPEG, adpcm_ima_smjpeg); PCM_CODEC(CODEC_ID_ADPCM_SWF, adpcm_swf); +PCM_CODEC(CODEC_ID_ADPCM_THP, adpcm_thp); PCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa); PCM_CODEC(CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha);