Mercurial > libavcodec.hg
comparison pcm.c @ 2852:6f7428adc6ad libavcodec
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
author | reimar |
---|---|
date | Fri, 02 Sep 2005 19:16:48 +0000 |
parents | 9404bbf9de07 |
children | 87c11495e393 |
comparison
equal
deleted
inserted
replaced
2851:411601677547 | 2852:6f7428adc6ad |
---|---|
21 * @file pcm.c | 21 * @file pcm.c |
22 * PCM codecs | 22 * PCM codecs |
23 */ | 23 */ |
24 | 24 |
25 #include "avcodec.h" | 25 #include "avcodec.h" |
26 #include "bitstream.h" // for ff_reverse | |
26 | 27 |
27 /* from g711.c by SUN microsystems (unrestricted use) */ | 28 /* from g711.c by SUN microsystems (unrestricted use) */ |
28 | 29 |
29 #define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ | 30 #define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ |
30 #define QUANT_MASK (0xf) /* Quantization field mask. */ | 31 #define QUANT_MASK (0xf) /* Quantization field mask. */ |
126 default: | 127 default: |
127 break; | 128 break; |
128 } | 129 } |
129 | 130 |
130 switch(avctx->codec->id) { | 131 switch(avctx->codec->id) { |
132 case CODEC_ID_PCM_S32LE: | |
133 case CODEC_ID_PCM_S32BE: | |
134 case CODEC_ID_PCM_U32LE: | |
135 case CODEC_ID_PCM_U32BE: | |
136 avctx->block_align = 4 * avctx->channels; | |
137 break; | |
138 case CODEC_ID_PCM_S24LE: | |
139 case CODEC_ID_PCM_S24BE: | |
140 case CODEC_ID_PCM_U24LE: | |
141 case CODEC_ID_PCM_U24BE: | |
142 case CODEC_ID_PCM_S24DAUD: | |
143 avctx->block_align = 3 * avctx->channels; | |
144 break; | |
131 case CODEC_ID_PCM_S16LE: | 145 case CODEC_ID_PCM_S16LE: |
132 case CODEC_ID_PCM_S16BE: | 146 case CODEC_ID_PCM_S16BE: |
133 case CODEC_ID_PCM_U16LE: | 147 case CODEC_ID_PCM_U16LE: |
134 case CODEC_ID_PCM_U16BE: | 148 case CODEC_ID_PCM_U16BE: |
135 avctx->block_align = 2 * avctx->channels; | 149 avctx->block_align = 2 * avctx->channels; |
168 break; | 182 break; |
169 } | 183 } |
170 return 0; | 184 return 0; |
171 } | 185 } |
172 | 186 |
187 /** | |
188 * \brief convert samples from 16 bit | |
189 * \param bps byte per sample for the destination format, must be >= 2 | |
190 * \param le 0 for big-, 1 for little-endian | |
191 * \param samples input samples | |
192 * \param dst output samples | |
193 * \param n number of samples in samples buffer. | |
194 */ | |
195 static inline void encode_from16(int bps, int le, int us, | |
196 short **samples, uint8_t **dst, int n) { | |
197 if (bps > 2) | |
198 memset(*dst, 0, n * bps); | |
199 if (le) *dst += bps - 2; | |
200 for(;n>0;n--) { | |
201 register int v = *(*samples)++; | |
202 if (us) v += 0x8000; | |
203 (*dst)[le] = v >> 8; | |
204 (*dst)[1 - le] = v; | |
205 *dst += bps; | |
206 } | |
207 if (le) *dst -= bps - 2; | |
208 } | |
209 | |
173 static int pcm_encode_frame(AVCodecContext *avctx, | 210 static int pcm_encode_frame(AVCodecContext *avctx, |
174 unsigned char *frame, int buf_size, void *data) | 211 unsigned char *frame, int buf_size, void *data) |
175 { | 212 { |
176 int n, sample_size, v; | 213 int n, sample_size, v; |
177 short *samples; | 214 short *samples; |
178 unsigned char *dst; | 215 unsigned char *dst; |
179 | 216 |
180 switch(avctx->codec->id) { | 217 switch(avctx->codec->id) { |
218 case CODEC_ID_PCM_S32LE: | |
219 case CODEC_ID_PCM_S32BE: | |
220 case CODEC_ID_PCM_U32LE: | |
221 case CODEC_ID_PCM_U32BE: | |
222 sample_size = 4; | |
223 break; | |
224 case CODEC_ID_PCM_S24LE: | |
225 case CODEC_ID_PCM_S24BE: | |
226 case CODEC_ID_PCM_U24LE: | |
227 case CODEC_ID_PCM_U24BE: | |
228 case CODEC_ID_PCM_S24DAUD: | |
229 sample_size = 3; | |
230 break; | |
181 case CODEC_ID_PCM_S16LE: | 231 case CODEC_ID_PCM_S16LE: |
182 case CODEC_ID_PCM_S16BE: | 232 case CODEC_ID_PCM_S16BE: |
183 case CODEC_ID_PCM_U16LE: | 233 case CODEC_ID_PCM_U16LE: |
184 case CODEC_ID_PCM_U16BE: | 234 case CODEC_ID_PCM_U16BE: |
185 sample_size = 2; | 235 sample_size = 2; |
191 n = buf_size / sample_size; | 241 n = buf_size / sample_size; |
192 samples = data; | 242 samples = data; |
193 dst = frame; | 243 dst = frame; |
194 | 244 |
195 switch(avctx->codec->id) { | 245 switch(avctx->codec->id) { |
246 case CODEC_ID_PCM_S32LE: | |
247 encode_from16(4, 1, 0, &samples, &dst, n); | |
248 break; | |
249 case CODEC_ID_PCM_S32BE: | |
250 encode_from16(4, 0, 0, &samples, &dst, n); | |
251 break; | |
252 case CODEC_ID_PCM_U32LE: | |
253 encode_from16(4, 1, 1, &samples, &dst, n); | |
254 break; | |
255 case CODEC_ID_PCM_U32BE: | |
256 encode_from16(4, 0, 1, &samples, &dst, n); | |
257 break; | |
258 case CODEC_ID_PCM_S24LE: | |
259 encode_from16(3, 1, 0, &samples, &dst, n); | |
260 break; | |
261 case CODEC_ID_PCM_S24BE: | |
262 encode_from16(3, 0, 0, &samples, &dst, n); | |
263 break; | |
264 case CODEC_ID_PCM_U24LE: | |
265 encode_from16(3, 1, 1, &samples, &dst, n); | |
266 break; | |
267 case CODEC_ID_PCM_U24BE: | |
268 encode_from16(3, 0, 1, &samples, &dst, n); | |
269 break; | |
270 case CODEC_ID_PCM_S24DAUD: | |
271 for(;n>0;n--) { | |
272 uint32_t tmp = ff_reverse[*samples >> 8] + | |
273 (ff_reverse[*samples & 0xff] << 8); | |
274 tmp <<= 4; // sync flags would go here | |
275 dst[2] = tmp & 0xff; | |
276 tmp >>= 8; | |
277 dst[1] = tmp & 0xff; | |
278 dst[0] = tmp >> 8; | |
279 samples++; | |
280 dst += 3; | |
281 } | |
282 break; | |
196 case CODEC_ID_PCM_S16LE: | 283 case CODEC_ID_PCM_S16LE: |
197 for(;n>0;n--) { | 284 for(;n>0;n--) { |
198 v = *samples++; | 285 v = *samples++; |
199 dst[0] = v & 0xff; | 286 dst[0] = v & 0xff; |
200 dst[1] = v >> 8; | 287 dst[1] = v >> 8; |
285 break; | 372 break; |
286 } | 373 } |
287 return 0; | 374 return 0; |
288 } | 375 } |
289 | 376 |
377 /** | |
378 * \brief convert samples to 16 bit | |
379 * \param bps byte per sample for the source format, must be >= 2 | |
380 * \param le 0 for big-, 1 for little-endian | |
381 * \param src input samples | |
382 * \param samples output samples | |
383 * \param src_len number of bytes in src | |
384 */ | |
385 static inline void decode_to16(int bps, int le, int us, | |
386 uint8_t **src, short **samples, int src_len) | |
387 { | |
388 register int n = src_len / bps; | |
389 if (le) *src += bps - 2; | |
390 for(;n>0;n--) { | |
391 *(*samples)++ = ((*src)[le] << 8 | (*src)[1 - le]) - (us?0x8000:0); | |
392 *src += bps; | |
393 } | |
394 if (le) *src -= bps - 2; | |
395 } | |
396 | |
290 static int pcm_decode_frame(AVCodecContext *avctx, | 397 static int pcm_decode_frame(AVCodecContext *avctx, |
291 void *data, int *data_size, | 398 void *data, int *data_size, |
292 uint8_t *buf, int buf_size) | 399 uint8_t *buf, int buf_size) |
293 { | 400 { |
294 PCMDecode *s = avctx->priv_data; | 401 PCMDecode *s = avctx->priv_data; |
301 | 408 |
302 if(buf_size > AVCODEC_MAX_AUDIO_FRAME_SIZE/2) | 409 if(buf_size > AVCODEC_MAX_AUDIO_FRAME_SIZE/2) |
303 buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE/2; | 410 buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE/2; |
304 | 411 |
305 switch(avctx->codec->id) { | 412 switch(avctx->codec->id) { |
413 case CODEC_ID_PCM_S32LE: | |
414 decode_to16(4, 1, 0, &src, &samples, buf_size); | |
415 break; | |
416 case CODEC_ID_PCM_S32BE: | |
417 decode_to16(4, 0, 0, &src, &samples, buf_size); | |
418 break; | |
419 case CODEC_ID_PCM_U32LE: | |
420 decode_to16(4, 1, 1, &src, &samples, buf_size); | |
421 break; | |
422 case CODEC_ID_PCM_U32BE: | |
423 decode_to16(4, 0, 1, &src, &samples, buf_size); | |
424 break; | |
425 case CODEC_ID_PCM_S24LE: | |
426 decode_to16(3, 1, 0, &src, &samples, buf_size); | |
427 break; | |
428 case CODEC_ID_PCM_S24BE: | |
429 decode_to16(3, 0, 0, &src, &samples, buf_size); | |
430 break; | |
431 case CODEC_ID_PCM_U24LE: | |
432 decode_to16(3, 1, 1, &src, &samples, buf_size); | |
433 break; | |
434 case CODEC_ID_PCM_U24BE: | |
435 decode_to16(3, 0, 1, &src, &samples, buf_size); | |
436 break; | |
437 case CODEC_ID_PCM_S24DAUD: | |
438 n = buf_size / 3; | |
439 for(;n>0;n--) { | |
440 uint32_t v = src[0] << 16 | src[1] << 8 | src[2]; | |
441 v >>= 4; // sync flags are here | |
442 *samples++ = ff_reverse[(v >> 8) & 0xff] + | |
443 (ff_reverse[v & 0xff] << 8); | |
444 src += 3; | |
445 } | |
446 break; | |
306 case CODEC_ID_PCM_S16LE: | 447 case CODEC_ID_PCM_S16LE: |
307 n = buf_size >> 1; | 448 n = buf_size >> 1; |
308 for(;n>0;n--) { | 449 for(;n>0;n--) { |
309 *samples++ = src[0] | (src[1] << 8); | 450 *samples++ = src[0] | (src[1] << 8); |
310 src += 2; | 451 src += 2; |
380 NULL, \ | 521 NULL, \ |
381 NULL, \ | 522 NULL, \ |
382 pcm_decode_frame, \ | 523 pcm_decode_frame, \ |
383 } | 524 } |
384 | 525 |
526 PCM_CODEC(CODEC_ID_PCM_S32LE, pcm_s32le); | |
527 PCM_CODEC(CODEC_ID_PCM_S32BE, pcm_s32be); | |
528 PCM_CODEC(CODEC_ID_PCM_U32LE, pcm_u32le); | |
529 PCM_CODEC(CODEC_ID_PCM_U32BE, pcm_u32be); | |
530 PCM_CODEC(CODEC_ID_PCM_S24LE, pcm_s24le); | |
531 PCM_CODEC(CODEC_ID_PCM_S24BE, pcm_s24be); | |
532 PCM_CODEC(CODEC_ID_PCM_U24LE, pcm_u24le); | |
533 PCM_CODEC(CODEC_ID_PCM_U24BE, pcm_u24be); | |
534 PCM_CODEC(CODEC_ID_PCM_S24DAUD, pcm_s24daud); | |
385 PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le); | 535 PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le); |
386 PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be); | 536 PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be); |
387 PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le); | 537 PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le); |
388 PCM_CODEC(CODEC_ID_PCM_U16BE, pcm_u16be); | 538 PCM_CODEC(CODEC_ID_PCM_U16BE, pcm_u16be); |
389 PCM_CODEC(CODEC_ID_PCM_S8, pcm_s8); | 539 PCM_CODEC(CODEC_ID_PCM_S8, pcm_s8); |