* EA ADPCM XAS decoder by Peter Ross (pross@xvid.org)
* MAXIS EA ADPCM decoder by Robert Marston (rmarston@gmail.com)
* THP ADPCM decoder by Marco Gerards (mgerards@xs4all.nl)
+ * Argonaut Games ADPCM decoder by Zane van Iperen (zane@zanevaniperen.com)
+ * Simon & Schuster Interactive ADPCM decoder by Zane van Iperen (zane@zanevaniperen.com)
+ * Ubisoft ADPCM decoder by Zane van Iperen (zane@zanevaniperen.com)
*
* This file is part of FFmpeg.
*
/*5*/ { -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16 }
};
+static const int8_t zork_index_table[8] = {
+ -1, -1, -1, 1, 4, 7, 10, 12,
+};
+
/* end of tables */
typedef struct ADPCMDecodeContext {
break;
case AV_CODEC_ID_ADPCM_IMA_APC:
if (avctx->extradata && avctx->extradata_size >= 8) {
- c->status[0].predictor = AV_RL32(avctx->extradata);
- c->status[1].predictor = AV_RL32(avctx->extradata + 4);
+ c->status[0].predictor = av_clip_intp2(AV_RL32(avctx->extradata ), 18);
+ c->status[1].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 4), 18);
+ }
+ break;
+ case AV_CODEC_ID_ADPCM_IMA_APM:
+ if (avctx->extradata && avctx->extradata_size >= 16) {
+ c->status[0].predictor = AV_RL32(avctx->extradata + 0);
+ c->status[0].step_index = AV_RL32(avctx->extradata + 4);
+ c->status[1].predictor = AV_RL32(avctx->extradata + 8);
+ c->status[1].step_index = AV_RL32(avctx->extradata + 12);
}
break;
case AV_CODEC_ID_ADPCM_IMA_WS:
if (avctx->extradata && avctx->extradata_size >= 2)
c->vqa_version = AV_RL16(avctx->extradata);
break;
+ case AV_CODEC_ID_ADPCM_ARGO:
+ if (avctx->bits_per_coded_sample != 4)
+ return AVERROR_INVALIDDATA;
+ break;
+ case AV_CODEC_ID_ADPCM_ZORK:
+ if (avctx->bits_per_coded_sample != 8)
+ return AVERROR_INVALIDDATA;
+ break;
default:
break;
}
- switch(avctx->codec->id) {
- case AV_CODEC_ID_ADPCM_AICA:
- case AV_CODEC_ID_ADPCM_IMA_DAT4:
- 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:
- case AV_CODEC_ID_ADPCM_EA_R1:
- case AV_CODEC_ID_ADPCM_EA_R2:
- case AV_CODEC_ID_ADPCM_EA_R3:
- case AV_CODEC_ID_ADPCM_EA_XAS:
- case AV_CODEC_ID_ADPCM_THP:
- case AV_CODEC_ID_ADPCM_THP_LE:
- case AV_CODEC_ID_ADPCM_AFC:
- case AV_CODEC_ID_ADPCM_DTK:
- case AV_CODEC_ID_ADPCM_PSX:
- case AV_CODEC_ID_ADPCM_MTAF:
- avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
- break;
- case AV_CODEC_ID_ADPCM_IMA_WS:
- avctx->sample_fmt = c->vqa_version == 3 ? AV_SAMPLE_FMT_S16P :
- AV_SAMPLE_FMT_S16;
- break;
- case AV_CODEC_ID_ADPCM_MS:
- avctx->sample_fmt = avctx->channels > 2 ? AV_SAMPLE_FMT_S16P :
- AV_SAMPLE_FMT_S16;
- break;
- default:
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ switch (avctx->codec->id) {
+ case AV_CODEC_ID_ADPCM_AICA:
+ case AV_CODEC_ID_ADPCM_IMA_DAT4:
+ 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:
+ case AV_CODEC_ID_ADPCM_EA_R1:
+ case AV_CODEC_ID_ADPCM_EA_R2:
+ case AV_CODEC_ID_ADPCM_EA_R3:
+ case AV_CODEC_ID_ADPCM_EA_XAS:
+ case AV_CODEC_ID_ADPCM_THP:
+ case AV_CODEC_ID_ADPCM_THP_LE:
+ case AV_CODEC_ID_ADPCM_AFC:
+ case AV_CODEC_ID_ADPCM_DTK:
+ case AV_CODEC_ID_ADPCM_PSX:
+ case AV_CODEC_ID_ADPCM_MTAF:
+ case AV_CODEC_ID_ADPCM_ARGO:
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
+ break;
+ case AV_CODEC_ID_ADPCM_IMA_WS:
+ avctx->sample_fmt = c->vqa_version == 3 ? AV_SAMPLE_FMT_S16P :
+ AV_SAMPLE_FMT_S16;
+ break;
+ case AV_CODEC_ID_ADPCM_MS:
+ avctx->sample_fmt = avctx->channels > 2 ? AV_SAMPLE_FMT_S16P :
+ AV_SAMPLE_FMT_S16;
+ break;
+ default:
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
}
return 0;
c->predictor = av_clip_intp2(predictor, 11);
c->step_index = step_index;
- return c->predictor << 4;
+ return c->predictor * 16;
}
static inline int16_t adpcm_ct_expand_nibble(ADPCMChannelStatus *c, int8_t nibble)
return c->predictor;
}
+static inline int16_t adpcm_zork_expand_nibble(ADPCMChannelStatus *c, uint8_t nibble)
+{
+ int16_t index = c->step_index;
+ uint32_t lookup_sample = ff_adpcm_step_table[index];
+ int32_t sample = 0;
+
+ if (nibble & 0x40)
+ sample += lookup_sample;
+ if (nibble & 0x20)
+ sample += lookup_sample >> 1;
+ if (nibble & 0x10)
+ sample += lookup_sample >> 2;
+ if (nibble & 0x08)
+ sample += lookup_sample >> 3;
+ if (nibble & 0x04)
+ sample += lookup_sample >> 4;
+ if (nibble & 0x02)
+ sample += lookup_sample >> 5;
+ if (nibble & 0x01)
+ sample += lookup_sample >> 6;
+ if (nibble & 0x80)
+ sample = -sample;
+
+ sample += c->predictor;
+ sample = av_clip_int16(sample);
+
+ index += zork_index_table[(nibble >> 4) & 7];
+ index = av_clip(index, 0, 88);
+
+ c->predictor = sample;
+ c->step_index = index;
+
+ return sample;
+}
+
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)
d = in[16+i+j*4];
t = sign_extend(d, 4);
- s = ( t<<shift ) + ((s_1*f0 + s_2*f1+32)>>6);
+ s = t*(1<<shift) + ((s_1*f0 + s_2*f1+32)>>6);
s_2 = s_1;
s_1 = av_clip_int16(s);
out0[j] = s_1;
d = in[16+i+j*4];
t = sign_extend(d >> 4, 4);
- s = ( t<<shift ) + ((s_1*f0 + s_2*f1+32)>>6);
+ s = t*(1<<shift) + ((s_1*f0 + s_2*f1+32)>>6);
s_2 = s_1;
s_1 = av_clip_int16(s);
out1[j] = s_1;
}
}
+static inline int16_t adpcm_argo_expand_nibble(ADPCMChannelStatus *cs, int nibble, int control, int shift)
+{
+ int sample = nibble * (1 << shift);
+
+ if (control & 0x04)
+ sample += (8 * cs->sample1) - (4 * cs->sample2);
+ else
+ sample += 4 * cs->sample1;
+
+ sample = av_clip_int16(sample >> 2);
+
+ cs->sample2 = cs->sample1;
+ cs->sample1 = sample;
+
+ return sample;
+}
+
/**
* Get the number of samples that will be decoded from the packet.
* In one case, this is actually the maximum number of samples possible to
return 0;
nb_samples = 64;
break;
+ case AV_CODEC_ID_ADPCM_ARGO:
+ if (buf_size < 17 * ch)
+ return 0;
+ nb_samples = 32;
+ break;
/* simple 4-bit adpcm */
case AV_CODEC_ID_ADPCM_CT:
case AV_CODEC_ID_ADPCM_IMA_APC:
case AV_CODEC_ID_ADPCM_IMA_WS:
case AV_CODEC_ID_ADPCM_YAMAHA:
case AV_CODEC_ID_ADPCM_AICA:
+ case AV_CODEC_ID_ADPCM_IMA_SSI:
+ case AV_CODEC_ID_ADPCM_IMA_APM:
nb_samples = buf_size * 2 / ch;
break;
}
case AV_CODEC_ID_ADPCM_PSX:
nb_samples = buf_size / (16 * ch) * 28;
break;
+ case AV_CODEC_ID_ADPCM_ZORK:
+ nb_samples = buf_size / ch;
+ break;
}
/* validate coded sample count */
*samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3);
}
break;
+ case AV_CODEC_ID_ADPCM_IMA_SSI:
+ while (bytestream2_get_bytes_left(&gb) > 0) {
+ int v = bytestream2_get_byteu(&gb);
+ *samples++ = adpcm_ima_qt_expand_nibble(&c->status[0], v >> 4 , 3);
+ *samples++ = adpcm_ima_qt_expand_nibble(&c->status[st], v & 0x0F, 3);
+ }
+ break;
+ case AV_CODEC_ID_ADPCM_IMA_APM:
+ for (n = nb_samples / 2; n > 0; n--) {
+ for (channel = 0; channel < avctx->channels; channel++) {
+ int v = bytestream2_get_byteu(&gb);
+ *samples++ = adpcm_ima_qt_expand_nibble(&c->status[channel], v >> 4 , 3);
+ samples[st] = adpcm_ima_qt_expand_nibble(&c->status[channel], v & 0x0F, 3);
+ }
+ samples += avctx->channels;
+ }
+ break;
case AV_CODEC_ID_ADPCM_IMA_OKI:
while (bytestream2_get_bytes_left(&gb) > 0) {
int v = bytestream2_get_byteu(&gb);
return AVERROR_INVALIDDATA;
}
}
- for (i=0; i<=st; i++)
+ for (i=0; i<=st; i++) {
c->status[i].predictor = bytestream2_get_le32u(&gb);
+ if (FFABS((int64_t)c->status[i].predictor) > (1<<16))
+ return AVERROR_INVALIDDATA;
+ }
for (n = nb_samples >> (1 - st); n > 0; n--) {
int byte = bytestream2_get_byteu(&gb);
for (count2 = 0; count2 < 28; count2++) {
byte = bytestream2_get_byteu(&gb);
- next_left_sample = sign_extend(byte >> 4, 4) << shift_left;
- next_right_sample = sign_extend(byte, 4) << shift_right;
+ next_left_sample = sign_extend(byte >> 4, 4) * (1 << shift_left);
+ next_right_sample = sign_extend(byte, 4) * (1 << shift_right);
next_left_sample = (next_left_sample +
(current_left_sample * coeff1l) +
if (st) byte[1] = bytestream2_get_byteu(&gb);
for(i = 4; i >= 0; i-=4) { /* Pairwise samples LL RR (st) or LL LL (mono) */
for(channel = 0; channel < avctx->channels; channel++) {
- int sample = sign_extend(byte[channel] >> i, 4) << shift[channel];
+ int sample = sign_extend(byte[channel] >> i, 4) * (1 << shift[channel]);
sample = (sample +
c->status[channel].sample1 * coeff[channel][0] +
c->status[channel].sample2 * coeff[channel][1] + 0x80) >> 8;
for (count2=0; count2<28; count2++) {
if (count2 & 1)
- next_sample = sign_extend(byte, 4) << shift;
+ next_sample = (unsigned)sign_extend(byte, 4) << shift;
else {
byte = bytestream2_get_byte(&gb);
- next_sample = sign_extend(byte >> 4, 4) << shift;
+ next_sample = (unsigned)sign_extend(byte >> 4, 4) << shift;
}
next_sample += (current_sample * coeff1) +
int level, pred;
int byte = bytestream2_get_byteu(&gb);
- level = sign_extend(byte >> 4, 4) << shift[n];
+ level = sign_extend(byte >> 4, 4) * (1 << shift[n]);
pred = s[-1] * coeff[0][n] + s[-2] * coeff[1][n];
s[0] = av_clip_int16((level + pred + 0x80) >> 8);
- level = sign_extend(byte, 4) << shift[n];
+ level = sign_extend(byte, 4) * (1 << shift[n]);
pred = s[0] * coeff[0][n] + s[-1] * coeff[1][n];
s[1] = av_clip_int16((level + pred + 0x80) >> 8);
}
sampledat = sign_extend(byte >> 4, 4);
}
- sampledat = ((prev1 * factor1 + prev2 * factor2) +
- ((sampledat * scale) << 11)) >> 11;
+ sampledat = ((prev1 * factor1 + prev2 * factor2) >> 11) +
+ sampledat * scale;
*samples = av_clip_int16(sampledat);
prev2 = prev1;
prev1 = *samples++;
}
sampledat = ((c->status[ch].sample1 * factor1
- + c->status[ch].sample2 * factor2) >> 11) + (sampledat << exp);
+ + c->status[ch].sample2 * factor2) >> 11) + sampledat * (1 << exp);
*samples = av_clip_int16(sampledat);
c->status[ch].sample2 = c->status[ch].sample1;
c->status[ch].sample1 = *samples++;
else
sampledat = sign_extend(byte >> 4, 4);
- sampledat = (((sampledat << 12) >> (header & 0xf)) << 6) + prev;
+ sampledat = ((sampledat * (1 << 12)) >> (header & 0xf)) * (1 << 6) + prev;
*samples++ = av_clip_int16(sampledat >> 6);
c->status[channel].sample2 = c->status[channel].sample1;
c->status[channel].sample1 = sampledat;
}
}
break;
+ case AV_CODEC_ID_ADPCM_ARGO:
+ /*
+ * The format of each block:
+ * uint8_t left_control;
+ * uint4_t left_samples[nb_samples];
+ * ---- and if stereo ----
+ * uint8_t right_control;
+ * uint4_t right_samples[nb_samples];
+ *
+ * Format of the control byte:
+ * MSB [SSSSDRRR] LSB
+ * S = (Shift Amount - 2)
+ * D = Decoder flag.
+ * R = Reserved
+ *
+ * Each block relies on the previous two samples of each channel.
+ * They should be 0 initially.
+ */
+ for (channel = 0; channel < avctx->channels; channel++) {
+ int control, shift;
+
+ samples = samples_p[channel];
+ cs = c->status + channel;
+ /* Get the control byte and decode the samples, 2 at a time. */
+ control = bytestream2_get_byteu(&gb);
+ shift = (control >> 4) + 2;
+
+ for (n = 0; n < nb_samples / 2; n++) {
+ int sample = bytestream2_get_byteu(&gb);
+ *samples++ = adpcm_argo_expand_nibble(cs, sign_extend(sample >> 4, 4), control, shift);
+ *samples++ = adpcm_argo_expand_nibble(cs, sign_extend(sample >> 0, 4), control, shift);
+ }
+ }
+ break;
+ case AV_CODEC_ID_ADPCM_ZORK:
+ if (!c->has_status) {
+ for (channel = 0; channel < avctx->channels; channel++) {
+ c->status[channel].predictor = 0;
+ c->status[channel].step_index = 0;
+ }
+ c->has_status = 1;
+ }
+ for (n = 0; n < nb_samples * avctx->channels; n++) {
+ int v = bytestream2_get_byteu(&gb);
+ *samples++ = adpcm_zork_expand_nibble(&c->status[n % avctx->channels], v);
+ }
+ break;
default:
av_assert0(0); // unsupported codec_id should not happen
}
ADPCM_DECODER(AV_CODEC_ID_ADPCM_AFC, sample_fmts_s16p, adpcm_afc, "ADPCM Nintendo Gamecube AFC");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_AGM, sample_fmts_s16, adpcm_agm, "ADPCM AmuseGraphics Movie");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_AICA, sample_fmts_s16p, adpcm_aica, "ADPCM Yamaha AICA");
+ADPCM_DECODER(AV_CODEC_ID_ADPCM_ARGO, sample_fmts_s16p, adpcm_argo, "ADPCM Argonaut Games");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_CT, sample_fmts_s16, adpcm_ct, "ADPCM Creative Technology");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_DTK, sample_fmts_s16p, adpcm_dtk, "ADPCM Nintendo Gamecube DTK");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA, sample_fmts_s16, adpcm_ea, "ADPCM Electronic Arts");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_XAS, sample_fmts_s16p, adpcm_ea_xas, "ADPCM Electronic Arts XAS");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_AMV, sample_fmts_s16, adpcm_ima_amv, "ADPCM IMA AMV");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_APC, sample_fmts_s16, adpcm_ima_apc, "ADPCM IMA CRYO APC");
+ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_APM, sample_fmts_s16, adpcm_ima_apm, "ADPCM IMA Ubisoft APM");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_DAT4, sample_fmts_s16, adpcm_ima_dat4, "ADPCM IMA Eurocom DAT4");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_DK3, sample_fmts_s16, adpcm_ima_dk3, "ADPCM IMA Duck DK3");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_DK4, sample_fmts_s16, adpcm_ima_dk4, "ADPCM IMA Duck DK4");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_OKI, sample_fmts_s16, adpcm_ima_oki, "ADPCM IMA Dialogic OKI");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_QT, sample_fmts_s16p, adpcm_ima_qt, "ADPCM IMA QuickTime");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_RAD, sample_fmts_s16, adpcm_ima_rad, "ADPCM IMA Radical");
+ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_SSI, sample_fmts_s16, adpcm_ima_ssi, "ADPCM IMA Simon & Schuster Interactive");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_SMJPEG, sample_fmts_s16, adpcm_ima_smjpeg, "ADPCM IMA Loki SDL MJPEG");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WAV, sample_fmts_s16p, adpcm_ima_wav, "ADPCM IMA WAV");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WS, sample_fmts_both, adpcm_ima_ws, "ADPCM IMA Westwood");
ADPCM_DECODER(AV_CODEC_ID_ADPCM_THP, sample_fmts_s16p, adpcm_thp, "ADPCM Nintendo THP");
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");
+ADPCM_DECODER(AV_CODEC_ID_ADPCM_ZORK, sample_fmts_s16, adpcm_zork, "ADPCM Zork");