[FFmpeg-devel] [PATCH] Lowpass functionality for lavc
Kostya
kostya.shishkov
Mon Aug 18 08:28:04 CEST 2008
On Sun, Aug 17, 2008 at 03:10:34PM +0200, Michael Niedermayer wrote:
> On Sun, Aug 17, 2008 at 03:19:19PM +0300, Kostya wrote:
> > On Sat, Aug 16, 2008 at 06:01:45PM +0200, Michael Niedermayer wrote:
> > > On Sat, Aug 16, 2008 at 06:35:43PM +0300, Kostya wrote:
> > [...]
> > > > >
> > > > > > #define FILTER(i0, i1, i2, i3) \
> > > > > > in = *src * c->gain; \
> > > > >
> > > > > > res = (s->x[i0] + in )*1 \
> > > > > > + (s->x[i1] + s->x[i3])*4 \
> > > > > > + s->x[i2] *6 \
> > > > > > + c->c[0]*s->y[i0] + c->c[1]*s->y[i1] \
> > > > > > + c->c[2]*s->y[i2] + c->c[3]*s->y[i3]; \
> > > > > > *dst = av_clip_int16(lrintf(res)); \
> > > > > > s->x[i0] = in; \
> > > > > > s->y[i0] = res; \
> > > > >
> > > > > i think the followng is equivalent and needs a few memory accesses less
> > > > >
> > > > > in += c->c[0]*s->y[i0] + c->c[1]*s->y[i1]
> > > > > + c->c[2]*s->y[i2] + c->c[3]*s->y[i3];
> > > > > res = s->y[i0] + in
> > > > > + (s->y[i1] + s->y[i3])*4
> > > > > + s->y[i2] *6
> > > > > s->y[i0]= in;
> > > >
> > > > err, I am not sure that will work at all
> > > > how those s->x[] and s->y[] are merged into one array?
> > >
> > > Wikipedia has pretty pictures about the trick:
> > > http://en.wikipedia.org/wiki/Digital_biquad_filter#Direct_Form_1
> > > http://en.wikipedia.org/wiki/Digital_biquad_filter#Direct_Form_2
> >
> > indeed, thanks for a pointer
> >
> > implemented in this way
>
> [...]
>
> > const struct FFLPFilterCoeffs* ff_lowpass_filter_init_coeffs(int order, float cutoff_ratio)
> > {
> > int i, j, size;
> >
> > //we can create only order-4 filters with cutoff ratio <= 0.5 for now
> > if(order != LOWPASS_FILTER_ORDER) return NULL;
> >
> > size = sizeof(lp_cutoff_ratios) / sizeof(lp_cutoff_ratios[0]);
> > if(cutoff_ratio > lp_cutoff_ratios[0])
> > return NULL;
> > for(i = 0; i < size; i++){
> > if(cutoff_ratio >= lp_cutoff_ratios[i])
> > break;
> > }
> > if(i == size)
> > i = size - 1;
> > return &lp_filter_coeffs[i];
> > }
> >
> > struct FFLPFilterState* ff_lowpass_filter_init_state(int order)
> > {
> > if(order != LOWPASS_FILTER_ORDER) return NULL;
> > return av_mallocz(sizeof(FFLPFilterState));
> > }
> >
> > #define FILTER(i0, i1, i2, i3) \
> > in = *src * c->gain \
> > + c->c[0]*s->x[i0] + c->c[1]*s->x[i1] \
> > + c->c[2]*s->x[i2] + c->c[3]*s->x[i3]; \
> > res = (s->x[i0] + in )*1 \
> > + (s->x[i1] + s->x[i3])*4 \
> > + s->x[i2] *6; \
> > *dst = av_clip_int16(lrintf(res)); \
> > s->x[i0] = in; \
> > src += sstep; \
> > dst += dstep; \
> >
> > void ff_lowpass_filter(const struct FFLPFilterCoeffs *c, struct FFLPFilterState *s, int size, int16_t *src, int sstep, int16_t *dst, int dstep)
> > {
> > int i, j;
> > float in, res;
> >
> > for(i = 0; i < size; i += 4){
> > FILTER(0, 1, 2, 3);
> > FILTER(1, 2, 3, 0);
> > FILTER(2, 3, 0, 1);
> > FILTER(3, 0, 1, 2);
> > }
> > }
>
> please remove all unused variables (like 2 j)
> move variables into the loops where they are used when not used outside
>
> except these patch ok
looks like there's more generic implementation has appeared in nellymoser
encoder, so I'll commit this after my return if it is still needed then.
> [...]
> --
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> If a bugfix only changes things apparently unrelated to the bug with no
> further explanation, that is a good sign that the bugfix is wrong.
More information about the ffmpeg-devel
mailing list