From 0cdc6ec94130572e1da1902821e2b3cbcf0fbea8 Mon Sep 17 00:00:00 2001 From: Peter Ross Date: Sat, 23 Aug 2008 22:45:03 +0000 Subject: [PATCH] Upgrade 20/24-bit PCM DVD decoder use SAMPLE_FMT_S32. Patch supplied by lars dot taeuber at gmx dot net. Originally committed as revision 14931 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/pcm.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c index c0ac736..1e822e4 100644 --- a/libavcodec/pcm.c +++ b/libavcodec/pcm.c @@ -327,7 +327,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, PCMDecode *s = avctx->priv_data; int sample_size, c, n; short *samples; - const uint8_t *src, *src2[MAX_CHANNELS]; + const uint8_t *src, *src8, *src2[MAX_CHANNELS]; uint8_t *dstu8; int16_t *dst_int16_t; int32_t *dst_int32_t; @@ -467,18 +467,37 @@ static int pcm_decode_frame(AVCodecContext *avctx, } break; case CODEC_ID_PCM_DVD: - if(avctx->bits_per_sample != 20 && avctx->bits_per_sample != 24) { - av_log(avctx, AV_LOG_ERROR, "PCM DVD unsupported sample depth\n"); - return -1; - } else { - int jump = avctx->channels * (avctx->bits_per_sample-16) / 4; - n = buf_size / (avctx->channels * 2 * avctx->bits_per_sample / 8); + dst_int32_t = data; + n /= avctx->channels; + switch (avctx->bits_per_sample) { + case 20: while (n--) { - for (c=0; c < 2*avctx->channels; c++) - *samples++ = bytestream_get_be16(&src); - src += jump; + c = avctx->channels; + src8 = src + 4*c; + while (c--) { + *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8 &0xf0) << 8); + *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++ &0x0f) << 12); + } + src = src8; } + break; + case 24: + while (n--) { + c = avctx->channels; + src8 = src + 4*c; + while (c--) { + *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++) << 8); + *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++) << 8); + } + src = src8; + } + break; + default: + av_log(avctx, AV_LOG_ERROR, "PCM DVD unsupported sample depth\n"); + return -1; + break; } + samples = (short *) dst_int32_t; break; default: return -1; @@ -528,7 +547,7 @@ AVCodec name ## _decoder = { \ /* Note: Do not forget to add new entries to the Makefile as well. */ PCM_CODEC (CODEC_ID_PCM_ALAW, SAMPLE_FMT_S16, pcm_alaw, "A-law PCM"); -PCM_CODEC (CODEC_ID_PCM_DVD, SAMPLE_FMT_S16, pcm_dvd, "signed 16|20|24-bit big-endian PCM"); +PCM_CODEC (CODEC_ID_PCM_DVD, SAMPLE_FMT_S32, pcm_dvd, "signed 20|24-bit big-endian PCM"); PCM_CODEC (CODEC_ID_PCM_F32BE, SAMPLE_FMT_FLT, pcm_f32be, "32-bit floating point big-endian PCM"); PCM_CODEC (CODEC_ID_PCM_F32LE, SAMPLE_FMT_FLT, pcm_f32le, "32-bit floating point little-endian PCM"); PCM_CODEC (CODEC_ID_PCM_F64BE, SAMPLE_FMT_DBL, pcm_f64be, "64-bit floating point big-endian PCM"); -- 2.7.4