On Wed, Apr 15, 2015 at 03:14:07PM +0200, Nedeljko Babic wrote: > From: Djordje Pesut <djordje.pe...@imgtec.com> > > Functions for sqrt and sincos are added. > > Div function is improved. > > Some changes are made in order for code in softfloat to be usable in fixed aac > decoder code. > > This doesn't create any impact on current ffmpeg code since softfloat is > currently not in use and this way we don't need to make much changes in > implementation of aac fixed point decoder that uses this code. > > Softfloat tests are adjusted. > > Signed-off-by: Nedeljko Babic <nedeljko.ba...@imgtec.com> > --- > libavutil/softfloat.c | 6 +- > libavutil/softfloat.h | 167 +++++++++++++++++++++--- > libavutil/softfloat_tables.h | 294 > +++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 447 insertions(+), 20 deletions(-) > create mode 100644 libavutil/softfloat_tables.h > > diff --git a/libavutil/softfloat.c b/libavutil/softfloat.c > index bf9cfda..23de93d 100644 > --- a/libavutil/softfloat.c > +++ b/libavutil/softfloat.c > @@ -27,7 +27,7 @@ > #undef printf > > int main(void){ > - SoftFloat one= av_int2sf(1, 0); > + SoftFloat one= av_int2sf(1, 30); > SoftFloat sf1, sf2; > double d1, d2; > int i, j; > @@ -59,8 +59,8 @@ int main(void){ > > for(i= 0; i<100; i++){ > START_TIMER > - sf1= av_int2sf(i, 0); > - sf2= av_div_sf(av_int2sf(i, 2), av_int2sf(200, 3)); > + sf1= av_int2sf(i, 30); > + sf2= av_div_sf(av_int2sf(i, 28), av_int2sf(200, 27)); > for(j= 0; j<1000; j++){ > sf1= av_mul_sf(av_add_sf(sf1, one),sf2); > } > diff --git a/libavutil/softfloat.h b/libavutil/softfloat.h > index 654a31f..c3ab316 100644 > --- a/libavutil/softfloat.h > +++ b/libavutil/softfloat.h > @@ -25,6 +25,7 @@ > #include "common.h" > > #include "avassert.h" > +#include "softfloat_tables.h" > > #define MIN_EXP -126 > #define MAX_EXP 126 > @@ -35,6 +36,14 @@ typedef struct SoftFloat{ > int32_t exp; > }SoftFloat; > > +static const SoftFloat FLOAT_0 = { 0, 0}; > +static const SoftFloat FLOAT_05 = { 0x20000000, 0}; > +static const SoftFloat FLOAT_1 = { 0x20000000, 1}; > +static const SoftFloat FLOAT_EPSILON = { 0x29F16B12, -16}; > +static const SoftFloat FLOAT_1584893192 = { 0x32B771ED, 1}; > +static const SoftFloat FLOAT_100000 = { 0x30D40000, 17}; > +static const SoftFloat FLOAT_0999999 = { 0x3FFFFBCE, 0}; > + > static av_const SoftFloat av_normalize_sf(SoftFloat a){ > if(a.mant){ > #if 1 > @@ -83,17 +92,7 @@ static inline av_const SoftFloat av_mul_sf(SoftFloat a, > SoftFloat b){ > a.exp += b.exp; > av_assert2((int32_t)((a.mant * (int64_t)b.mant) >> ONE_BITS) == (a.mant > * (int64_t)b.mant) >> ONE_BITS); > a.mant = (a.mant * (int64_t)b.mant) >> ONE_BITS; > - return av_normalize1_sf(a); > -} > - > -/** > - * b has to be normalized and not zero. > - * @return Will not be more denormalized than a. > - */ > -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
> } > > 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 is this exact ? if not what are the gurantees to the user > +#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 also is it really an advantage to have this av_always_inline ? it looks a bit big for always inlining it > + 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 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 [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB DNS cache poisoning attacks, popular search engine, Google internet authority dont be evil, please
signature.asc
Description: Digital signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel