Mercurial > libavcodec.hg
comparison dpcm.c @ 1443:47f4c8a5a7fc libavcodec
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
author | tmmm |
---|---|
date | Mon, 08 Sep 2003 04:10:59 +0000 |
parents | a4d00b1f0271 |
children | afc7baa19b62 |
comparison
equal
deleted
inserted
replaced
1442:2a4bd3a11d4a | 1443:47f4c8a5a7fc |
---|---|
19 | 19 |
20 /** | 20 /** |
21 * @file: dpcm.c | 21 * @file: dpcm.c |
22 * Assorted DPCM (differential pulse code modulation) audio codecs | 22 * Assorted DPCM (differential pulse code modulation) audio codecs |
23 * by Mike Melanson (melanson@pcisys.net) | 23 * by Mike Melanson (melanson@pcisys.net) |
24 * Xan DPCM decoder by Mario Brito (mbrito@student.dei.uc.pt) | |
24 * for more information on the specific data formats, visit: | 25 * for more information on the specific data formats, visit: |
25 * http://www.pcisys.net/~melanson/codecs/simpleaudio.html | 26 * http://www.pcisys.net/~melanson/codecs/simpleaudio.html |
27 * | |
28 * Note about using the Xan DPCM decoder: Xan DPCM is used in AVI files | |
29 * found in the Wing Commander IV computer game. These AVI files contain | |
30 * WAVEFORMAT headers which report the audio format as 0x01: raw PCM. | |
31 * Clearly incorrect. To detect Xan DPCM, you will probably have to | |
32 * special-case your AVI demuxer to use Xan DPCM if the file uses 'Xxan' | |
33 * (Xan video) for its video codec. Alternately, such AVI files also contain | |
34 * the fourcc 'Axan' in the 'auds' chunk of the AVI header. | |
26 */ | 35 */ |
27 | 36 |
28 #include "avcodec.h" | 37 #include "avcodec.h" |
29 | 38 |
30 typedef struct DPCMContext { | 39 typedef struct DPCMContext { |
113 int i; | 122 int i; |
114 int predictor[2]; | 123 int predictor[2]; |
115 int channel_number = 0; | 124 int channel_number = 0; |
116 short *output_samples = data; | 125 short *output_samples = data; |
117 int sequence_number; | 126 int sequence_number; |
127 int shift[2]; | |
128 unsigned char byte; | |
129 short diff; | |
118 | 130 |
119 switch(avctx->codec->id) { | 131 switch(avctx->codec->id) { |
120 | 132 |
121 case CODEC_ID_ROQ_DPCM: | 133 case CODEC_ID_ROQ_DPCM: |
122 if (s->channels == 1) | 134 if (s->channels == 1) |
169 /* save predictors for next round */ | 181 /* save predictors for next round */ |
170 for (i = 0; i < s->channels; i++) | 182 for (i = 0; i < s->channels; i++) |
171 s->last_delta[i] = predictor[i]; | 183 s->last_delta[i] = predictor[i]; |
172 | 184 |
173 break; | 185 break; |
186 | |
187 case CODEC_ID_XAN_DPCM: | |
188 in = 0; | |
189 shift[0] = shift[1] = 4; | |
190 predictor[0] = LE_16(&buf[in]); | |
191 in += 2; | |
192 SE_16BIT(predictor[0]); | |
193 if (s->channels == 2) { | |
194 predictor[1] = LE_16(&buf[in]); | |
195 in += 2; | |
196 SE_16BIT(predictor[1]); | |
197 } | |
198 | |
199 while (in < buf_size) { | |
200 byte = buf[in++]; | |
201 diff = (byte & 0xFC) << 8; | |
202 if ((byte & 0x03) == 3) | |
203 shift[channel_number]++; | |
204 else | |
205 shift[channel_number] -= (2 * (byte & 3)); | |
206 /* saturate the shifter to a lower limit of 0 */ | |
207 if (shift[channel_number] < 0) | |
208 shift[channel_number] = 0; | |
209 | |
210 diff >>= shift[channel_number]; | |
211 predictor[channel_number] += diff; | |
212 | |
213 SATURATE_S16(predictor[channel_number]); | |
214 output_samples[out++] = predictor[channel_number]; | |
215 | |
216 /* toggle channel */ | |
217 channel_number ^= s->channels - 1; | |
218 } | |
219 break; | |
174 } | 220 } |
175 | 221 |
176 *data_size = out * sizeof(short); | 222 *data_size = out * sizeof(short); |
177 return buf_size; | 223 return buf_size; |
178 } | 224 } |
196 dpcm_decode_init, | 242 dpcm_decode_init, |
197 NULL, | 243 NULL, |
198 NULL, | 244 NULL, |
199 dpcm_decode_frame, | 245 dpcm_decode_frame, |
200 }; | 246 }; |
247 | |
248 AVCodec xan_dpcm_decoder = { | |
249 "xan_dpcm", | |
250 CODEC_TYPE_AUDIO, | |
251 CODEC_ID_XAN_DPCM, | |
252 sizeof(DPCMContext), | |
253 dpcm_decode_init, | |
254 NULL, | |
255 NULL, | |
256 dpcm_decode_frame, | |
257 }; |