aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2004-09-19 16:38:54 +0000
committerMichael Niedermayer <michaelni@gmx.at>2004-09-19 16:38:54 +0000
commit1f0182250aede7baf92e8f7326560280ab7c3f46 (patch)
tree4b5ddae3b67fad0b83c52e0e44bd0628ef9fd383
parentaa25a462b691e7d156325cf07f853fd259aaf781 (diff)
downloadffmpeg-1f0182250aede7baf92e8f7326560280ab7c3f46.tar.gz
av_rescale with user specified rounding
Originally committed as revision 3481 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavcodec/avcodec.h15
-rw-r--r--libavcodec/utils.c24
2 files changed, 30 insertions, 9 deletions
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 10c06989e7..dc83bba064 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -230,6 +230,14 @@ enum Motion_Est_ID {
ME_X1
};
+enum AVRounding {
+ AV_ROUND_ZERO = 0, ///< round toward zero
+ AV_ROUND_INF = 1, ///< round away from zero
+ AV_ROUND_DOWN = 2, ///< round toward -infinity
+ AV_ROUND_UP = 3, ///< round toward +infinity
+ AV_ROUND_NEAR_INF = 5, ///< round to nearest and halfway cases away from zero
+};
+
typedef struct RcOverride{
int start_frame;
int end_frame;
@@ -2061,11 +2069,16 @@ char av_get_pict_type_char(int pict_type);
int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max);
/**
- * rescale a 64bit integer.
+ * rescale a 64bit integer with rounding to nearest.
* a simple a*b/c isnt possible as it can overflow
*/
int64_t av_rescale(int64_t a, int64_t b, int64_t c);
+/**
+ * rescale a 64bit integer with specified rounding.
+ * a simple a*b/c isnt possible as it can overflow
+ */
+int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding);
/**
* Interface for 0.5.0 version
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index a34a65db71..2790362fe6 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -822,25 +822,33 @@ int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max)
return den==0;
}
-int64_t av_rescale(int64_t a, int64_t b, int64_t c){
- AVInteger ai, ci;
+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) return -av_rescale(-a, b, c);
+ if(a<0) 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;
+
if(b<=INT_MAX && c<=INT_MAX){
if(a<=INT_MAX)
- return (a * b + c/2)/c;
+ return (a * b + r)/c;
else
- return a/c*b + (a%c*b + c/2)/c;
+ return a/c*b + (a%c*b + r)/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));
+ ai= av_add_i(ai, av_int2i(r));
- return av_i2int(av_div_i(ai, ci));
+ return av_i2int(av_div_i(ai, av_int2i(c)));
+}
+
+int64_t av_rescale(int64_t a, int64_t b, int64_t c){
+ return av_rescale_rnd(a, b, c, AV_ROUND_NEAR_INF);
}
/* av_log API */