[FFmpeg-devel] [PATCH] Common ACELP routines (2/3) - filters

Vladimir Voroshilov voroshil
Thu Apr 24 19:07:15 CEST 2008


On Thu, Apr 24, 2008 at 10:13 AM, Michael Niedermayer <michaelni at gmx.at> wrote:
> On Thu, Apr 24, 2008 at 08:24:25AM +0700, Vladimir Voroshilov wrote:
>  > Michael Niedermayer wrote:
>  > > On Thu, Apr 24, 2008 at 02:15:51AM +0700, Vladimir Voroshilov wrote:
>  > > > Michael Niedermayer wrote:
>  > > [...]
>  > > > > > +        v=0;
>  > > > > > +        for(i=0; i<10; i++)
>  > > > > > +        {
>  > > > >
>  > > > > > +            /*  R(x):=ac_v[-k+x] */
>  > > > > > +            v += ac_v[n - pitch_delay_int - i    ] * ff_g729_interp_filter[i][    pitch_delay_frac];
>  > > > > > +            v = av_clip(v, -0x40000000, 0x3fffffff); //v += R(n-i)*ff_g729_interp_filter(t+3i)
>  > > > > > +            v += ac_v[n - pitch_delay_int + i + 1] * ff_g729_interp_filter[i][3 - pitch_delay_frac];
>  > > > > > +            v = av_clip(v, -0x40000000, 0x3fffffff); //v += R(n+i+1)*ff_g729_interp_filter(3-t+3i)
>  > > > >
>  > > > > The cliping is incorrect for generic code. Also i doubt g729 really needs
>  > > > > it. What happens without that cliping or at least with it at the end, just
>  > > > > before storing in ac_v?
>  > > >
>  > > > Removing those line breaks OVERFLOW test (regardless of clipping outside loop),
>  > > > significantly reduces PSNR from bitexact's 99,99 to 18,54 without outside
>  > > > clipping and to 26,01 with it.
>  > >
>  > > What is the OVERFLOW test anyway? Is this a normal valid bitstream generated
>  > > from a pcm wave? Or some sythetic overflow excercise which cannot be generated
>  > > by any input wave?
>  > > (If you dont know you can test it by encoding the wave from overflow to see if
>  > > there are still any overflows happening from the resulting bitstream)
>  >
>  > Completely synthetic test, imho. ITU does not provide any PCM stream related to
>  > it. I don't know is it possible to generate such stream from regular PCM or not.
>
>  So a reencoded version of that synthetic vector is not affected by the
>  existence of these checks?

Yes. Reencoded file passes all tests even with removed clipping.

>  > > > +        filter_data[10+n] = out[n] = sum;
>  > >
>  > > This duplicated storeage is unacceptable.
>  >
>  > First for all assigned to filter data values will be used in loop later.
>  > Thus filter_data can not be eliminated.
>  > I can't use "out" instead of it due to necessary 10 items
>  > with data from previous subframe at top).
>  > Extending out with 10 items at top will require another temporary buffer
>  > one memcpy somewhere later (because i will not be able to use output buffer
>  > directly).
>
>  The double write is definitly useless after the first 10 iterations as
>  after that you can just work in the out buffer.
>
>  foobar_filter(filter_data+10, 10);
>  memcpy(out, filter_data+10, 10);
>  foobar_filter(out+10, N-10);
>
>  should work fine and will for large N (dunno how large it is, so maybe
>  this isnt worth it ...) be faster. Also it allows filter_data to be smaller.

... and code will look like :(

if(foobar_filter(filter_data+10, 10)!=OVERFLOW)
{
  memcpy(out, filter_data+10, 10);
  if(foobar_filter(out+10, N-10)==OVERFLOW)
  {
     for(i=0;i<len;i++) out>>=2;
     foobar_filter(filter_data+10, 10);
     memcpy(out, filter_data+10, 10);
     foobar_filter(out+10, N-10);
  }
}
else
{
     for(i=0;i<len;i++) out>>=2;
     foobar_filter(filter_data+10, 10);
     memcpy(out, filter_data+10, 10);
     foobar_filter(out+10, N-10);
}

>
>
>
>  >
>  > > > +    }
>  > > > +
>  > > > +    // Saving data for using in next subframe
>  > > > +    if(update_filter_data)
>  > > > +        memcpy(filter_data, filter_data + subframe_size, 10 * sizeof(int16_t));
>  > >
>  > > This design requires the memcpy to be duplicated.
>  >
>  > Don't see. Please explain.
>  > I can put this memcpy outside, but this will look like cosmetic
>  > change since the overall count of memcpy will be the same.
>
>  +        if(ff_acelp_lp_synthesis_filter(
>  +                &lp[i][0],
>  +                ctx->exc  + i * ctx->subframe_size,
>  +                out_frame + i * ctx->subframe_size,
>  +                ctx->syn_filter_data,
>  +                ctx->subframe_size,
>  +                0))
>  +            //Overflow occured, downscale excitation signal...
>  +            for(j=0; j<2*MAX_SUBFRAME_SIZE+PITCH_LAG_MAX+INTERPOL_LEN; j++)
>  +                ctx->exc_base[j] >>= 2;
>  +
>
> +            ff_acelp_lp_synthesis_filter(
>  +                    &lp[i][0],
>  +                    ctx->exc  + i * ctx->subframe_size,
>  +                    out_frame + i * ctx->subframe_size,
>  +                    ctx->syn_filter_data,
>  +                    ctx->subframe_size,
>  +                    1);
>
>  Above unconditionally executes the code twice. If you skip the second
>  one (like the indention suggests) it will fail due to the missing
>  update_filter_data based code IMHO

Yes it does. Indentation was wrong.
First pass checks for overflow, second - does real filtering.
Note also that G.729D looks like:

if(filter(exc,out,0))
   ecx[*]>>=2

if(format==G729D)
{
  make_new_exc(exc,new_exc)
  filter(new_exc, out,1)
}else
  filter(exc,out,1)


>
>  [...]
>
>  --
>  Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
>  I do not agree with what you have to say, but I'll defend to the death your
>  right to say it. -- Voltaire
>
> -----BEGIN PGP SIGNATURE-----
>  Version: GnuPG v1.4.6 (GNU/Linux)
>
>  iD8DBQFID/q6YR7HhwQLD6sRApGdAJ9KrE71M5pm7FSGF9gewrjh5qENdACdG82d
>  lDTAS5B5ipgiFOJgIeI78ss=
>  =/yBq
>  -----END PGP SIGNATURE-----
>
> _______________________________________________
>  ffmpeg-devel mailing list
>  ffmpeg-devel at mplayerhq.hu
>  https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-devel
>



-- 
Regards,
Vladimir Voroshilov mailto:voroshil at gmail.com
JID: voroshil at gmail.com, voroshil at jabber.ru
ICQ: 95587719




More information about the ffmpeg-devel mailing list