Mercurial > libavcodec.hg
comparison dpcm.c @ 1477:afc7baa19b62 libavcodec
fix Interplay DPCM (frames are intracoded, predictors do not carry
forward to next block, initial predictors go to the output)
author | tmmm |
---|---|
date | Fri, 19 Sep 2003 04:41:02 +0000 |
parents | 47f4c8a5a7fc |
children | 19ee8ddea820 |
comparison
equal
deleted
inserted
replaced
1476:72e115e94673 | 1477:afc7baa19b62 |
---|---|
37 #include "avcodec.h" | 37 #include "avcodec.h" |
38 | 38 |
39 typedef struct DPCMContext { | 39 typedef struct DPCMContext { |
40 int channels; | 40 int channels; |
41 short roq_square_array[256]; | 41 short roq_square_array[256]; |
42 int last_delta[2]; | |
43 } DPCMContext; | 42 } DPCMContext; |
44 | 43 |
45 #define SATURATE_S16(x) if (x < -32768) x = -32768; \ | 44 #define SATURATE_S16(x) if (x < -32768) x = -32768; \ |
46 else if (x > 32767) x = 32767; | 45 else if (x > 32767) x = 32767; |
47 #define SE_16BIT(x) if (x & 0x8000) x -= 0x10000; | 46 #define SE_16BIT(x) if (x & 0x8000) x -= 0x10000; |
117 void *data, int *data_size, | 116 void *data, int *data_size, |
118 uint8_t *buf, int buf_size) | 117 uint8_t *buf, int buf_size) |
119 { | 118 { |
120 DPCMContext *s = avctx->priv_data; | 119 DPCMContext *s = avctx->priv_data; |
121 int in, out = 0; | 120 int in, out = 0; |
122 int i; | |
123 int predictor[2]; | 121 int predictor[2]; |
124 int channel_number = 0; | 122 int channel_number = 0; |
125 short *output_samples = data; | 123 short *output_samples = data; |
126 int sequence_number; | |
127 int shift[2]; | 124 int shift[2]; |
128 unsigned char byte; | 125 unsigned char byte; |
129 short diff; | 126 short diff; |
130 | 127 |
131 switch(avctx->codec->id) { | 128 switch(avctx->codec->id) { |
150 channel_number ^= s->channels - 1; | 147 channel_number ^= s->channels - 1; |
151 } | 148 } |
152 break; | 149 break; |
153 | 150 |
154 case CODEC_ID_INTERPLAY_DPCM: | 151 case CODEC_ID_INTERPLAY_DPCM: |
155 in = 0; | 152 in = 6; /* skip over the stream mask and stream length */ |
156 sequence_number = LE_16(&buf[in]); | 153 predictor[0] = LE_16(&buf[in]); |
157 in += 6; /* skip over the stream mask and stream length */ | 154 in += 2; |
158 if (sequence_number == 1) { | 155 SE_16BIT(predictor[0]) |
159 predictor[0] = LE_16(&buf[in]); | 156 output_samples[out++] = predictor[0]; |
157 if (s->channels == 2) { | |
158 predictor[1] = LE_16(&buf[in]); | |
160 in += 2; | 159 in += 2; |
161 SE_16BIT(predictor[0]) | 160 SE_16BIT(predictor[1]) |
162 if (s->channels == 2) { | 161 output_samples[out++] = predictor[1]; |
163 predictor[1] = LE_16(&buf[in]); | |
164 SE_16BIT(predictor[1]) | |
165 in += 2; | |
166 } | |
167 } else { | |
168 for (i = 0; i < s->channels; i++) | |
169 predictor[i] = s->last_delta[i]; | |
170 } | 162 } |
171 | 163 |
172 while (in < buf_size) { | 164 while (in < buf_size) { |
173 predictor[channel_number] += interplay_delta_table[buf[in++]]; | 165 predictor[channel_number] += interplay_delta_table[buf[in++]]; |
174 SATURATE_S16(predictor[channel_number]); | 166 SATURATE_S16(predictor[channel_number]); |
175 output_samples[out++] = predictor[channel_number]; | 167 output_samples[out++] = predictor[channel_number]; |
176 | 168 |
177 /* toggle channel */ | 169 /* toggle channel */ |
178 channel_number ^= s->channels - 1; | 170 channel_number ^= s->channels - 1; |
179 } | 171 } |
180 | |
181 /* save predictors for next round */ | |
182 for (i = 0; i < s->channels; i++) | |
183 s->last_delta[i] = predictor[i]; | |
184 | 172 |
185 break; | 173 break; |
186 | 174 |
187 case CODEC_ID_XAN_DPCM: | 175 case CODEC_ID_XAN_DPCM: |
188 in = 0; | 176 in = 0; |