[FFmpeg-devel] [PATCH 2/2] libavutil: Make changes in softfloat needed for fixed point aac decoder.
Nedeljko Babic
Nedeljko.Babic at imgtec.com
Mon Apr 20 15:33:16 CEST 2015
>> -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
>
> > +#if 0
>> + a.exp -= b.exp + 1;
>> + a.mant = ((int64_t)a.mant<<(ONE_BITS+1)) / b.mant;
>> + return av_normalize1_sf(a);
>> +#else
>
>enabing this breaks the tests
>
This is av_div_sf as it was before our changes.
I left it here in case someone wants to develop this function based on what it
was before changes.
Of course, it would be better if I just left code history to git...
Maybe it would be best if I just remove this.
>
>also is it really an advantage to have this av_always_inline ?
>it looks a bit big for always inlining it
>
I guess it depends on compiler and the system on which this will be used.
In any case I suppose that there will not be great performance loss if I remove
av_always_inline.
>
>> + 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.
Thanks,
Nedeljko
More information about the ffmpeg-devel
mailing list