00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/intreadwrite.h"
00023 #include "avcodec.h"
00024 #include "adx.h"
00025 #include "get_bits.h"
00026
00036 static av_cold int adx_decode_init(AVCodecContext *avctx)
00037 {
00038 ADXContext *c = avctx->priv_data;
00039 int ret, header_size;
00040
00041 if (avctx->extradata_size >= 24) {
00042 if ((ret = avpriv_adx_decode_header(avctx, avctx->extradata,
00043 avctx->extradata_size, &header_size,
00044 c->coeff)) < 0) {
00045 av_log(avctx, AV_LOG_ERROR, "error parsing ADX header\n");
00046 return AVERROR_INVALIDDATA;
00047 }
00048 c->channels = avctx->channels;
00049 c->header_parsed = 1;
00050 }
00051
00052 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
00053
00054 avcodec_get_frame_defaults(&c->frame);
00055 avctx->coded_frame = &c->frame;
00056
00057 return 0;
00058 }
00059
00067 static int adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch)
00068 {
00069 ADXChannelState *prev = &c->prev[ch];
00070 GetBitContext gb;
00071 int scale = AV_RB16(in);
00072 int i;
00073 int s0, s1, s2, d;
00074
00075
00076 if (scale & 0x8000)
00077 return -1;
00078
00079 init_get_bits(&gb, in + 2, (BLOCK_SIZE - 2) * 8);
00080 s1 = prev->s1;
00081 s2 = prev->s2;
00082 for (i = 0; i < BLOCK_SAMPLES; i++) {
00083 d = get_sbits(&gb, 4);
00084 s0 = ((d << COEFF_BITS) * scale + c->coeff[0] * s1 + c->coeff[1] * s2) >> COEFF_BITS;
00085 s2 = s1;
00086 s1 = av_clip_int16(s0);
00087 *out = s1;
00088 out += c->channels;
00089 }
00090 prev->s1 = s1;
00091 prev->s2 = s2;
00092
00093 return 0;
00094 }
00095
00096 static int adx_decode_frame(AVCodecContext *avctx, void *data,
00097 int *got_frame_ptr, AVPacket *avpkt)
00098 {
00099 int buf_size = avpkt->size;
00100 ADXContext *c = avctx->priv_data;
00101 int16_t *samples;
00102 const uint8_t *buf = avpkt->data;
00103 int num_blocks, ch, ret;
00104
00105 if (c->eof) {
00106 *got_frame_ptr = 0;
00107 return buf_size;
00108 }
00109
00110 if (!c->header_parsed && buf_size >= 2 && AV_RB16(buf) == 0x8000) {
00111 int header_size;
00112 if ((ret = avpriv_adx_decode_header(avctx, buf, buf_size, &header_size,
00113 c->coeff)) < 0) {
00114 av_log(avctx, AV_LOG_ERROR, "error parsing ADX header\n");
00115 return AVERROR_INVALIDDATA;
00116 }
00117 c->channels = avctx->channels;
00118 c->header_parsed = 1;
00119 if (buf_size < header_size)
00120 return AVERROR_INVALIDDATA;
00121 buf += header_size;
00122 buf_size -= header_size;
00123 }
00124 if (!c->header_parsed)
00125 return AVERROR_INVALIDDATA;
00126
00127
00128 num_blocks = buf_size / (BLOCK_SIZE * c->channels);
00129
00130
00131
00132 if (!num_blocks || buf_size % (BLOCK_SIZE * avctx->channels)) {
00133 if (buf_size >= 4 && (AV_RB16(buf) & 0x8000)) {
00134 c->eof = 1;
00135 *got_frame_ptr = 0;
00136 return avpkt->size;
00137 }
00138 return AVERROR_INVALIDDATA;
00139 }
00140
00141
00142 c->frame.nb_samples = num_blocks * BLOCK_SAMPLES;
00143 if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) {
00144 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00145 return ret;
00146 }
00147 samples = (int16_t *)c->frame.data[0];
00148
00149 while (num_blocks--) {
00150 for (ch = 0; ch < c->channels; ch++) {
00151 if (adx_decode(c, samples + ch, buf, ch)) {
00152 c->eof = 1;
00153 buf = avpkt->data + avpkt->size;
00154 break;
00155 }
00156 buf_size -= BLOCK_SIZE;
00157 buf += BLOCK_SIZE;
00158 }
00159 samples += BLOCK_SAMPLES * c->channels;
00160 }
00161
00162 *got_frame_ptr = 1;
00163 *(AVFrame *)data = c->frame;
00164
00165 return buf - avpkt->data;
00166 }
00167
00168 static void adx_decode_flush(AVCodecContext *avctx)
00169 {
00170 ADXContext *c = avctx->priv_data;
00171 memset(c->prev, 0, sizeof(c->prev));
00172 c->eof = 0;
00173 }
00174
00175 AVCodec ff_adpcm_adx_decoder = {
00176 .name = "adpcm_adx",
00177 .type = AVMEDIA_TYPE_AUDIO,
00178 .id = CODEC_ID_ADPCM_ADX,
00179 .priv_data_size = sizeof(ADXContext),
00180 .init = adx_decode_init,
00181 .decode = adx_decode_frame,
00182 .flush = adx_decode_flush,
00183 .capabilities = CODEC_CAP_DR1,
00184 .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
00185 };