From aa29709ec8f42616ccc6ef0fda95a1a134c21ca5 Mon Sep 17 00:00:00 2001 From: Peter Ross Date: Sat, 26 Jul 2008 07:08:15 +0000 Subject: [PATCH] add CODEC_ID_PCM_F32BE (32-bit floating point PCM big endian decoder) Originally committed as revision 14409 to svn://svn.ffmpeg.org/ffmpeg/trunk --- ffmpeg.c | 1 + libavcodec/allcodecs.c | 1 + libavcodec/avcodec.h | 3 ++- libavcodec/pcm.c | 34 ++++++++++++++++++++++++++++++++++ libavcodec/utils.c | 2 ++ 5 files changed, 40 insertions(+), 1 deletion(-) diff --git a/ffmpeg.c b/ffmpeg.c index 57ec83fc1c..ba615b3481 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -639,6 +639,7 @@ static void do_audio_out(AVFormatContext *s, case CODEC_ID_PCM_S32BE: case CODEC_ID_PCM_U32LE: case CODEC_ID_PCM_U32BE: + case CODEC_ID_PCM_F32BE: size_out = size_out << 1; break; case CODEC_ID_PCM_S24LE: diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 8658d5a686..4cf719baa7 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -218,6 +218,7 @@ void avcodec_register_all(void) /* PCM codecs */ REGISTER_ENCDEC (PCM_ALAW, pcm_alaw); REGISTER_DECODER (PCM_DVD, pcm_dvd); + REGISTER_ENCDEC (PCM_F32BE, pcm_f32be); REGISTER_ENCDEC (PCM_MULAW, pcm_mulaw); REGISTER_ENCDEC (PCM_S8, pcm_s8); REGISTER_ENCDEC (PCM_S16BE, pcm_s16be); diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 3a53c7fd4a..f42d3906e5 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -30,7 +30,7 @@ #include "libavutil/avutil.h" #define LIBAVCODEC_VERSION_MAJOR 51 -#define LIBAVCODEC_VERSION_MINOR 60 +#define LIBAVCODEC_VERSION_MINOR 61 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ @@ -210,6 +210,7 @@ enum CodecID { CODEC_ID_PCM_ZORK, CODEC_ID_PCM_S16LE_PLANAR, CODEC_ID_PCM_DVD, + CODEC_ID_PCM_F32BE, /* various ADPCM codecs */ CODEC_ID_ADPCM_IMA_QT= 0x11000, diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c index 29779c5ba0..8f02fda7e3 100644 --- a/libavcodec/pcm.c +++ b/libavcodec/pcm.c @@ -107,6 +107,9 @@ static av_cold void build_xlaw_table(uint8_t *linear_to_xlaw, static av_cold int pcm_encode_init(AVCodecContext *avctx) { avctx->frame_size = 1; + if (avctx->codec->id==CODEC_ID_PCM_F32BE && avctx->sample_fmt!=SAMPLE_FMT_FLT) { + return -1; + } switch(avctx->codec->id) { case CODEC_ID_PCM_ALAW: build_xlaw_table(linear_to_alaw, alaw2linear, 0xd5); @@ -123,6 +126,7 @@ static av_cold int pcm_encode_init(AVCodecContext *avctx) case CODEC_ID_PCM_S32BE: case CODEC_ID_PCM_U32LE: case CODEC_ID_PCM_U32BE: + case CODEC_ID_PCM_F32BE: avctx->block_align = 4 * avctx->channels; break; case CODEC_ID_PCM_S24LE: @@ -198,6 +202,7 @@ static int pcm_encode_frame(AVCodecContext *avctx, case CODEC_ID_PCM_S32BE: case CODEC_ID_PCM_U32LE: case CODEC_ID_PCM_U32BE: + case CODEC_ID_PCM_F32BE: sample_size = 4; break; case CODEC_ID_PCM_S24LE: @@ -222,6 +227,16 @@ static int pcm_encode_frame(AVCodecContext *avctx, dst = frame; switch(avctx->codec->id) { + case CODEC_ID_PCM_F32BE: + { + float *fsamples = data; + for(;n>0;n--) { + float fv = *fsamples++; + bytestream_put_be32(&dst, av_flt2int(fv)); + } + samples = (void*)fsamples; + } + break; case CODEC_ID_PCM_S32LE: encode_from16(4, 1, 0, &samples, &dst, n); break; @@ -342,6 +357,15 @@ static av_cold int pcm_decode_init(AVCodecContext * avctx) default: break; } + + switch(avctx->codec->id) { + case CODEC_ID_PCM_F32BE: + avctx->sample_fmt = SAMPLE_FMT_FLT; + break; + default: + avctx->sample_fmt = SAMPLE_FMT_S16; + break; + } return 0; } @@ -407,6 +431,15 @@ static int pcm_decode_frame(AVCodecContext *avctx, src2[c] = &src[c*n]; switch(avctx->codec->id) { + case CODEC_ID_PCM_F32BE: + { + float *fsamples = data; + n = buf_size >> 2; + for(;n>0;n--) + *fsamples++ = av_int2flt(bytestream_get_be32(&src)); + samples = (void*)fsamples; + break; + } case CODEC_ID_PCM_S32LE: decode_to16(4, 1, 0, &src, &samples, buf_size); break; @@ -559,6 +592,7 @@ AVCodec name ## _decoder = { \ /* Note: Do not forget to add new entries to the Makefile as well. */ 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_F32BE, pcm_f32be, "32-bit floating point 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"); diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 3fb33d6f73..6af208dd52 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -1155,6 +1155,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) case CODEC_ID_PCM_S32BE: case CODEC_ID_PCM_U32LE: case CODEC_ID_PCM_U32BE: + case CODEC_ID_PCM_F32BE: bitrate = enc->sample_rate * enc->channels * 32; break; case CODEC_ID_PCM_S24LE: @@ -1301,6 +1302,7 @@ int av_get_bits_per_sample(enum CodecID codec_id){ case CODEC_ID_PCM_S32LE: case CODEC_ID_PCM_U32BE: case CODEC_ID_PCM_U32LE: + case CODEC_ID_PCM_F32BE: return 32; default: return 0;