diff options
author | Mike Melanson <mike@multimedia.cx> | 2006-08-02 07:12:57 +0000 |
---|---|---|
committer | Mike Melanson <mike@multimedia.cx> | 2006-08-02 07:12:57 +0000 |
commit | d5afac816ee0c00832622a5fb403dbb9dab5ccc8 (patch) | |
tree | cbab03ed9fcefe44d9f504494de8b946efeb6622 /src/libffmpeg/libavutil/mathematics.c | |
parent | a70def82fe95a3847c2cfe8c0df475d0dbec1281 (diff) | |
download | xine-lib-d5afac816ee0c00832622a5fb403dbb9dab5ccc8.tar.gz xine-lib-d5afac816ee0c00832622a5fb403dbb9dab5ccc8.tar.bz2 |
sync FFmpeg tree
CVS patchset: 8149
CVS date: 2006/08/02 07:12:57
Diffstat (limited to 'src/libffmpeg/libavutil/mathematics.c')
-rw-r--r-- | src/libffmpeg/libavutil/mathematics.c | 77 |
1 files changed, 65 insertions, 12 deletions
diff --git a/src/libffmpeg/libavutil/mathematics.c b/src/libffmpeg/libavutil/mathematics.c index aa3fd74e0..951324e99 100644 --- a/src/libffmpeg/libavutil/mathematics.c +++ b/src/libffmpeg/libavutil/mathematics.c @@ -13,16 +13,15 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - + /** * @file mathematics.c * Miscellaneous math routines and tables. */ #include "common.h" -#include "integer.h" #include "mathematics.h" const uint8_t ff_sqrt_tab[128]={ @@ -49,14 +48,13 @@ int64_t ff_gcd(int64_t a, int64_t b){ } int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd){ - AVInteger ai; int64_t r=0; assert(c > 0); assert(b >=0); assert(rnd >=0 && rnd<=5 && rnd!=4); - - if(a<0 && a != INT64_MIN) return -av_rescale_rnd(-a, b, c, rnd ^ ((rnd>>1)&1)); - + + if(a<0 && a != INT64_MIN) return -av_rescale_rnd(-a, b, c, rnd ^ ((rnd>>1)&1)); + if(rnd==AV_ROUND_NEAR_INF) r= c/2; else if(rnd&1) r= c-1; @@ -65,12 +63,40 @@ int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd){ return (a * b + r)/c; else return a/c*b + (a%c*b + r)/c; + }else{ +#if 1 + uint64_t a0= a&0xFFFFFFFF; + uint64_t a1= a>>32; + uint64_t b0= b&0xFFFFFFFF; + uint64_t b1= b>>32; + uint64_t t1= a0*b1 + a1*b0; + uint64_t t1a= t1<<32; + int i; + + a0 = a0*b0 + t1a; + a1 = a1*b1 + (t1>>32) + (a0<t1a); + a0 += r; + a1 += a0<r; + + for(i=63; i>=0; i--){ +// int o= a1 & 0x8000000000000000ULL; + a1+= a1 + ((a0>>i)&1); + t1+=t1; + if(/*o || */c <= a1){ + a1 -= c; + t1++; + } + } + return t1; + } +#else + AVInteger ai; + ai= av_mul_i(av_int2i(a), av_int2i(b)); + ai= av_add_i(ai, av_int2i(r)); + + return av_i2int(av_div_i(ai, av_int2i(c))); } - - ai= av_mul_i(av_int2i(a), av_int2i(b)); - ai= av_add_i(ai, av_int2i(r)); - - return av_i2int(av_div_i(ai, av_int2i(c))); +#endif } int64_t av_rescale(int64_t a, int64_t b, int64_t c){ @@ -82,3 +108,30 @@ int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq){ int64_t c= cq.num * (int64_t)bq.den; return av_rescale_rnd(a, b, c, AV_ROUND_NEAR_INF); } +#if 0 +#include "integer.h" +#undef printf +main(){ + int64_t a,b,c,d,e; + + for(a=7; a<(1LL<<62); a+=a/3+1){ + for(b=3; b<(1LL<<62); b+=b/4+1){ + for(c=9; c<(1LL<<62); c+=(c*2)/5+3){ + int64_t r= c/2; + AVInteger ai; + ai= av_mul_i(av_int2i(a), av_int2i(b)); + ai= av_add_i(ai, av_int2i(r)); + + d= av_i2int(av_div_i(ai, av_int2i(c))); + + e= av_rescale(a,b,c); + + if((double)a * (double)b / (double)c > (1LL<<63)) + continue; + + if(d!=e) printf("%Ld*%Ld/%Ld= %Ld=%Ld\n", a, b, c, d, e); + } + } + } +} +#endif |