00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/channel_layout.h"
00023 #include "avcodec.h"
00024 #include "get_bits.h"
00025 #include "internal.h"
00026 #include "adpcm_data.h"
00027
00028 typedef struct {
00029 AVFrame frame;
00030 uint16_t predict_table[5786 * 2];
00031 } VimaContext;
00032
00033 static const uint8_t size_table[] =
00034 {
00035 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
00036 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
00037 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
00038 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
00039 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
00040 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
00041 };
00042
00043 static const int8_t index_table1[] =
00044 {
00045 -1, 4, -1, 4
00046 };
00047
00048 static const int8_t index_table2[] =
00049 {
00050 -1, -1, 2, 6, -1, -1, 2, 6
00051 };
00052
00053 static const int8_t index_table3[] =
00054 {
00055 -1, -1, -1, -1, 1, 2, 4, 6,
00056 -1, -1, -1, -1, 1, 2, 4, 6
00057 };
00058
00059 static const int8_t index_table4[] =
00060 {
00061 -1, -1, -1, -1, -1, -1, -1, -1,
00062 1, 1, 1, 2, 2, 4, 5, 6,
00063 -1, -1, -1, -1, -1, -1, -1, -1,
00064 1, 1, 1, 2, 2, 4, 5, 6
00065 };
00066
00067 static const int8_t index_table5[] =
00068 {
00069 -1, -1, -1, -1, -1, -1, -1, -1,
00070 -1, -1, -1, -1, -1, -1, -1, -1,
00071 1, 1, 1, 1, 1, 2, 2, 2,
00072 2, 4, 4, 4, 5, 5, 6, 6,
00073 -1, -1, -1, -1, -1, -1, -1, -1,
00074 -1, -1, -1, -1, -1, -1, -1, -1,
00075 1, 1, 1, 1, 1, 2, 2, 2,
00076 2, 4, 4, 4, 5, 5, 6, 6
00077 };
00078
00079 static const int8_t index_table6[] =
00080 {
00081 -1, -1, -1, -1, -1, -1, -1, -1,
00082 -1, -1, -1, -1, -1, -1, -1, -1,
00083 -1, -1, -1, -1, -1, -1, -1, -1,
00084 -1, -1, -1, -1, -1, -1, -1, -1,
00085 1, 1, 1, 1, 1, 1, 1, 1,
00086 1, 1, 2, 2, 2, 2, 2, 2,
00087 2, 2, 4, 4, 4, 4, 4, 4,
00088 5, 5, 5, 5, 6, 6, 6, 6,
00089 -1, -1, -1, -1, -1, -1, -1, -1,
00090 -1, -1, -1, -1, -1, -1, -1, -1,
00091 -1, -1, -1, -1, -1, -1, -1, -1,
00092 -1, -1, -1, -1, -1, -1, -1, -1,
00093 1, 1, 1, 1, 1, 1, 1, 1,
00094 1, 1, 2, 2, 2, 2, 2, 2,
00095 2, 2, 4, 4, 4, 4, 4, 4,
00096 5, 5, 5, 5, 6, 6, 6, 6
00097 };
00098
00099 static const int8_t* const step_index_tables[] =
00100 {
00101 index_table1, index_table2, index_table3,
00102 index_table4, index_table5, index_table6
00103 };
00104
00105 static av_cold int decode_init(AVCodecContext *avctx)
00106 {
00107 VimaContext *vima = avctx->priv_data;
00108 int start_pos;
00109
00110 for (start_pos = 0; start_pos < 64; start_pos++) {
00111 unsigned int dest_pos, table_pos;
00112
00113 for (table_pos = 0, dest_pos = start_pos;
00114 table_pos < FF_ARRAY_ELEMS(ff_adpcm_step_table);
00115 table_pos++, dest_pos += 64) {
00116 int put = 0, count, table_value;
00117
00118 table_value = ff_adpcm_step_table[table_pos];
00119 for (count = 32; count != 0; count >>= 1) {
00120 if (start_pos & count)
00121 put += table_value;
00122 table_value >>= 1;
00123 }
00124 vima->predict_table[dest_pos] = put;
00125 }
00126 }
00127
00128 avcodec_get_frame_defaults(&vima->frame);
00129 avctx->coded_frame = &vima->frame;
00130 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
00131
00132 return 0;
00133 }
00134
00135 static int decode_frame(AVCodecContext *avctx, void *data,
00136 int *got_frame_ptr, AVPacket *pkt)
00137 {
00138 GetBitContext gb;
00139 VimaContext *vima = avctx->priv_data;
00140 int16_t pcm_data[2];
00141 uint32_t samples;
00142 int8_t channel_hint[2];
00143 int ret, chan, channels = 1;
00144
00145 if (pkt->size < 13)
00146 return AVERROR_INVALIDDATA;
00147
00148 init_get_bits(&gb, pkt->data, pkt->size * 8);
00149
00150 samples = get_bits_long(&gb, 32);
00151 if (samples == 0xffffffff) {
00152 skip_bits_long(&gb, 32);
00153 samples = get_bits_long(&gb, 32);
00154 }
00155
00156 if (samples > pkt->size * 2)
00157 return AVERROR_INVALIDDATA;
00158
00159 channel_hint[0] = get_sbits(&gb, 8);
00160 if (channel_hint[0] & 0x80) {
00161 channel_hint[0] = ~channel_hint[0];
00162 channels = 2;
00163 }
00164 avctx->channels = channels;
00165 avctx->channel_layout = (channels == 2) ? AV_CH_LAYOUT_STEREO :
00166 AV_CH_LAYOUT_MONO;
00167 pcm_data[0] = get_sbits(&gb, 16);
00168 if (channels > 1) {
00169 channel_hint[1] = get_sbits(&gb, 8);
00170 pcm_data[1] = get_sbits(&gb, 16);
00171 }
00172
00173 vima->frame.nb_samples = samples;
00174 if ((ret = ff_get_buffer(avctx, &vima->frame)) < 0) {
00175 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00176 return ret;
00177 }
00178
00179 for (chan = 0; chan < channels; chan++) {
00180 uint16_t *dest = (uint16_t*)vima->frame.data[0] + chan;
00181 int step_index = channel_hint[chan];
00182 int output = pcm_data[chan];
00183 int sample;
00184
00185 for (sample = 0; sample < samples; sample++) {
00186 int lookup_size, lookup, highbit, lowbits;
00187
00188 step_index = av_clip(step_index, 0, 88);
00189 lookup_size = size_table[step_index];
00190 lookup = get_bits(&gb, lookup_size);
00191 highbit = 1 << (lookup_size - 1);
00192 lowbits = highbit - 1;
00193
00194 if (lookup & highbit)
00195 lookup ^= highbit;
00196 else
00197 highbit = 0;
00198
00199 if (lookup == lowbits) {
00200 output = get_sbits(&gb, 16);
00201 } else {
00202 int predict_index, diff;
00203
00204 predict_index = (lookup << (7 - lookup_size)) | (step_index << 6);
00205 predict_index = av_clip(predict_index, 0, 5785);
00206 diff = vima->predict_table[predict_index];
00207 if (lookup)
00208 diff += ff_adpcm_step_table[step_index] >> (lookup_size - 1);
00209 if (highbit)
00210 diff = -diff;
00211
00212 output = av_clip_int16(output + diff);
00213 }
00214
00215 *dest = output;
00216 dest += channels;
00217
00218 step_index += step_index_tables[lookup_size - 2][lookup];
00219 }
00220 }
00221
00222 *got_frame_ptr = 1;
00223 *(AVFrame *)data = vima->frame;
00224
00225 return pkt->size;
00226 }
00227
00228 AVCodec ff_vima_decoder = {
00229 .name = "vima",
00230 .type = AVMEDIA_TYPE_AUDIO,
00231 .id = AV_CODEC_ID_VIMA,
00232 .priv_data_size = sizeof(VimaContext),
00233 .init = decode_init,
00234 .decode = decode_frame,
00235 .capabilities = CODEC_CAP_DR1,
00236 .long_name = NULL_IF_CONFIG_SMALL("LucasArts VIMA audio"),
00237 };