From 9b45bcf713e0bc30fff7d1e6c2facb539c27ec28 Mon Sep 17 00:00:00 2001 From: Andrew D'Addesio Date: Sat, 2 Dec 2017 11:36:24 -0600 Subject: [PATCH] libavutil: Add saturating subtraction functions Add av_sat_sub32 and av_sat_dsub32 as the subtraction analogues to av_sat_add32/av_sat_dadd32. Also clarify the formulas for dadd32/dsub32. Signed-off-by: Andrew D'Addesio --- libavutil/arm/intmath.h | 16 ++++++++++++++++ libavutil/common.h | 32 +++++++++++++++++++++++++++++++- libavutil/version.h | 2 +- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/libavutil/arm/intmath.h b/libavutil/arm/intmath.h index 65e42c5733..5311a7d52b 100644 --- a/libavutil/arm/intmath.h +++ b/libavutil/arm/intmath.h @@ -94,6 +94,22 @@ static av_always_inline int av_sat_dadd32_arm(int a, int b) return r; } +#define av_sat_sub32 av_sat_sub32_arm +static av_always_inline int av_sat_sub32_arm(int a, int b) +{ + int r; + __asm__ ("qsub %0, %1, %2" : "=r"(r) : "r"(a), "r"(b)); + return r; +} + +#define av_sat_dsub32 av_sat_dsub32_arm +static av_always_inline int av_sat_dsub32_arm(int a, int b) +{ + int r; + __asm__ ("qdsub %0, %1, %2" : "=r"(r) : "r"(a), "r"(b)); + return r; +} + #endif /* HAVE_ARMV6_INLINE */ #if HAVE_ASM_MOD_Q diff --git a/libavutil/common.h b/libavutil/common.h index 8142b31fdb..5e0382827b 100644 --- a/libavutil/common.h +++ b/libavutil/common.h @@ -260,13 +260,37 @@ static av_always_inline int av_sat_add32_c(int a, int b) * * @param a first value * @param b value doubled and added to a - * @return sum with signed saturation + * @return sum sat(a + sat(2*b)) with signed saturation */ static av_always_inline int av_sat_dadd32_c(int a, int b) { return av_sat_add32(a, av_sat_add32(b, b)); } +/** + * Subtract two signed 32-bit values with saturation. + * + * @param a one value + * @param b another value + * @return difference with signed saturation + */ +static av_always_inline int av_sat_sub32_c(int a, int b) +{ + return av_clipl_int32((int64_t)a - b); +} + +/** + * Subtract a doubled value from another value with saturation at both stages. + * + * @param a first value + * @param b value doubled and subtracted from a + * @return difference sat(a - sat(2*b)) with signed saturation + */ +static av_always_inline int av_sat_dsub32_c(int a, int b) +{ + return av_sat_sub32(a, av_sat_add32(b, b)); +} + /** * Clip a float value into the amin-amax range. * @param a value to clip @@ -513,6 +537,12 @@ static av_always_inline av_const int av_parity_c(uint32_t v) #ifndef av_sat_dadd32 # define av_sat_dadd32 av_sat_dadd32_c #endif +#ifndef av_sat_sub32 +# define av_sat_sub32 av_sat_sub32_c +#endif +#ifndef av_sat_dsub32 +# define av_sat_dsub32 av_sat_dsub32_c +#endif #ifndef av_clipf # define av_clipf av_clipf_c #endif diff --git a/libavutil/version.h b/libavutil/version.h index 285d2f1cf9..498b5d8414 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 56 -#define LIBAVUTIL_VERSION_MINOR 4 +#define LIBAVUTIL_VERSION_MINOR 5 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \