[FFmpeg-devel] [RFC] LPCM 24 bits support
Giuliano Pochini
pochini
Sun Mar 30 20:56:17 CEST 2008
On Sun, 30 Mar 2008 01:48:22 +0100
Michael Niedermayer <michaelni at gmx.at> wrote:
> On Sat, Mar 29, 2008 at 08:25:45PM +0000, Giuliano Pochini wrote:
> > On Wed, 26 Mar 2008 00:48:39 +0100
> > Michael Niedermayer <michaelni at gmx.at> wrote:
> >
> > > On Wed, Mar 26, 2008 at 12:20:13AM +0000, Giuliano Pochini wrote:
> > > > } else if (startcode >= 0xa0 && startcode <= 0xaf) {
> > > > type = CODEC_TYPE_AUDIO;
> > > > - codec_id = CODEC_ID_PCM_S16BE;
> > > > + codec_id = CODEC_ID_PCM_DVD;
> > >
> > > CODEC_ID_PCM_S16BE should stay CODEC_ID_PCM_S16BE
> >
> > My patch also handles that format. If codec_id stays CODEC_ID_PCM_S16BE
> > then I have to place the DVD LPCM decoder into the CODEC_ID_PCM_S16BE case
> > in pcm.c which doesn't look correct IMHO. Any hints ?
>
> If it is 16bit PCM set CODEC_ID_PCM_S16BE, if it is not set CODEC_ID_DVD_LPCM
> or whatever is the correct name.
Ok, here is the revised patch. In case bits_per_sample is unknown it
returns AVERROR(EINVAL). I'm not sure if it's correct and if we actually
need to check that.
diff -dupr ffmpeg__orig/libavcodec/allcodecs.c ffmpeg/libavcodec/allcodecs.c
--- ffmpeg__orig/libavcodec/allcodecs.c 2008-02-06 12:37:37.000000000 +0000
+++ ffmpeg/libavcodec/allcodecs.c 2008-03-30 16:59:35.000000000 +0000
@@ -227,6 +227,8 @@ void avcodec_register_all(void)
REGISTER_ENCDEC (PCM_U32BE, pcm_u32be);
REGISTER_ENCDEC (PCM_U32LE, pcm_u32le);
REGISTER_ENCDEC (PCM_ZORK , pcm_zork);
+ REGISTER_DECODER (PCM_DVD20, pcm_dvd20);
+ REGISTER_DECODER (PCM_DVD24, pcm_dvd24);
/* dpcm codecs */
REGISTER_DECODER (INTERPLAY_DPCM, interplay_dpcm);
diff -dupr ffmpeg__orig/libavcodec/avcodec.h ffmpeg/libavcodec/avcodec.h
--- ffmpeg__orig/libavcodec/avcodec.h 2008-02-06 12:37:37.000000000 +0000
+++ ffmpeg/libavcodec/avcodec.h 2008-03-30 16:59:35.000000000 +0000
@@ -192,6 +192,8 @@ enum CodecID {
CODEC_ID_PCM_S24DAUD,
CODEC_ID_PCM_ZORK,
CODEC_ID_PCM_S16LE_PLANAR,
+ CODEC_ID_PCM_DVD20,
+ CODEC_ID_PCM_DVD24,
/* various ADPCM codecs */
CODEC_ID_ADPCM_IMA_QT= 0x11000,
diff -dupr ffmpeg__orig/libavcodec/pcm.c ffmpeg/libavcodec/pcm.c
--- ffmpeg__orig/libavcodec/pcm.c 2008-02-06 12:37:37.000000000 +0000
+++ ffmpeg/libavcodec/pcm.c 2008-03-30 18:41:30.000000000 +0000
@@ -492,6 +492,43 @@ static int pcm_decode_frame(AVCodecConte
*samples++ = s->table[*src++];
}
break;
+ case CODEC_ID_PCM_DVD20:
+ {
+ int audio24[8*2], *ap;
+ const uint8_t *src_LSB;
+
+ for (n=buf_size/(avctx->channels * 5); n>0; n--) {
+ ap = audio24;
+ src_LSB = src + avctx->channels * 2 * 2;
+ for (c=0; c<avctx->channels; c++, src+=4, src_LSB++) {
+ *ap++ = (((const int8_t *)src)[0]<<16) + (src[1]<<8) + (*src_LSB & 0xf0);
+ *ap++ = (((const int8_t *)src)[2]<<16) + (src[3]<<8) + ((*src_LSB << 4) & 0xff);
+ }
+ src = src_LSB;
+
+ for (c=0; c<avctx->channels * 2; c++)
+ *samples++ = audio24[c] >> 8;
+ }
+ break;
+ }
+ case CODEC_ID_PCM_DVD24:
+ {
+ int audio24[8*2], *ap;
+ const uint8_t *src_LSB;
+
+ for (n=buf_size/(avctx->channels * 2 * 3); n>0; n--) {
+ ap = audio24;
+ src_LSB = src + avctx->channels * 2 * 2;
+ for (c=0; c<avctx->channels * 2; c++, src+=2, src_LSB++) {
+ *ap++ = (((const int8_t *)src)[0]<<16) + (src[1]<<8) + *src_LSB;
+ }
+ src = src_LSB;
+
+ for (c=0; c<avctx->channels * 2; c++)
+ *samples++ = audio24[c] >> 8;
+ }
+ break;
+ }
default:
return -1;
}
@@ -553,3 +590,5 @@ PCM_CODEC (CODEC_ID_PCM_U8, pcm_u8);
PCM_CODEC (CODEC_ID_PCM_ALAW, pcm_alaw);
PCM_CODEC (CODEC_ID_PCM_MULAW, pcm_mulaw);
PCM_CODEC (CODEC_ID_PCM_ZORK, pcm_zork);
+PCM_DECODER(CODEC_ID_PCM_DVD20, pcm_dvd20);
+PCM_DECODER(CODEC_ID_PCM_DVD24, pcm_dvd24);
diff -dupr ffmpeg__orig/libavformat/mpeg.c ffmpeg/libavformat/mpeg.c
--- ffmpeg__orig/libavformat/mpeg.c 2008-02-06 12:37:37.000000000 +0000
+++ ffmpeg/libavformat/mpeg.c 2008-03-30 18:43:27.000000000 +0000
@@ -514,7 +514,21 @@ static int mpegps_read_packet(AVFormatCo
freq = (b1 >> 4) & 3;
st->codec->sample_rate = lpcm_freq_tab[freq];
st->codec->channels = 1 + (b1 & 7);
- st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * 2;
+ st->codec->bits_per_sample = 16 + ((b1 >> 6) & 3) * 4;
+ st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_sample;
+ switch (st->codec->bits_per_sample) {
+ case 16:
+ st->codec->codec_id = CODEC_ID_PCM_S16BE;
+ break;
+ case 20:
+ st->codec->codec_id = CODEC_ID_PCM_DVD20;
+ break;
+ case 24:
+ st->codec->codec_id = CODEC_ID_PCM_DVD24;
+ break;
+ default:
+ return AVERROR(EINVAL);
+ }
}
av_new_packet(pkt, len);
get_buffer(s->pb, pkt->data, pkt->size);
--
Giuliano.
More information about the ffmpeg-devel
mailing list