[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