[FFmpeg-devel] [PATCH] add 32bits output format to the flac decoder

Justin Ruggles justin.ruggles
Sun Dec 7 17:54:33 CET 2008


Mathieu Velten wrote:
> forgot the patch...
> 
> Mathieu Velten
> 
> 2008/12/7 Mathieu Velten <matmaul at gmail.com>:
>> with this patch flac decoder outputs SAMPLE_FMT_S32 instead of
>> SAMPLE_FMT_S16 when the bps of the stream is superior to 16 bits.
>>
>> Mathieu Velten
>>
>>
> Index: libavcodec/flac.c
> ===================================================================
> --- libavcodec/flac.c	(revision 16028)
> +++ libavcodec/flac.c	(working copy)
> @@ -607,7 +607,7 @@
>                              const uint8_t *buf, int buf_size)
>  {
>      FLACContext *s = avctx->priv_data;
> -    int tmp = 0, i, j = 0, input_buf_size = 0;
> +    int tmp = 0, i, j = 0, input_buf_size = 0, shift, offset_per_sample;
>      int16_t *samples = data;
>      int alloc_data_size= *data_size;
>  
> @@ -708,14 +708,31 @@
>      }
>      }
>  #else
> +    avctx->bits_per_raw_sample = s->bps;
> +
> +    if (s->bps > 16)
> +    {
> +        offset_per_sample = 2;
> +        avctx->sample_fmt = SAMPLE_FMT_S32;
> +        shift = 32 - s->bps;
> +    }
> +    else
> +    {
> +        offset_per_sample = 1;
> +        avctx->sample_fmt = SAMPLE_FMT_S16;
> +        shift = 16 - s->bps;
> +    }
> +

If you move shift and offset_per_sample to the FLACContext you can just
set them once at the start of encoding instead of for every frame, along
with avctx->bits_per_raw_sample.  It would also make ffmpeg report s32
as the sample type instead of s16 when appropriate.  A good place to do
this would be in ff_flac_parse_streaminfo().

>  #define DECORRELATE(left, right)\
>              assert(s->channels == 2);\
>              for (i = 0; i < s->blocksize; i++)\
>              {\
>                  int a= s->decoded[0][i];\
>                  int b= s->decoded[1][i];\
> -                *samples++ = ((left)  << (24 - s->bps)) >> 8;\
> -                *samples++ = ((right) << (24 - s->bps)) >> 8;\
> +                *(int32_t *)samples = (left)  << shift;\
> +                samples += offset_per_sample;\
> +                *(int32_t *)samples = (right) << shift;\
> +                samples += offset_per_sample;\
>              }\
>              break;
>  
> @@ -725,7 +742,10 @@
>              for (j = 0; j < s->blocksize; j++)
>              {
>                  for (i = 0; i < s->channels; i++)
> -                    *samples++ = (s->decoded[i][j] << (24 - s->bps)) >> 8;
> +                {
> +                    *(int32_t *)samples = s->decoded[i][j] << shift;
> +                    samples += offset_per_sample;
> +                }
>              }
>              break;
>          case LEFT_SIDE:

I can confirm that this works with the 24-bit samples I have and gives
bitexact output.

-Justin





More information about the ffmpeg-devel mailing list