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