[FFmpeg-devel] PATCH: COOK audio decode infastructure to support fixpoint optimization

Marc Hoffman mmhoffm
Sun Jul 15 19:13:44 CEST 2007


On 7/15/07, Benjamin Larsson <banan at ludd.ltu.se> wrote:
>
> Marc Hoffman wrote:
> > This patch changes the way the data flows by introducing a vec_t data
> > type which is just unsigned char. This way we can abstract the low
> > level data type itself keeping the logic the same.  I'm using a char
> > type so we can walk through the data this is not possible with voids
> > to my knowledge. I have chosen to use vec_t so that we can easily
> > locate the vectors which represent the input and output signals of the
> > system.
>
> Ok, I don't know if this is the best way to do it, but I'll assume it is
> for now.
>
> >
> > I will then add a set of overloaded primitives to the existing
> > structure that handle the lowlevel stuff like quantization, decouple,
> > satruate, interpolate, and imlt etc that needs to know if your working
> > with float or shorts.  I want to keep all the logic the same so I will
> > also introduce a fixpoint fft which I'm in the process of developing
> > under the ffmpeg license as GPL code.
>
> No chance for a LGPL license ? And if you need a reference fp fft to
> look at use this:



LGPL thats what I meant .


http://svn.rockbox.org/viewvc.cgi/trunk/apps/codecs/libwma/wmadeci.c?revision=13859&view=markup
>
> >
> > Please review:
> >
> >
> >
> > ------------------------------------------------------------------------
> >
> > Index: libavcodec/cook.c
> > ===================================================================
> > --- libavcodec/cook.c (revision 9441)
> > +++ libavcodec/cook.c (working copy)
> > @@ -61,6 +61,8 @@
> >  #define JOINT_STEREO    0x1000003
> >  #define MC_COOK         0x2000000   //multichannel Cook, not supported
> >
> > +#define vec_t uint8_t
> > +
> >  #define SUBBAND_SIZE    20
> >  //#define COOKDEBUG
> >
> > @@ -69,7 +71,43 @@
> >      int *previous;
> >  } cook_gains;
> >
> > -typedef struct {
> > +
> > +
> > +typedef struct cook {
> > +
> > +    /*
> > +      joint_decode: creates mlt_buffer1, mlt_buffer2
> > +
> > +     mono_decode: creates decode_buffer
> > +          ... category handling all integer and bitstream related...
> > +
> > +          decode_vectors: creates mlt_buffer from categories.
> > +              scalar_dequant: for each block of 20 elements ie
> SUBBAND_SIZE. 32bit-floats
> > +                 (quant_centroid_tab[index][subband_coef_index[i]],
> > +                  dither_tab[index],
> > +                  rootpow2tab[quant_index+63])
> > +
> > +          mlt_compensate_output:
> > +              imlt_gain: inverse modified dct + windowing all dones as
> 32bit-floats
>
> dones
>
> > +                 (mlt_window)
> > +              saturate to 16bit integers
> > +
> > +     then decode_buffer is separated into mlt_buffer1, mlt_buffer2 via
> cplscale multipliers.
> > +    */
> > +    void (* scalar_dequant)(struct cook *q, int index, int quant_index,
> > +                         int* subband_coef_index, int*
> subband_coef_sign,
> > +                         vec_t* mlt_p);
> > +
> > +    void (* decouple) (struct cook *q, int *decouple_tab,
> > +                    vec_t *decode_buffer, vec_t *mlt_buffer1, vec_t
> *mlt_buffer2);
> > +
> > +    void (* interpolate) (struct cook *q, vec_t* buffer, int
> gain_index, int gain_index_next);
> > +
> > +    void (* saturate_output) (struct cook *q, int chan, int16_t *out);
> > +
> > +
> > +    int f_sample_size;
> >
> > [...]
> >
> > +
> > +static void joint_decode(COOKContext *q, vec_t* mlt_buffer1,
> > +                         vec_t* mlt_buffer2) {
> > +    int decouple_tab[SUBBAND_SIZE];
> > +    vec_t *decode_buffer;
> > +
> > +    decode_buffer = av_malloc (1060*q->f_sample_size);
>
> Don't allocate memory with malloc during decode. Use a fixed max size.
>
> > +    memset(decouple_tab, 0, sizeof(decouple_tab));
> > +    memset(decode_buffer, 0, 1060*q->f_sample_size);
> > +
> > +    /* Make sure the buffers are zeroed out. */
> > +    memset(mlt_buffer1,0, 1024*q->f_sample_size);
> > +    memset(mlt_buffer2,0, 1024*q->f_sample_size);
> > +    decouple_info(q, decouple_tab);
> > +    mono_decode(q, decode_buffer);
> > +    q->decouple (q, decouple_tab, decode_buffer, mlt_buffer1,
> mlt_buffer2);
> > +    av_free (decode_buffer);
> > +}
> > +
>
> To me it looks ok but are you sure the f_sample_size thing is needed ?
> It should be 4 for both float and fp and if it is set to that lots of
> logic is simplified.


I guess you might be correct. Initially I was thinking we might be able to
use 16-bit ints to represent the signal and not 32-bits.  I'm still not sure
if the implementation requires the higher precision to be maintained does
anyone know if the algorithm requires the 24bits?

MvH
> Benjamin Larsson
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at mplayerhq.hu
> http://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-devel
>




More information about the ffmpeg-devel mailing list