aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2004-05-04 02:58:30 +0000
committerMichael Niedermayer <michaelni@gmx.at>2004-05-04 02:58:30 +0000
commit4c263142c5da89745fb956b3c5738f257c873532 (patch)
tree4a1f814ecd841f90eb1fd0da514598194cfe7ee1 /libavcodec
parent29adde838c244b59ea03f81cb8625deac5bf3cd6 (diff)
downloadffmpeg-4c263142c5da89745fb956b3c5738f257c873532.tar.gz
use AVInteger in av_rescale() so it can finally do 64*64/64 instead of just 64*32/32
Originally committed as revision 3106 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/avcodec.h4
-rw-r--r--libavcodec/utils.c26
2 files changed, 17 insertions, 13 deletions
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 678ae5f7ae..6738293f50 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -17,7 +17,7 @@ extern "C" {
#define FFMPEG_VERSION_INT 0x000408
#define FFMPEG_VERSION "0.4.8"
-#define LIBAVCODEC_BUILD 4711
+#define LIBAVCODEC_BUILD 4712
#define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT
#define LIBAVCODEC_VERSION FFMPEG_VERSION
@@ -1986,7 +1986,7 @@ int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max)
* rescale a 64bit integer.
* a simple a*b/c isnt possible as it can overflow
*/
-int64_t av_rescale(int64_t a, int b, int c);
+int64_t av_rescale(int64_t a, int64_t b, int64_t c);
/**
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 6998f77223..d08c630317 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -27,7 +27,9 @@
#include "avcodec.h"
#include "dsputil.h"
#include "mpegvideo.h"
+#include "integer.h"
#include <stdarg.h>
+#include <limits.h>
static void avcodec_default_free_buffers(AVCodecContext *s);
@@ -816,23 +818,25 @@ int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max)
return exact;
}
-int64_t av_rescale(int64_t a, int b, int c){
- uint64_t h, l;
+int64_t av_rescale(int64_t a, int64_t b, int64_t c){
+ AVInteger ai, ci;
assert(c > 0);
assert(b >=0);
if(a<0) return -av_rescale(-a, b, c);
- h= a>>32;
- if(h==0) return a*b/c;
+ if(b<=INT_MAX && c<=INT_MAX){
+ if(a<=INT_MAX)
+ return (a * b + c/2)/c;
+ else
+ return a/c*b + (a%c*b + c/2)/c;
+ }
- l= a&0xFFFFFFFF;
- l *= b;
- h *= b;
-
- l += (h%c)<<32;
-
- return ((h/c)<<32) + l/c;
+ ai= av_mul_i(av_int2i(a), av_int2i(b));
+ ci= av_int2i(c);
+ ai= av_add_i(ai, av_shr_i(ci,1));
+
+ return av_i2int(av_div_i(ai, ci));
}
/* av_log API */