diff options
author | Dale Curtis <dalecurtis@chromium.org> | 2020-04-30 15:16:31 -0700 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2020-05-15 22:03:36 +0200 |
commit | a7e1af3cb10b7c914622deff3435bc200000eb65 (patch) | |
tree | f442957417076bb7a2266da0f7ecfd638783179d | |
parent | 2d8d554f15a7a27cfeca81467cc9341a86f784e2 (diff) | |
download | ffmpeg-a7e1af3cb10b7c914622deff3435bc200000eb65.tar.gz |
avutil/common: Add saturated add/sub operations for int64_t.
Many places are using their own custom code for handling overflow
around timestamps or other int64_t values. There are enough of these
now that having some common saturated math functions seems sound.
Signed-off-by: Dale Curtis <dalecurtis@chromium.org>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r-- | libavutil/common.h | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/libavutil/common.h b/libavutil/common.h index 142ff9abe7..7a774fc448 100644 --- a/libavutil/common.h +++ b/libavutil/common.h @@ -292,6 +292,36 @@ static av_always_inline int av_sat_dsub32_c(int a, int b) } /** + * Add two signed 64-bit values with saturation. + * + * @param a one value + * @param b another value + * @return sum with signed saturation + */ +static av_always_inline int64_t av_sat_add64_c(int64_t a, int64_t b) { + if (b >= 0 && a >= INT64_MAX - b) + return INT64_MAX; + if (b <= 0 && a <= INT64_MIN - b) + return INT64_MIN; + return a + b; +} + +/** + * Subtract two signed 64-bit values with saturation. + * + * @param a one value + * @param b another value + * @return difference with signed saturation + */ +static av_always_inline int64_t av_sat_sub64_c(int64_t a, int64_t b) { + if (b <= 0 && a >= INT64_MAX + b) + return INT64_MAX; + if (b >= 0 && a <= INT64_MIN + b) + return INT64_MIN; + return a - b; +} + +/** * Clip a float value into the amin-amax range. * @param a value to clip * @param amin minimum value of the clip range @@ -545,6 +575,12 @@ static av_always_inline av_const int av_parity_c(uint32_t v) #ifndef av_sat_dsub32 # define av_sat_dsub32 av_sat_dsub32_c #endif +#ifndef av_sat_add64 +# define av_sat_add64 av_sat_add64_c +#endif +#ifndef av_sat_sub64 +# define av_sat_sub64 av_sat_sub64_c +#endif #ifndef av_clipf # define av_clipf av_clipf_c #endif |