summaryrefslogtreecommitdiff
path: root/libavcodec/pcm.c
diff options
context:
space:
mode:
authorPeter Ross <pross@xvid.org>2008-08-23 22:45:03 +0000
committerPeter Ross <pross@xvid.org>2008-08-23 22:45:03 +0000
commit0cdc6ec94130572e1da1902821e2b3cbcf0fbea8 (patch)
tree0406ab07c63010d642c06b3a48da3f0491ba25ef /libavcodec/pcm.c
parentee7948cb8d7fc020f41f90f14c885e937f48e409 (diff)
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
Diffstat (limited to 'libavcodec/pcm.c')
-rw-r--r--libavcodec/pcm.c41
1 files changed, 30 insertions, 11 deletions
diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c
index c0ac736512..1e822e4498 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");