[FFmpeg-devel] [RFC] LPCM 24 bits support
Michael Niedermayer
michaelni
Sat Apr 19 02:15:16 CEST 2008
On Fri, Apr 18, 2008 at 11:24:03PM +0200, Lars T?uber wrote:
> On Fri, 18 Apr 2008 22:52:40 +0200 Michael Niedermayer <michaelni at gmx.at> wrote:
> > On Fri, Apr 18, 2008 at 09:37:12PM +0200, Lars T?uber wrote:
> > > On Fri, 18 Apr 2008 22:08:24 +0200 Michael Niedermayer <michaelni at gmx.at> wrote:
> > > > On Fri, Apr 18, 2008 at 09:05:23PM +0200, Lars T?uber wrote:
> > > > > On Fri, 18 Apr 2008 15:39:43 +0200 Michael Niedermayer <michaelni at gmx.at> wrote:
> > > > > > On Thu, Apr 17, 2008 at 10:13:40PM +0200, Lars T?uber wrote:
> [...]
> > > @@ -492,6 +498,35 @@ static int pcm_decode_frame(AVCodecConte
> > > *samples++ = s->table[*src++];
> > > }
> > > break;
> > > + case CODEC_ID_PCM_DVD: {
> > > + int audio24[8*2], *ap;
> > > + const uint8_t *src_LSB;
> > > +
> > > + if (avctx->channels <= 0 || avctx->channels > 8) {
> > > + av_log(avctx, AV_LOG_ERROR, "PCM_DVD channels out of bounds\n");
> > > + return -1;
> > > + }
> > > + n = buf_size / (avctx->channels * 2 * avctx->bits_per_sample / 8);
> > > + while (n--) {
> > > + ap = audio24;
> > > + src_LSB = src + avctx->channels * 2 * 2;
> > > +
> > > + if (avctx->bits_per_sample == 20)
> > > + for (c=0; c < avctx->channels; c++, src+=4, src_LSB++ ) {
> > > + *ap++ = src[0]<<16 | src[1]<<8 | (*src_LSB & 0xf0);
> > > + *ap++ = src[2]<<16 | src[3]<<8 | (*src_LSB & 0x0f)<<4;
> > > + }
> > > + else {
> > > + for (c=0; c < 2*avctx->channels; c++, src+=2, src_LSB++ )
> > > + *ap++ = src[0]<<16 | src[1]<<8 | *src_LSB;
> > > + }
> > > + src = src_LSB;
> > > +
> > > + for (c=0; c < avctx->channels*2; c++)
> > > + *samples++ = audio24[c] >> 8;
> > > + }
> >
> > and what if bits_per_sample is something else than 20 or 24 ?
>
> Switch statement added.
>
> I'm not sure about the wording of the error message.
> Is it
> - sample depth
> - sample width or
> - sample resolution
> ???
all are fine
[...]
> diff -pur ffmpeg/libavcodec/pcm.c ffmpeg.1/libavcodec/pcm.c
> --- ffmpeg/libavcodec/pcm.c 2008-04-18 20:22:18.000000000 +0200
> +++ ffmpeg.1/libavcodec/pcm.c 2008-04-18 23:19:20.000000000 +0200
> @@ -492,6 +498,41 @@ static int pcm_decode_frame(AVCodecConte
> *samples++ = s->table[*src++];
> }
> break;
> + case CODEC_ID_PCM_DVD: {
> + int audio24[8*2], *ap;
> + const uint8_t *src_LSB;
> +
> + if (avctx->channels > 8) {
> + av_log(avctx, AV_LOG_ERROR, "PCM_DVD channels out of bounds\n");
> + return -1;
> + }
> + n = buf_size / (avctx->channels * 2 * avctx->bits_per_sample / 8);
> + while (n--) {
> + ap = audio24;
> + src_LSB = src + avctx->channels * 2 * 2;
> +
> + switch (avctx->bits_per_sample) {
> + case 20:
> + for (c=0; c < avctx->channels; c++, src+=4, src_LSB++ ) {
> + *ap++ = src[0]<<16 | src[1]<<8 | (*src_LSB & 0xf0);
> + *ap++ = src[2]<<16 | src[3]<<8 | (*src_LSB & 0x0f)<<4;
> + }
> + break;
> + case 24:
> + for (c=0; c < 2*avctx->channels; c++, src+=2, src_LSB++ )
> + *ap++ = src[0]<<16 | src[1]<<8 | *src_LSB;
> + break;
> + default:
> + av_log(avctx, AV_LOG_ERROR, "PCM_DVD unsupported sample depth\n");
> + return -1;
> + }
> + src = src_LSB;
> +
> + for (c=0; c < avctx->channels*2; c++)
> + *samples++ = audio24[c] >> 8;
following is simpler and faster:
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;
}
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+= avctx->channels * (avctx->bits_per_sample-16) / 4;
}
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
No snowflake in an avalanche ever feels responsible. -- Voltaire
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20080419/28282c5d/attachment.pgp>
More information about the ffmpeg-devel
mailing list