# HG changeset patch # User michael # Date 1095611934 0 # Node ID 8f605c66d1d4bc534db2dcd266e59ad4490ca17d # Parent c26038875ebc7e8cc36160c25349f40ba0037eb1 av_rescale with user specified rounding diff -r c26038875ebc -r 8f605c66d1d4 avcodec.h --- a/avcodec.h Sun Sep 19 14:43:09 2004 +0000 +++ b/avcodec.h Sun Sep 19 16:38:54 2004 +0000 @@ -230,6 +230,14 @@ 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 @@ 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 -r c26038875ebc -r 8f605c66d1d4 utils.c --- a/utils.c Sun Sep 19 14:43:09 2004 +0000 +++ b/utils.c Sun Sep 19 16:38:54 2004 +0000 @@ -822,25 +822,33 @@ 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 */