📄 adpcm.c
字号:
}
break;
case CODEC_ID_ADPCM_IMA_WS:
/* no per-block initialization; just start decoding the data */
while (src < buf + buf_size) {
if (st) {
*samples++ = adpcm_ima_expand_nibble(&c->status[0],
(src[0] >> 4) & 0x0F, 3);
*samples++ = adpcm_ima_expand_nibble(&c->status[1],
src[0] & 0x0F, 3);
} else {
*samples++ = adpcm_ima_expand_nibble(&c->status[0],
(src[0] >> 4) & 0x0F, 3);
*samples++ = adpcm_ima_expand_nibble(&c->status[0],
src[0] & 0x0F, 3);
}
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;
case CODEC_ID_ADPCM_EA:
samples_in_chunk = AV_RL32(src);
if (samples_in_chunk >= ((buf_size - 12) * 2)) {
src += buf_size;
break;
}
src += 4;
current_left_sample = (int16_t)AV_RL16(src);
src += 2;
previous_left_sample = (int16_t)AV_RL16(src);
src += 2;
current_right_sample = (int16_t)AV_RL16(src);
src += 2;
previous_right_sample = (int16_t)AV_RL16(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;
previous_left_sample = current_left_sample;
current_left_sample = av_clip_int16(next_left_sample);
previous_right_sample = current_right_sample;
current_right_sample = av_clip_int16(next_right_sample);
*samples++ = (unsigned short)current_left_sample;
*samples++ = (unsigned short)current_right_sample;
}
}
break;
case CODEC_ID_ADPCM_IMA_AMV:
case CODEC_ID_ADPCM_IMA_SMJPEG:
c->status[0].predictor = (int16_t)bytestream_get_le16(&src);
c->status[0].step_index = bytestream_get_le16(&src);
if (avctx->codec->id == CODEC_ID_ADPCM_IMA_AMV)
src+=4;
while (src < buf + buf_size) {
char hi, lo;
lo = *src & 0x0F;
hi = (*src >> 4) & 0x0F;
if (avctx->codec->id == CODEC_ID_ADPCM_IMA_AMV)
FFSWAP(char, hi, lo);
*samples++ = adpcm_ima_expand_nibble(&c->status[0],
lo, 3);
*samples++ = adpcm_ima_expand_nibble(&c->status[0],
hi, 3);
src++;
}
break;
case CODEC_ID_ADPCM_CT:
while (src < buf + buf_size) {
if (st) {
*samples++ = adpcm_ct_expand_nibble(&c->status[0],
(src[0] >> 4) & 0x0F);
*samples++ = adpcm_ct_expand_nibble(&c->status[1],
src[0] & 0x0F);
} else {
*samples++ = adpcm_ct_expand_nibble(&c->status[0],
(src[0] >> 4) & 0x0F);
*samples++ = adpcm_ct_expand_nibble(&c->status[0],
src[0] & 0x0F);
}
src++;
}
break;
case CODEC_ID_ADPCM_SBPRO_4:
case CODEC_ID_ADPCM_SBPRO_3:
case CODEC_ID_ADPCM_SBPRO_2:
if (!c->status[0].step_index) {
/* the first byte is a raw sample */
*samples++ = 128 * (*src++ - 0x80);
if (st)
*samples++ = 128 * (*src++ - 0x80);
c->status[0].step_index = 1;
}
if (avctx->codec->id == CODEC_ID_ADPCM_SBPRO_4) {
while (src < buf + buf_size) {
*samples++ = adpcm_sbpro_expand_nibble(&c->status[0],
(src[0] >> 4) & 0x0F, 4, 0);
*samples++ = adpcm_sbpro_expand_nibble(&c->status[st],
src[0] & 0x0F, 4, 0);
src++;
}
} else if (avctx->codec->id == CODEC_ID_ADPCM_SBPRO_3) {
while (src < buf + buf_size && samples + 2 < samples_end) {
*samples++ = adpcm_sbpro_expand_nibble(&c->status[0],
(src[0] >> 5) & 0x07, 3, 0);
*samples++ = adpcm_sbpro_expand_nibble(&c->status[0],
(src[0] >> 2) & 0x07, 3, 0);
*samples++ = adpcm_sbpro_expand_nibble(&c->status[0],
src[0] & 0x03, 2, 0);
src++;
}
} else {
while (src < buf + buf_size && samples + 3 < samples_end) {
*samples++ = adpcm_sbpro_expand_nibble(&c->status[0],
(src[0] >> 6) & 0x03, 2, 2);
*samples++ = adpcm_sbpro_expand_nibble(&c->status[st],
(src[0] >> 4) & 0x03, 2, 2);
*samples++ = adpcm_sbpro_expand_nibble(&c->status[0],
(src[0] >> 2) & 0x03, 2, 2);
*samples++ = adpcm_sbpro_expand_nibble(&c->status[st],
src[0] & 0x03, 2, 2);
src++;
}
}
break;
case CODEC_ID_ADPCM_SWF:
{
GetBitContext gb;
const int *table;
int k0, signmask, nb_bits, count;
int size = buf_size*8;
init_get_bits(&gb, buf, size);
//read bits & initial values
nb_bits = get_bits(&gb, 2)+2;
//av_log(NULL,AV_LOG_INFO,"nb_bits: %d\n", nb_bits);
table = swf_index_tables[nb_bits-2];
k0 = 1 << (nb_bits-2);
signmask = 1 << (nb_bits-1);
while (get_bits_count(&gb) <= size - 22*avctx->channels) {
for (i = 0; i < avctx->channels; i++) {
*samples++ = c->status[i].predictor = get_sbits(&gb, 16);
c->status[i].step_index = get_bits(&gb, 6);
}
for (count = 0; get_bits_count(&gb) <= size - nb_bits*avctx->channels && count < 4095; count++) {
int i;
for (i = 0; i < avctx->channels; i++) {
// similar to IMA adpcm
int delta = get_bits(&gb, nb_bits);
int step = step_table[c->status[i].step_index];
long vpdiff = 0; // vpdiff = (delta+0.5)*step/4
int k = k0;
do {
if (delta & k)
vpdiff += step;
step >>= 1;
k >>= 1;
} while(k);
vpdiff += step;
if (delta & signmask)
c->status[i].predictor -= vpdiff;
else
c->status[i].predictor += vpdiff;
c->status[i].step_index += table[delta & (~signmask)];
c->status[i].step_index = av_clip(c->status[i].step_index, 0, 88);
c->status[i].predictor = av_clip_int16(c->status[i].predictor);
*samples++ = c->status[i].predictor;
if (samples >= samples_end) {
av_log(avctx, AV_LOG_ERROR, "allocated output buffer is too small\n");
return -1;
}
}
}
}
src += buf_size;
break;
}
case CODEC_ID_ADPCM_YAMAHA:
while (src < buf + buf_size) {
if (st) {
*samples++ = adpcm_yamaha_expand_nibble(&c->status[0],
src[0] & 0x0F);
*samples++ = adpcm_yamaha_expand_nibble(&c->status[1],
(src[0] >> 4) & 0x0F);
} else {
*samples++ = adpcm_yamaha_expand_nibble(&c->status[0],
src[0] & 0x0F);
*samples++ = adpcm_yamaha_expand_nibble(&c->status[0],
(src[0] >> 4) & 0x0F);
}
src++;
}
break;
case CODEC_ID_ADPCM_THP:
{
int table[2][16];
unsigned int samplecnt;
int prev[2][2];
int ch;
if (buf_size < 80) {
av_log(avctx, AV_LOG_ERROR, "frame too small\n");
return -1;
}
src+=4;
samplecnt = bytestream_get_be32(&src);
for (i = 0; i < 32; i++)
table[0][i] = (int16_t)bytestream_get_be16(&src);
/* Initialize the previous sample. */
for (i = 0; i < 4; i++)
prev[0][i] = (int16_t)bytestream_get_be16(&src);
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++) {
int index = (*src >> 4) & 7;
unsigned int exp = 28 - (*src++ & 15);
int factor1 = table[ch][index * 2];
int factor2 = table[ch][index * 2 + 1];
/* Decode 14 samples. */
for (n = 0; n < 14; n++) {
int32_t sampledat;
if(n&1) sampledat= *src++ <<28;
else sampledat= (*src&0xF0)<<24;
sampledat = ((prev[ch][0]*factor1
+ prev[ch][1]*factor2) >> 11) + (sampledat>>exp);
*samples = av_clip_int16(sampledat);
prev[ch][1] = prev[ch][0];
prev[ch][0] = *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;
}
*data_size = (uint8_t *)samples - (uint8_t *)data;
return src - buf;
}
#ifdef CONFIG_ENCODERS
#define ADPCM_ENCODER(id,name) \
AVCodec name ## _encoder = { \
#name, \
CODEC_TYPE_AUDIO, \
id, \
sizeof(ADPCMContext), \
adpcm_encode_init, \
adpcm_encode_frame, \
adpcm_encode_close, \
NULL, \
};
#else
#define ADPCM_ENCODER(id,name)
#endif
#ifdef CONFIG_DECODERS
#define ADPCM_DECODER(id,name) \
AVCodec name ## _decoder = { \
#name, \
CODEC_TYPE_AUDIO, \
id, \
sizeof(ADPCMContext), \
adpcm_decode_init, \
NULL, \
NULL, \
adpcm_decode_frame, \
};
#else
#define ADPCM_DECODER(id,name)
#endif
#define ADPCM_CODEC(id, name) \
ADPCM_ENCODER(id,name) ADPCM_DECODER(id,name)
ADPCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm);
ADPCM_CODEC(CODEC_ID_ADPCM_CT, adpcm_ct);
ADPCM_CODEC(CODEC_ID_ADPCM_EA, adpcm_ea);
ADPCM_CODEC(CODEC_ID_ADPCM_IMA_AMV, adpcm_ima_amv);
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_QT, adpcm_ima_qt);
ADPCM_CODEC(CODEC_ID_ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg);
ADPCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav);
ADPCM_CODEC(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws);
ADPCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms);
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_SWF, adpcm_swf);
ADPCM_CODEC(CODEC_ID_ADPCM_THP, adpcm_thp);
ADPCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa);
ADPCM_CODEC(CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha);
#undef ADPCM_CODEC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -