aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDale Curtis <dalecurtis@chromium.org>2020-04-30 15:16:31 -0700
committerMichael Niedermayer <michael@niedermayer.cc>2020-05-15 22:03:36 +0200
commita7e1af3cb10b7c914622deff3435bc200000eb65 (patch)
treef442957417076bb7a2266da0f7ecfd638783179d
parent2d8d554f15a7a27cfeca81467cc9341a86f784e2 (diff)
downloadffmpeg-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.h36
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