LPCM 24 bits support, patch by Lars Täuber, lars.taeuber gmx net

Originally committed as revision 13187 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Lars Täuber 2008-05-17 11:42:03 +00:00 committed by Diego Biurrun
parent 8f89843475
commit 1472b7dd28
4 changed files with 30 additions and 6 deletions

View File

@ -236,6 +236,7 @@ OBJS-$(CONFIG_ZMBV_ENCODER) += zmbvenc.o
OBJS-$(CONFIG_PCM_ALAW_DECODER) += pcm.o
OBJS-$(CONFIG_PCM_ALAW_ENCODER) += pcm.o
OBJS-$(CONFIG_PCM_DVD_DECODER) += pcm.o
OBJS-$(CONFIG_PCM_MULAW_DECODER) += pcm.o
OBJS-$(CONFIG_PCM_MULAW_ENCODER) += pcm.o
OBJS-$(CONFIG_PCM_S8_DECODER) += pcm.o

View File

@ -214,6 +214,7 @@ void avcodec_register_all(void)
/* PCM codecs */
REGISTER_ENCDEC (PCM_ALAW, pcm_alaw);
REGISTER_DECODER (PCM_DVD, pcm_dvd);
REGISTER_ENCDEC (PCM_MULAW, pcm_mulaw);
REGISTER_ENCDEC (PCM_S8, pcm_s8);
REGISTER_ENCDEC (PCM_S16BE, pcm_s16be);

View File

@ -30,7 +30,7 @@
#include "libavutil/avutil.h"
#define LIBAVCODEC_VERSION_MAJOR 51
#define LIBAVCODEC_VERSION_MINOR 56
#define LIBAVCODEC_VERSION_MINOR 57
#define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
@ -207,6 +207,7 @@ enum CodecID {
CODEC_ID_PCM_S24DAUD,
CODEC_ID_PCM_ZORK,
CODEC_ID_PCM_S16LE_PLANAR,
CODEC_ID_PCM_DVD,
/* various ADPCM codecs */
CODEC_ID_ADPCM_IMA_QT= 0x11000,

View File

@ -383,16 +383,22 @@ static int pcm_decode_frame(AVCodecContext *avctx,
samples = data;
src = buf;
n= av_get_bits_per_sample(avctx->codec_id)/8;
if(n && buf_size % n){
av_log(avctx, AV_LOG_ERROR, "invalid PCM packet\n");
return -1;
}
if(avctx->channels <= 0 || avctx->channels > MAX_CHANNELS){
av_log(avctx, AV_LOG_ERROR, "PCM channels out of bounds\n");
return -1;
}
n = avctx->channels * av_get_bits_per_sample(avctx->codec_id)/8;
/* av_get_bits_per_sample returns 0 for CODEC_ID_PCM_DVD */
if (CODEC_ID_PCM_DVD == avctx->codec_id)
/* 2 samples are interleaved per block in PCM_DVD */
n = 2 * avctx->channels * avctx->bits_per_sample/8;
if(n && buf_size % n){
av_log(avctx, AV_LOG_ERROR, "invalid PCM packet\n");
return -1;
}
buf_size= FFMIN(buf_size, *data_size/2);
*data_size=0;
@ -492,6 +498,20 @@ static int pcm_decode_frame(AVCodecContext *avctx,
*samples++ = s->table[*src++];
}
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);
while (n--) {
for (c=0; c < 2*avctx->channels; c++)
*samples++ = bytestream_get_be16(&src);
src += jump;
}
}
break;
default:
return -1;
}
@ -537,6 +557,7 @@ AVCodec name ## _decoder = { \
PCM_ENCODER(id,name,long_name_) PCM_DECODER(id,name,long_name_)
PCM_CODEC (CODEC_ID_PCM_ALAW, pcm_alaw, "A-law PCM");
PCM_CODEC (CODEC_ID_PCM_DVD, pcm_dvd, "signed 16|20|24-bit big-endian PCM");
PCM_CODEC (CODEC_ID_PCM_MULAW, pcm_mulaw, "mu-law PCM");
PCM_CODEC (CODEC_ID_PCM_S8, pcm_s8, "signed 8-bit PCM");
PCM_CODEC (CODEC_ID_PCM_S16BE, pcm_s16be, "signed 16-bit big-endian PCM");