diff options
author | Justin Ruggles <justin.ruggles@gmail.com> | 2012-08-30 18:08:59 -0400 |
---|---|---|
committer | Justin Ruggles <justin.ruggles@gmail.com> | 2012-10-09 09:03:52 -0400 |
commit | d2b6ae02aa4d80fb19137ec11f3cefb9f71b9b81 (patch) | |
tree | 53dc7b8caf1530d5fbcef5c974674301fde791ac | |
parent | 8b854283c3463d28ceedb55456b362e914e8fe77 (diff) | |
download | ffmpeg-d2b6ae02aa4d80fb19137ec11f3cefb9f71b9b81.tar.gz |
adpcmdec: use planar sample format for adpcm_xa
-rw-r--r-- | libavcodec/adpcm.c | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index fca5f1b88f..92c7943e4f 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -139,6 +139,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) case AV_CODEC_ID_ADPCM_IMA_QT: case AV_CODEC_ID_ADPCM_IMA_WAV: case AV_CODEC_ID_ADPCM_4XM: + case AV_CODEC_ID_ADPCM_XA: avctx->sample_fmt = AV_SAMPLE_FMT_S16P; break; case AV_CODEC_ID_ADPCM_IMA_WS: @@ -277,17 +278,22 @@ static inline short adpcm_yamaha_expand_nibble(ADPCMChannelStatus *c, unsigned c return c->predictor; } -static int xa_decode(AVCodecContext *avctx, - short *out, const unsigned char *in, - ADPCMChannelStatus *left, ADPCMChannelStatus *right, int inc) +static int xa_decode(AVCodecContext *avctx, int16_t *out0, int16_t *out1, + const uint8_t *in, ADPCMChannelStatus *left, + ADPCMChannelStatus *right, int channels, int sample_offset) { int i, j; int shift,filter,f0,f1; int s_1,s_2; int d,s,t; - for(i=0;i<4;i++) { + out0 += sample_offset; + if (channels == 1) + out1 = out0 + 28; + else + out1 += sample_offset; + for(i=0;i<4;i++) { shift = 12 - (in[4+i*2] & 15); filter = in[4+i*2] >> 4; if (filter > 4) { @@ -309,16 +315,14 @@ static int xa_decode(AVCodecContext *avctx, s = ( t<<shift ) + ((s_1*f0 + s_2*f1+32)>>6); s_2 = s_1; s_1 = av_clip_int16(s); - *out = s_1; - out += inc; + out0[j] = s_1; } - if (inc==2) { /* stereo */ + if (channels == 2) { 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); @@ -339,18 +343,19 @@ static int xa_decode(AVCodecContext *avctx, s = ( t<<shift ) + ((s_1*f0 + s_2*f1+32)>>6); s_2 = s_1; s_1 = av_clip_int16(s); - *out = s_1; - out += inc; + out1[j] = s_1; } - if (inc==2) { /* stereo */ + if (channels == 2) { right->sample1 = s_1; right->sample2 = s_2; - out -= 1; } else { left->sample1 = s_1; left->sample2 = s_2; } + + out0 += 28 * (3 - channels); + out1 += 28 * (3 - channels); } return 0; @@ -887,14 +892,21 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, bytestream2_seek(&gb, 0, SEEK_END); break; case AV_CODEC_ID_ADPCM_XA: + { + int16_t *out0 = samples_p[0]; + int16_t *out1 = samples_p[1]; + int samples_per_block = 28 * (3 - avctx->channels) * 4; + int sample_offset = 0; while (bytestream2_get_bytes_left(&gb) >= 128) { - if ((ret = xa_decode(avctx, samples, buf + bytestream2_tell(&gb), &c->status[0], - &c->status[1], avctx->channels)) < 0) + if ((ret = xa_decode(avctx, out0, out1, buf + bytestream2_tell(&gb), + &c->status[0], &c->status[1], + avctx->channels, sample_offset)) < 0) return ret; bytestream2_skipu(&gb, 128); - samples += 28 * 8; + sample_offset += samples_per_block; } break; + } case AV_CODEC_ID_ADPCM_IMA_EA_EACS: for (i=0; i<=st; i++) { c->status[i].step_index = bytestream2_get_le32u(&gb); @@ -1318,5 +1330,5 @@ ADPCM_DECODER(AV_CODEC_ID_ADPCM_SBPRO_3, sample_fmts_s16, adpcm_sbpro_3, ADPCM_DECODER(AV_CODEC_ID_ADPCM_SBPRO_4, sample_fmts_s16, adpcm_sbpro_4, "ADPCM Sound Blaster Pro 4-bit"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_SWF, sample_fmts_s16, adpcm_swf, "ADPCM Shockwave Flash"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_THP, sample_fmts_s16, adpcm_thp, "ADPCM Nintendo Gamecube THP"); -ADPCM_DECODER(AV_CODEC_ID_ADPCM_XA, sample_fmts_s16, adpcm_xa, "ADPCM CDROM XA"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_XA, sample_fmts_s16p, adpcm_xa, "ADPCM CDROM XA"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_YAMAHA, sample_fmts_s16, adpcm_yamaha, "ADPCM Yamaha"); |