[FFmpeg-devel] [PATCH 2/2] libavutil: Make changes in softfloat needed for fixed point aac decoder.
Michael Niedermayer
michaelni at gmx.at
Mon Apr 20 16:48:26 CEST 2015
On Mon, Apr 20, 2015 at 01:33:16PM +0000, Nedeljko Babic wrote:
>
> >> -static av_const SoftFloat av_div_sf(SoftFloat a, SoftFloat b){
> >> - a.exp -= b.exp+1;
> >> - a.mant = ((int64_t)a.mant<<(ONE_BITS+1)) / b.mant;
> >> - return av_normalize1_sf(a);
> >> + return av_normalize1_sf((SoftFloat){a.mant, --a.exp});
> > ^^^^^^
> > a.exp - 1
>
> Ok.
> I will change this.
>
> >
> >> }
> >>
> >> static inline av_const int av_cmp_sf(SoftFloat a, SoftFloat b){
> >> @@ -102,11 +101,18 @@ static inline av_const int av_cmp_sf(SoftFloat a, SoftFloat b){
> >> else return a.mant - (b.mant >> t);
> >> }
> >>
> >> +static inline av_const int av_gt_sf(SoftFloat a, SoftFloat b)
> >> +{
> >> + int t= a.exp - b.exp;
> >> + if(t<0) return (a.mant >> (-t)) > b.mant ;
> >> + else return a.mant > (b.mant >> t);
> >> +}
> >> +
> >> static inline av_const SoftFloat av_add_sf(SoftFloat a, SoftFloat b){
> >> int t= a.exp - b.exp;
> >> - if (t <-31) return b;
> >> - else if (t < 0) return av_normalize1_sf((SoftFloat){b.mant + (a.mant >> (-t)), b.exp});
> >> - else if (t < 32) return av_normalize1_sf((SoftFloat){a.mant + (b.mant >> t ), a.exp});
> >> + if (t <=-31) return b;
> >> + else if (t < 0) return av_normalize_sf(av_normalize1_sf((SoftFloat){ b.mant + (a.mant >> (-t)), b.exp}));
> >> + else if (t < 32) return av_normalize_sf(av_normalize1_sf((SoftFloat){ a.mant + (b.mant >> t ), a.exp}));
> >> else return a;
> >> }
> >>
> >> @@ -114,19 +120,146 @@ static inline av_const SoftFloat av_sub_sf(SoftFloat a, SoftFloat b){
> >> return av_add_sf(a, (SoftFloat){ -b.mant, b.exp});
> >> }
> >>
> >> -//FIXME sqrt, log, exp, pow, sin, cos
> >> +static inline av_const SoftFloat av_recip_sf(SoftFloat a)
> >> +{
> >> + int s = a.mant >> 31;
> >> +
> >> + a.exp = 1 - a.exp;
> >> + a.mant = (a.mant ^ s) - s;
> >> + a.mant = av_divtbl_sf[(a.mant - 0x20000000) >> 22];
> >> + a.mant = (a.mant ^ s) - s;
> >> +
> >> + return a;
> >> +}
> >> +
> >
> >> +static av_always_inline SoftFloat av_div_sf(SoftFloat a, SoftFloat b){
> >
> >missing documentation
>
> I'll add it.
>
> >is this exact ?
> >if not what are the gurantees to the user
> >
>
> On our tests
> For 80.3% of input values the output is exact
> For 19.2% of input values the error is one LSB bit of mantissa
> For 0.5% of input values the error is two LSB bits of mantissa
I think av_div_sf() should be exact, approximate
functions should have a clear and distinct name, be that
av_div_sf_approx() or whatever
[...]
> >
> >> + SoftFloat res;
> >> + SoftFloat iB, tmp;
> >> +
> >> + if (b.mant != 0)
> >> + {
> >> + iB = av_recip_sf(b);
> >> + /* Newton iteration to double precision */
> >> + tmp = av_sub_sf(FLOAT_1, av_mul_sf(b, iB));
> >> + iB = av_add_sf(iB, av_mul_sf(iB, tmp));
> >> + tmp = av_sub_sf(FLOAT_1, av_mul_sf(b, iB));
> >> + iB = av_add_sf(iB, av_mul_sf(iB, tmp));
> >> + tmp = av_sub_sf(FLOAT_1, av_mul_sf(b, iB));
> >> + iB = av_add_sf(iB, av_mul_sf(iB, tmp));
> >> + res = av_mul_sf(a, iB);
> >> + }
> >> + else
> >> + {
> >> + /* handle division-by-zero */
> >> + res.mant = 1;
> >> + res.exp = 0x7FFFFFFF;
> >> + }
> >> +
> >> + return res;
> >> +#endif
> >> +}
> >> +
> >> +//FIXME log, exp, pow
> >>
> >
> >> static inline av_const SoftFloat av_int2sf(int v, int frac_bits){
> >> - return av_normalize_sf((SoftFloat){v, ONE_BITS-frac_bits});
> >> + return av_normalize_sf((SoftFloat){v, frac_bits});
> >> }
> >
> >missing documentation
>
> I'll add it.
>
> >also please make sure that the parameters make some logic sense
> >and do not depend on the precission choosen by the implementation
> >
> >so a "1.0" shwould be generated from the same arguments no matter
> >what the precision used in the implementation is
>
> I am not sure I understand you on this.
>
> Basic implementation of this function is the same as in original except
> "ONE_BITS-frac_bits" is changed with "frac_bits".
> This was done since algorithm is adjusted to be usable in implementation
> of fixed point aac decoder.
the numbers are of the form x * 2^y
thus the interface to create 4.0 should be av_int2sf(1,2) not
int2sf(1,123)
The interface should be simple, logic and intuitive
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
He who knows, does not speak. He who speaks, does not know. -- Lao Tsu
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20150420/184b0c2f/attachment.asc>
More information about the ffmpeg-devel
mailing list