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 }; |
