From 7e52080cb18332cb1da9fe133498750b6b4b0fb3 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Fri, 16 Nov 2012 16:00:04 +0000 Subject: [PATCH] pcm: support 24-bit/32-bit little-endian planar Used by LXF. Signed-off-by: Luca Barbato --- doc/general.texi | 4 +++- libavcodec/Makefile | 2 ++ libavcodec/allcodecs.c | 2 ++ libavcodec/avcodec.h | 2 ++ libavcodec/codec_desc.c | 14 ++++++++++++ libavcodec/pcm.c | 47 +++++++++++++++++++++++++++++------------ libavcodec/utils.c | 2 ++ libavcodec/version.h | 2 +- libavformat/nut.c | 2 ++ 9 files changed, 61 insertions(+), 16 deletions(-) diff --git a/doc/general.texi b/doc/general.texi index aeda8ea92b..c2dc2723d7 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -771,7 +771,9 @@ following image formats are supported: @tab supported through external library libopus @item PCM A-law @tab X @tab X @item PCM mu-law @tab X @tab X -@item PCM 16-bit little-endian planar @tab @tab X +@item PCM signed 16-bit little-endian planar @tab @tab X +@item PCM signed 24-bit little-endian planar @tab @tab X +@item PCM signed 32-bit little-endian planar @tab @tab X @item PCM 32-bit floating point big-endian @tab X @tab X @item PCM 32-bit floating point little-endian @tab X @tab X @item PCM 64-bit floating point big-endian @tab X @tab X diff --git a/libavcodec/Makefile b/libavcodec/Makefile index b10526bb43..8e0d60d18f 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -454,10 +454,12 @@ OBJS-$(CONFIG_PCM_S24DAUD_DECODER) += pcm.o OBJS-$(CONFIG_PCM_S24DAUD_ENCODER) += pcm.o OBJS-$(CONFIG_PCM_S24LE_DECODER) += pcm.o OBJS-$(CONFIG_PCM_S24LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S24LE_PLANAR_DECODER) += pcm.o OBJS-$(CONFIG_PCM_S32BE_DECODER) += pcm.o OBJS-$(CONFIG_PCM_S32BE_ENCODER) += pcm.o OBJS-$(CONFIG_PCM_S32LE_DECODER) += pcm.o OBJS-$(CONFIG_PCM_S32LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S32LE_PLANAR_DECODER) += pcm.o OBJS-$(CONFIG_PCM_U8_DECODER) += pcm.o OBJS-$(CONFIG_PCM_U8_ENCODER) += pcm.o OBJS-$(CONFIG_PCM_U16BE_DECODER) += pcm.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index f827ca3a31..55d7957afd 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -352,8 +352,10 @@ void avcodec_register_all(void) REGISTER_ENCDEC (PCM_S24BE, pcm_s24be); REGISTER_ENCDEC (PCM_S24DAUD, pcm_s24daud); REGISTER_ENCDEC (PCM_S24LE, pcm_s24le); + REGISTER_DECODER(PCM_S24LE_PLANAR, pcm_s24le_planar); REGISTER_ENCDEC (PCM_S32BE, pcm_s32be); REGISTER_ENCDEC (PCM_S32LE, pcm_s32le); + REGISTER_DECODER(PCM_S32LE_PLANAR, pcm_s32le_planar); REGISTER_ENCDEC (PCM_U8, pcm_u8); REGISTER_ENCDEC (PCM_U16BE, pcm_u16be); REGISTER_ENCDEC (PCM_U16LE, pcm_u16le); diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 60cbeece57..ea055fa860 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -305,6 +305,8 @@ enum AVCodecID { AV_CODEC_ID_PCM_LXF, AV_CODEC_ID_S302M, AV_CODEC_ID_PCM_S8_PLANAR, + AV_CODEC_ID_PCM_S24LE_PLANAR, + AV_CODEC_ID_PCM_S32LE_PLANAR, /* various ADPCM codecs */ AV_CODEC_ID_ADPCM_IMA_QT = 0x11000, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index abab828ec6..f486cb2c21 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -1369,6 +1369,20 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("PCM 16-bit little-endian planar"), .props = AV_CODEC_PROP_LOSSLESS, }, + { + .id = AV_CODEC_ID_PCM_S24LE_PLANAR, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s24le_planar", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 24-bit little-endian planar"), + .props = AV_CODEC_PROP_LOSSLESS, + }, + { + .id = AV_CODEC_ID_PCM_S32LE_PLANAR, + .type = AVMEDIA_TYPE_AUDIO, + .name = "pcm_s32le_planar", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 32-bit little-endian planar"), + .props = AV_CODEC_PROP_LOSSLESS, + }, { .id = AV_CODEC_ID_PCM_DVD, .type = AVMEDIA_TYPE_AUDIO, diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c index 5b3bdf44e9..26801fd561 100644 --- a/libavcodec/pcm.c +++ b/libavcodec/pcm.c @@ -250,6 +250,30 @@ static av_cold int pcm_decode_init(AVCodecContext *avctx) dst += size / 8; \ } +#if HAVE_BIGENDIAN +#define DECODE_PLANAR(size, endian, src, dst, n, shift, offset) \ + { \ + int av_unused n2; \ + n /= avctx->channels; \ + for (c = 0; c < avctx->channels; c++) { \ + samples = frame->extended_data[c]; \ + n2 = n; \ + DECODE(size, endian, src, samples, n2, 0, 0) \ + } \ + } +#else +#define DECODE_PLANAR(size, endian, src, dst, n, shift, offset) \ + { \ + int av_unused n2; \ + n /= avctx->channels; \ + for (c = 0; c < avctx->channels; c++) { \ + samples = frame->extended_data[c]; \ + memcpy(samples, src, n * size / 8); \ + src += n * size / 8; \ + } \ + } +#endif /* HAVE_BIGENDIAN */ + static int pcm_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { @@ -325,21 +349,14 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data, } break; case AV_CODEC_ID_PCM_S16LE_PLANAR: - { - int av_unused n2; - n /= avctx->channels; - for (c = 0; c < avctx->channels; c++) { - samples = frame->extended_data[c]; -#if HAVE_BIGENDIAN - n2 = n; - DECODE(16, le16, src, samples, n2, 0, 0) -#else - memcpy(samples, src, n * 2); - src += n * 2; -#endif - } + DECODE_PLANAR(16, le16, src, samples, n, 0, 0); + break; + case AV_CODEC_ID_PCM_S24LE_PLANAR: + DECODE_PLANAR(32, le24, src, samples, n, 8, 0); + break; + case AV_CODEC_ID_PCM_S32LE_PLANAR: + DECODE_PLANAR(32, le32, src, samples, n, 0, 0); break; - } case AV_CODEC_ID_PCM_U16LE: DECODE(16, le16, src, samples, n, 0, 0x8000) break; @@ -495,8 +512,10 @@ PCM_DECODER(PCM_S16LE_PLANAR, AV_SAMPLE_FMT_S16P, pcm_s16le_planar, "PCM 16-bit PCM_CODEC (PCM_S24BE, AV_SAMPLE_FMT_S32, pcm_s24be, "PCM signed 24-bit big-endian"); PCM_CODEC (PCM_S24DAUD, AV_SAMPLE_FMT_S16, pcm_s24daud, "PCM D-Cinema audio signed 24-bit"); PCM_CODEC (PCM_S24LE, AV_SAMPLE_FMT_S32, pcm_s24le, "PCM signed 24-bit little-endian"); +PCM_DECODER(PCM_S24LE_PLANAR, AV_SAMPLE_FMT_S32P,pcm_s24le_planar, "PCM signed 24-bit little-endian planar"); PCM_CODEC (PCM_S32BE, AV_SAMPLE_FMT_S32, pcm_s32be, "PCM signed 32-bit big-endian"); PCM_CODEC (PCM_S32LE, AV_SAMPLE_FMT_S32, pcm_s32le, "PCM signed 32-bit little-endian"); +PCM_DECODER(PCM_S32LE_PLANAR, AV_SAMPLE_FMT_S32P,pcm_s32le_planar, "PCM signed 32-bit little-endian planar"); PCM_CODEC (PCM_U8, AV_SAMPLE_FMT_U8, pcm_u8, "PCM unsigned 8-bit"); PCM_CODEC (PCM_U16BE, AV_SAMPLE_FMT_S16, pcm_u16be, "PCM unsigned 16-bit big-endian"); PCM_CODEC (PCM_U16LE, AV_SAMPLE_FMT_S16, pcm_u16le, "PCM unsigned 16-bit little-endian"); diff --git a/libavcodec/utils.c b/libavcodec/utils.c index bf79cf1d08..9ef477f429 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -1840,11 +1840,13 @@ int av_get_exact_bits_per_sample(enum AVCodecID codec_id) case AV_CODEC_ID_PCM_S24DAUD: case AV_CODEC_ID_PCM_S24BE: case AV_CODEC_ID_PCM_S24LE: + case AV_CODEC_ID_PCM_S24LE_PLANAR: case AV_CODEC_ID_PCM_U24BE: case AV_CODEC_ID_PCM_U24LE: return 24; case AV_CODEC_ID_PCM_S32BE: case AV_CODEC_ID_PCM_S32LE: + case AV_CODEC_ID_PCM_S32LE_PLANAR: case AV_CODEC_ID_PCM_U32BE: case AV_CODEC_ID_PCM_U32LE: case AV_CODEC_ID_PCM_F32BE: diff --git a/libavcodec/version.h b/libavcodec/version.h index 574e02a7e2..55ef7055c3 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -27,7 +27,7 @@ */ #define LIBAVCODEC_VERSION_MAJOR 55 -#define LIBAVCODEC_VERSION_MINOR 20 +#define LIBAVCODEC_VERSION_MINOR 21 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --git a/libavformat/nut.c b/libavformat/nut.c index e8dbc54a10..2e1d129ed7 100644 --- a/libavformat/nut.c +++ b/libavformat/nut.c @@ -146,6 +146,8 @@ const AVCodecTag ff_nut_audio_tags[] = { { AV_CODEC_ID_PCM_U32LE, MKTAG('P', 'U', 'D', 32) }, { AV_CODEC_ID_PCM_U8, MKTAG('P', 'U', 'D', 8) }, { AV_CODEC_ID_PCM_S16LE_PLANAR, MKTAG('P', 'S', 'P', 16) }, + { AV_CODEC_ID_PCM_S24LE_PLANAR, MKTAG('P', 'S', 'P', 24) }, + { AV_CODEC_ID_PCM_S32LE_PLANAR, MKTAG('P', 'S', 'P', 32) }, { AV_CODEC_ID_MP3, MKTAG('M', 'P', '3', ' ') }, { AV_CODEC_ID_NONE, 0 } };