Mercurial > libavcodec.hg
comparison adpcm.c @ 4614:3c6c557aa977 libavcodec
fix adpcm swf decoding
author | bcoudurier |
---|---|
date | Fri, 02 Mar 2007 10:08:05 +0000 |
parents | a96d905dcbaa |
children | d6b2ddac2c5e |
comparison
equal
deleted
inserted
replaced
4613:c1c2e47aa5fe | 4614:3c6c557aa977 |
---|---|
148 | 148 |
149 typedef struct ADPCMContext { | 149 typedef struct ADPCMContext { |
150 int channel; /* for stereo MOVs, decode left, then decode right, then tell it's decoded */ | 150 int channel; /* for stereo MOVs, decode left, then decode right, then tell it's decoded */ |
151 ADPCMChannelStatus status[2]; | 151 ADPCMChannelStatus status[2]; |
152 short sample_buffer[32]; /* hold left samples while waiting for right samples */ | 152 short sample_buffer[32]; /* hold left samples while waiting for right samples */ |
153 | |
154 /* SWF only */ | |
155 int nb_bits; | |
156 int nb_samples; | |
157 } ADPCMContext; | 153 } ADPCMContext; |
158 | 154 |
159 /* XXX: implement encoding */ | 155 /* XXX: implement encoding */ |
160 | 156 |
161 #ifdef CONFIG_ENCODERS | 157 #ifdef CONFIG_ENCODERS |
1238 break; | 1234 break; |
1239 case CODEC_ID_ADPCM_SWF: | 1235 case CODEC_ID_ADPCM_SWF: |
1240 { | 1236 { |
1241 GetBitContext gb; | 1237 GetBitContext gb; |
1242 const int *table; | 1238 const int *table; |
1243 int k0, signmask; | 1239 int k0, signmask, nb_bits; |
1244 int size = buf_size*8; | 1240 int size = buf_size*8; |
1245 | 1241 |
1246 init_get_bits(&gb, buf, size); | 1242 init_get_bits(&gb, buf, size); |
1247 | 1243 |
1248 //FIXME the following return -1 may be removed only after | 1244 //read bits & inital values |
1249 //1. correctly spliting the stream into packets at demuxer or parser level | 1245 nb_bits = get_bits(&gb, 2)+2; |
1250 //2. checking array bounds when writing | 1246 //av_log(NULL,AV_LOG_INFO,"nb_bits: %d\n", nb_bits); |
1251 //3. moving the global nb_bits header into extradata | 1247 table = swf_index_tables[nb_bits-2]; |
1252 return -1; | 1248 k0 = 1 << (nb_bits-2); |
1253 // first frame, read bits & inital values | 1249 signmask = 1 << (nb_bits-1); |
1254 if (!c->nb_bits) | 1250 |
1255 { | 1251 for (i = 0; i < avctx->channels; i++) { |
1256 c->nb_bits = get_bits(&gb, 2)+2; | 1252 *samples++ = c->status[i].predictor = get_sbits(&gb, 16); |
1257 // av_log(NULL,AV_LOG_INFO,"nb_bits: %d\n", c->nb_bits); | 1253 c->status[i].step_index = get_bits(&gb, 6); |
1258 } | 1254 } |
1259 | 1255 |
1260 table = swf_index_tables[c->nb_bits-2]; | 1256 while (get_bits_count(&gb) < size) |
1261 k0 = 1 << (c->nb_bits-2); | |
1262 signmask = 1 << (c->nb_bits-1); | |
1263 | |
1264 while (get_bits_count(&gb) <= size) | |
1265 { | 1257 { |
1266 int i; | 1258 int i; |
1267 | 1259 |
1268 c->nb_samples++; | 1260 for (i = 0; i < avctx->channels; i++) { |
1269 // wrap around at every 4096 samples... | 1261 // similar to IMA adpcm |
1270 if ((c->nb_samples & 0xfff) == 1) | 1262 int delta = get_bits(&gb, nb_bits); |
1271 { | |
1272 for (i = 0; i <= st; i++) | |
1273 { | |
1274 *samples++ = c->status[i].predictor = get_sbits(&gb, 16); | |
1275 c->status[i].step_index = get_bits(&gb, 6); | |
1276 } | |
1277 } | |
1278 | |
1279 // similar to IMA adpcm | |
1280 for (i = 0; i <= st; i++) | |
1281 { | |
1282 int delta = get_bits(&gb, c->nb_bits); | |
1283 int step = step_table[c->status[i].step_index]; | 1263 int step = step_table[c->status[i].step_index]; |
1284 long vpdiff = 0; // vpdiff = (delta+0.5)*step/4 | 1264 long vpdiff = 0; // vpdiff = (delta+0.5)*step/4 |
1285 int k = k0; | 1265 int k = k0; |
1286 | 1266 |
1287 do { | 1267 do { |
1301 | 1281 |
1302 c->status[i].step_index = av_clip(c->status[i].step_index, 0, 88); | 1282 c->status[i].step_index = av_clip(c->status[i].step_index, 0, 88); |
1303 c->status[i].predictor = av_clip(c->status[i].predictor, -32768, 32767); | 1283 c->status[i].predictor = av_clip(c->status[i].predictor, -32768, 32767); |
1304 | 1284 |
1305 *samples++ = c->status[i].predictor; | 1285 *samples++ = c->status[i].predictor; |
1306 } | 1286 if (samples >= samples_end) { |
1307 } | 1287 av_log(avctx, AV_LOG_ERROR, "allocated output buffer is too small\n"); |
1308 | 1288 return -1; |
1309 // src += get_bits_count(&gb)*8; | 1289 } |
1310 src += size; | 1290 } |
1311 | 1291 } |
1292 src += buf_size; | |
1312 break; | 1293 break; |
1313 } | 1294 } |
1314 case CODEC_ID_ADPCM_YAMAHA: | 1295 case CODEC_ID_ADPCM_YAMAHA: |
1315 while (src < buf + buf_size) { | 1296 while (src < buf + buf_size) { |
1316 if (st) { | 1297 if (st) { |