Commit 1472b7dd authored by Lars Täuber's avatar Lars Täuber Committed by Diego Biurrun

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
parent 8f898434
...@@ -236,6 +236,7 @@ OBJS-$(CONFIG_ZMBV_ENCODER) += zmbvenc.o ...@@ -236,6 +236,7 @@ OBJS-$(CONFIG_ZMBV_ENCODER) += zmbvenc.o
OBJS-$(CONFIG_PCM_ALAW_DECODER) += pcm.o OBJS-$(CONFIG_PCM_ALAW_DECODER) += pcm.o
OBJS-$(CONFIG_PCM_ALAW_ENCODER) += 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_DECODER) += pcm.o
OBJS-$(CONFIG_PCM_MULAW_ENCODER) += pcm.o OBJS-$(CONFIG_PCM_MULAW_ENCODER) += pcm.o
OBJS-$(CONFIG_PCM_S8_DECODER) += pcm.o OBJS-$(CONFIG_PCM_S8_DECODER) += pcm.o
......
...@@ -214,6 +214,7 @@ void avcodec_register_all(void) ...@@ -214,6 +214,7 @@ void avcodec_register_all(void)
/* PCM codecs */ /* PCM codecs */
REGISTER_ENCDEC (PCM_ALAW, pcm_alaw); REGISTER_ENCDEC (PCM_ALAW, pcm_alaw);
REGISTER_DECODER (PCM_DVD, pcm_dvd);
REGISTER_ENCDEC (PCM_MULAW, pcm_mulaw); REGISTER_ENCDEC (PCM_MULAW, pcm_mulaw);
REGISTER_ENCDEC (PCM_S8, pcm_s8); REGISTER_ENCDEC (PCM_S8, pcm_s8);
REGISTER_ENCDEC (PCM_S16BE, pcm_s16be); REGISTER_ENCDEC (PCM_S16BE, pcm_s16be);
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include "libavutil/avutil.h" #include "libavutil/avutil.h"
#define LIBAVCODEC_VERSION_MAJOR 51 #define LIBAVCODEC_VERSION_MAJOR 51
#define LIBAVCODEC_VERSION_MINOR 56 #define LIBAVCODEC_VERSION_MINOR 57
#define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
...@@ -207,6 +207,7 @@ enum CodecID { ...@@ -207,6 +207,7 @@ enum CodecID {
CODEC_ID_PCM_S24DAUD, CODEC_ID_PCM_S24DAUD,
CODEC_ID_PCM_ZORK, CODEC_ID_PCM_ZORK,
CODEC_ID_PCM_S16LE_PLANAR, CODEC_ID_PCM_S16LE_PLANAR,
CODEC_ID_PCM_DVD,
/* various ADPCM codecs */ /* various ADPCM codecs */
CODEC_ID_ADPCM_IMA_QT= 0x11000, CODEC_ID_ADPCM_IMA_QT= 0x11000,
......
...@@ -383,16 +383,22 @@ static int pcm_decode_frame(AVCodecContext *avctx, ...@@ -383,16 +383,22 @@ static int pcm_decode_frame(AVCodecContext *avctx,
samples = data; samples = data;
src = buf; 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){ if(avctx->channels <= 0 || avctx->channels > MAX_CHANNELS){
av_log(avctx, AV_LOG_ERROR, "PCM channels out of bounds\n"); av_log(avctx, AV_LOG_ERROR, "PCM channels out of bounds\n");
return -1; 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); buf_size= FFMIN(buf_size, *data_size/2);
*data_size=0; *data_size=0;
...@@ -492,6 +498,20 @@ static int pcm_decode_frame(AVCodecContext *avctx, ...@@ -492,6 +498,20 @@ static int pcm_decode_frame(AVCodecContext *avctx,
*samples++ = s->table[*src++]; *samples++ = s->table[*src++];
} }
break; 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: default:
return -1; return -1;
} }
...@@ -537,6 +557,7 @@ AVCodec name ## _decoder = { \ ...@@ -537,6 +557,7 @@ AVCodec name ## _decoder = { \
PCM_ENCODER(id,name,long_name_) PCM_DECODER(id,name,long_name_) 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_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_MULAW, pcm_mulaw, "mu-law PCM");
PCM_CODEC (CODEC_ID_PCM_S8, pcm_s8, "signed 8-bit 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"); PCM_CODEC (CODEC_ID_PCM_S16BE, pcm_s16be, "signed 16-bit big-endian PCM");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment