diff options
author | Mike Melanson <mike@multimedia.cx> | 2004-02-03 04:27:16 +0000 |
---|---|---|
committer | Mike Melanson <mike@multimedia.cx> | 2004-02-03 04:27:16 +0000 |
commit | 2abfd77ce354f0d369c86393e4b9a2f0f984db2c (patch) | |
tree | 6ff95b38a2dcc1cf87bc81151338fc9ef844980f | |
parent | d0e05a83c949fe5d0ad638b1450497f5fbbf65b5 (diff) | |
download | xine-lib-2abfd77ce354f0d369c86393e4b9a2f0f984db2c.tar.gz xine-lib-2abfd77ce354f0d369c86393e4b9a2f0f984db2c.tar.bz2 |
ported SMJPEG IMA and EA ADPCM decoders to ffmpeg
CVS patchset: 6109
CVS date: 2004/02/03 04:27:16
-rw-r--r-- | src/libffmpeg/audio_decoder.c | 6 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/adpcm.c | 87 | ||||
-rw-r--r-- | src/libffmpeg/libavcodec/avcodec.h | 4 | ||||
-rw-r--r-- | src/libffmpeg/xine_decoder.c | 4 |
4 files changed, 99 insertions, 2 deletions
diff --git a/src/libffmpeg/audio_decoder.c b/src/libffmpeg/audio_decoder.c index fc1b2dac1..14be0c0f7 100644 --- a/src/libffmpeg/audio_decoder.c +++ b/src/libffmpeg/audio_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_decoder.c,v 1.2 2004/02/01 06:00:56 tmmm Exp $ + * $Id: audio_decoder.c,v 1.3 2004/02/03 04:27:18 tmmm Exp $ * * xine audio decoder plugin using ffmpeg * @@ -88,8 +88,10 @@ static const ff_codec_t ff_audio_lookup[] = { {BUF_AUDIO_DK3ADPCM, CODEC_ID_ADPCM_IMA_DK3, "Duck DK3 ADPCM (ffmpeg)"}, {BUF_AUDIO_DK4ADPCM, CODEC_ID_ADPCM_IMA_DK4, "Duck DK4 ADPCM (ffmpeg)"}, {BUF_AUDIO_VQA_IMA, CODEC_ID_ADPCM_IMA_WS, "Westwood Studios IMA (ffmpeg)"}, + {BUF_AUDIO_SMJPEG_IMA, CODEC_ID_ADPCM_IMA_SMJPEG, "SMJPEG IMA (ffmpeg)"}, {BUF_AUDIO_XA_ADPCM, CODEC_ID_ADPCM_XA, "CD-ROM/XA ADPCM (ffmpeg)"}, {BUF_AUDIO_4X_ADPCM, CODEC_ID_ADPCM_4XM, "4X ADPCM (ffmpeg)"}, + {BUF_AUDIO_EA_ADPCM, CODEC_ID_ADPCM_EA, "Electronic Arts ADPCM (ffmpeg)"}, {BUF_AUDIO_MULAW, CODEC_ID_PCM_MULAW, "mu-law logarithmic PCM (ffmpeg)"}, {BUF_AUDIO_ALAW, CODEC_ID_PCM_ALAW, "A-law logarithmic PCM (ffmpeg)"}, {BUF_AUDIO_ROQ, CODEC_ID_ROQ_DPCM, "RoQ DPCM (ffmpeg)"}, @@ -367,6 +369,8 @@ static uint32_t supported_audio_types[] = { BUF_AUDIO_MAC6, BUF_AUDIO_XAN_DPCM, BUF_AUDIO_VMD, + BUF_AUDIO_EA_ADPCM, + BUF_AUDIO_SMJPEG_IMA, /* BUF_AUDIO_MPEG, */ 0 }; diff --git a/src/libffmpeg/libavcodec/adpcm.c b/src/libffmpeg/libavcodec/adpcm.c index bced66f19..7aee84f65 100644 --- a/src/libffmpeg/libavcodec/adpcm.c +++ b/src/libffmpeg/libavcodec/adpcm.c @@ -25,6 +25,7 @@ * Fringe ADPCM codecs (e.g., DK3, DK4, Westwood) * by Mike Melanson (melanson@pcisys.net) * CD-ROM XA ADPCM codec by BERO + * EA ADPCM decoder by Robin Kay (komadori@myrealbox.com) * * Features and limitations: * @@ -44,6 +45,13 @@ #define BLKSIZE 1024 +#define BE_16(x) ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1]) +#define LE_16(x) ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0]) +#define LE_32(x) ((((uint8_t*)(x))[3] << 24) | \ + (((uint8_t*)(x))[2] << 16) | \ + (((uint8_t*)(x))[1] << 8) | \ + ((uint8_t*)(x))[0]) + #define CLAMP_TO_SHORT(value) \ if (value > 32767) \ value = 32767; \ @@ -97,6 +105,11 @@ static const int xa_adpcm_table[5][2] = { { 122, -60 } }; +static int ea_adpcm_table[] = { + 0, 240, 460, 392, 0, 0, -208, -220, 0, 1, + 3, 4, 7, 8, 10, 11, 0, -1, -3, -4 +}; + /* end of tables */ typedef struct ADPCMChannelStatus { @@ -444,6 +457,15 @@ static int adpcm_decode_frame(AVCodecContext *avctx, 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; + if (!buf_size) return 0; @@ -715,6 +737,69 @@ static int adpcm_decode_frame(AVCodecContext *avctx, buf_size -= 128; } break; + case CODEC_ID_ADPCM_EA: + samples_in_chunk = LE_32(src); + if (samples_in_chunk >= ((buf_size - 12) * 2)) { + src += buf_size; + break; + } + src += 4; + current_left_sample = (int16_t)LE_16(src); + src += 2; + previous_left_sample = (int16_t)LE_16(src); + src += 2; + current_right_sample = (int16_t)LE_16(src); + src += 2; + previous_right_sample = (int16_t)LE_16(src); + src += 2; + + for (count1 = 0; count1 < samples_in_chunk/28;count1++) { + coeff1l = ea_adpcm_table[(*src >> 4) & 0x0F]; + coeff2l = ea_adpcm_table[((*src >> 4) & 0x0F) + 4]; + coeff1r = ea_adpcm_table[*src & 0x0F]; + coeff2r = ea_adpcm_table[(*src & 0x0F) + 4]; + src++; + + shift_left = ((*src >> 4) & 0x0F) + 8; + shift_right = (*src & 0x0F) + 8; + src++; + + for (count2 = 0; count2 < 28; count2++) { + next_left_sample = (((*src & 0xF0) << 24) >> shift_left); + next_right_sample = (((*src & 0x0F) << 28) >> shift_right); + src++; + + next_left_sample = (next_left_sample + + (current_left_sample * coeff1l) + + (previous_left_sample * coeff2l) + 0x80) >> 8; + next_right_sample = (next_right_sample + + (current_right_sample * coeff1r) + + (previous_right_sample * coeff2r) + 0x80) >> 8; + CLAMP_TO_SHORT(next_left_sample); + CLAMP_TO_SHORT(next_right_sample); + + previous_left_sample = current_left_sample; + current_left_sample = next_left_sample; + previous_right_sample = current_right_sample; + current_right_sample = next_right_sample; + *samples++ = (unsigned short)current_left_sample; + *samples++ = (unsigned short)current_right_sample; + } + } + break; + case CODEC_ID_ADPCM_IMA_SMJPEG: + c->status[0].predictor = *src; + src += 2; + c->status[0].step_index = *src++; + src++; /* skip another byte before getting to the meat */ + while (src < buf + buf_size) { + *samples++ = adpcm_ima_expand_nibble(&c->status[0], + *src & 0x0F, 3); + *samples++ = adpcm_ima_expand_nibble(&c->status[0], + (*src >> 4) & 0x0F, 3); + src++; + } + break; default: *data_size = 0; return -1; @@ -765,9 +850,11 @@ ADPCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav); ADPCM_CODEC(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3); 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_IMA_SMJPEG, adpcm_ima_smjpeg); 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); +ADPCM_CODEC(CODEC_ID_ADPCM_EA, adpcm_ea); #undef ADPCM_CODEC diff --git a/src/libffmpeg/libavcodec/avcodec.h b/src/libffmpeg/libavcodec/avcodec.h index 6f26b0685..2e884e834 100644 --- a/src/libffmpeg/libavcodec/avcodec.h +++ b/src/libffmpeg/libavcodec/avcodec.h @@ -117,10 +117,12 @@ enum CodecID { CODEC_ID_ADPCM_IMA_DK3, CODEC_ID_ADPCM_IMA_DK4, CODEC_ID_ADPCM_IMA_WS, + CODEC_ID_ADPCM_IMA_SMJPEG, CODEC_ID_ADPCM_MS, CODEC_ID_ADPCM_4XM, CODEC_ID_ADPCM_XA, CODEC_ID_ADPCM_ADX, + CODEC_ID_ADPCM_EA, /* AMR */ CODEC_ID_AMR_NB, @@ -1727,10 +1729,12 @@ PCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav); PCM_CODEC(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3); 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_SMJPEG, adpcm_ima_smjpeg); 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); +PCM_CODEC(CODEC_ID_ADPCM_EA, adpcm_ea); #undef PCM_CODEC diff --git a/src/libffmpeg/xine_decoder.c b/src/libffmpeg/xine_decoder.c index b45a25eb7..d5d10d0fe 100644 --- a/src/libffmpeg/xine_decoder.c +++ b/src/libffmpeg/xine_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.156 2004/02/01 22:45:18 jstembridge Exp $ + * $Id: xine_decoder.c,v 1.157 2004/02/03 04:27:18 tmmm Exp $ * * xine decoder plugin using ffmpeg * @@ -83,8 +83,10 @@ void avcodec_register_all(void) register_avcodec(&adpcm_ima_dk3_decoder); register_avcodec(&adpcm_ima_dk4_decoder); register_avcodec(&adpcm_ima_ws_decoder); + register_avcodec(&adpcm_ima_smjpeg_decoder); register_avcodec(&adpcm_xa_decoder); register_avcodec(&adpcm_4xm_decoder); + register_avcodec(&adpcm_ea_decoder); register_avcodec(&pcm_alaw_decoder); register_avcodec(&pcm_mulaw_decoder); register_avcodec(&roq_dpcm_decoder); |