Re: [FFmpeg-devel] [PATCH 2/2] libavutil: Make changes in softfloat needed for fixed point aac decoder.
As I said in the comment of this patch and before in comments to review, I modified the code in the softfloat to be more usable in the implementation of fixed point aac decoder. Fixed point aac decoder was developed by using our float emulation and it was more convenient to change ffmpeg softfloat than to make changes in aac since softfloat is not used anywhere in ffmpeg currently. It is clear to me that maybe for the number that is power of two it is more convenient to use original way, but for other numbers it is basically the same. On the other hand there is one subtraction less in the implementation of this function if precision is used as argument. And at the end, basically, I do not have a problem with changing this function back to original if you want me to and comments above were just for the sake of discussion :) you can add a 2nd function if you feel the subtraction matters but there should be one with simple and a human understandable interface Ok. Than I'll leave the original function. I think it would bloat the code if I add basically the same function just because of a subtraction. Thanks, Nedeljko ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/2] libavutil: Make changes in softfloat needed for fixed point aac decoder.
+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 Ok, I'll rename the function. Should I leave the original div function in the code? [...] +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 = 0x7FFF; +} + +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 As I said in the comment of this patch and before in comments to review, I modified the code in the softfloat to be more usable in the implementation of fixed point aac decoder. Fixed point aac decoder was developed by using our float emulation and it was more convenient to change ffmpeg softfloat than to make changes in aac since softfloat is not used anywhere in ffmpeg currently. It is clear to me that maybe for the number that is power of two it is more convenient to use original way, but for other numbers it is basically the same. On the other hand there is one subtraction less in the implementation of this function if precision is used as argument. And at the end, basically, I do not have a problem with changing this function back to original if you want me to and comments above were just for the sake of discussion :) Thanks, Nedeljko ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/2] libavutil: Make changes in softfloat needed for fixed point aac decoder.
On Wed, Apr 22, 2015 at 01:15:56PM +, Nedeljko Babic wrote: +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 Ok, I'll rename the function. Should I leave the original div function in the code? there should be an exact divide function left in there, yes [...] +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 = 0x7FFF; +} + +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 As I said in the comment of this patch and before in comments to review, I modified the code in the softfloat to be more usable in the implementation of fixed point aac decoder. Fixed point aac decoder was developed by using our float emulation and it was more convenient to change ffmpeg softfloat than to make changes in aac since softfloat is not used anywhere in ffmpeg currently. It is clear to me that maybe for the number that is power of two it is more convenient to use original way, but for other numbers it is basically the same. On the other hand there is one subtraction less in the implementation of this function if precision is used as argument. And at the end, basically, I do not have a problem with changing this function back to original if you want me to and comments above were just for the sake of discussion :) you can add a 2nd function if you feel the subtraction matters but there should be one with simple and a human understandable interface [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB During times of universal deceit, telling the truth becomes a revolutionary act. -- George Orwell signature.asc Description: Digital signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/2] libavutil: Make changes in softfloat needed for fixed point aac decoder.
-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){ elsereturn a.mant - (b.mant t); } +static inline av_const int av_gt_sf(SoftFloat a, SoftFloat b) +{ +int t= a.exp - b.exp; +if(t0) return (a.mant (-t)) b.mant ; +elsereturn 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.mantt ), 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 - 0x2000) 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 = 0x7FFF; +} + +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 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/2] libavutil: Make changes in softfloat needed for fixed point aac decoder.
On Mon, Apr 20, 2015 at 01:33:16PM +, 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){ elsereturn a.mant - (b.mant t); } +static inline av_const int av_gt_sf(SoftFloat a, SoftFloat b) +{ +int t= a.exp - b.exp; +if(t0) return (a.mant (-t)) b.mant ; +elsereturn 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.mantt ), 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 - 0x2000) 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 = 0x7FFF; +} + +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 signature.asc Description: Digital signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/2] libavutil: Make changes in softfloat needed for fixed point aac decoder.
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; i100; 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; j1000; 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 = { 0x2000, 0}; +static const SoftFloat FLOAT_1 = { 0x2000, 1}; +static const SoftFloat FLOAT_EPSILON= { 0x29F16B12, -16}; +static const SoftFloat FLOAT_1584893192 = { 0x32B771ED, 1}; +static const SoftFloat FLOAT_10 = { 0x30D4, 17}; +static const SoftFloat FLOAT_099= { 0x3BCE, 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){ elsereturn a.mant - (b.mant t); } +static inline av_const int av_gt_sf(SoftFloat a, SoftFloat b) +{ +int t= a.exp - b.exp; +if(t0) return (a.mant (-t)) b.mant ; +elsereturn 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.mantt ), 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 - 0x2000) 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