diff --git a/libavutil/mathematics.c b/libavutil/mathematics.c index 6c2f6c04de..f9cf87da80 100644 --- a/libavutil/mathematics.c +++ b/libavutil/mathematics.c @@ -61,7 +61,13 @@ int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd){ int64_t r=0; av_assert2(c > 0); av_assert2(b >=0); - av_assert2((unsigned)rnd<=5 && rnd!=4); + av_assert2((unsigned)(rnd&~AV_ROUND_PASS_MINMAX)<=5 && (rnd&~AV_ROUND_PASS_MINMAX)!=4); + + if (rnd & AV_ROUND_PASS_MINMAX) { + if (a == INT64_MIN || a == INT64_MAX) + return a; + rnd -= AV_ROUND_PASS_MINMAX; + } if(a<0 && a != INT64_MIN) return -av_rescale_rnd(-a, b, c, rnd ^ ((rnd>>1)&1)); diff --git a/libavutil/mathematics.h b/libavutil/mathematics.h index 0021d523ef..479161e1fd 100644 --- a/libavutil/mathematics.h +++ b/libavutil/mathematics.h @@ -70,6 +70,7 @@ enum AVRounding { 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. + AV_ROUND_PASS_MINMAX = 8192, ///< Flag to pass INT64_MIN/MAX through instead of rescaling, this avoids special cases for AV_NOPTS_VALUE }; /** @@ -88,6 +89,9 @@ int64_t av_rescale(int64_t a, int64_t b, int64_t c) av_const; /** * Rescale a 64-bit integer with specified rounding. * A simple a*b/c isn't possible as it can overflow. + * + * @return rescaled value a or if AV_ROUND_PASS_MINMAX is set and a is + * INT64_MIN or INT64_MAX than a is passed through unchanged. */ int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding) av_const; @@ -98,6 +102,9 @@ int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const; /** * Rescale a 64-bit integer by 2 rational numbers with specified rounding. + * + * @return rescaled value a or if AV_ROUND_PASS_MINMAX is set and a is + * INT64_MIN or INT64_MAX than a is passed through unchanged. */ int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq, enum AVRounding) av_const;