aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMans Rullgard <mans@mansr.com>2012-08-11 01:15:19 +0100
committerMans Rullgard <mans@mansr.com>2012-08-13 01:03:10 +0100
commit6c4975eaafd7f8f91e81ad8d6be744a434241fd3 (patch)
tree9edb4f8cc534f15a876d417ab310468e43f26c1c
parent17c11cef9f99d31e31dd9176ee2f26bdf6e5d351 (diff)
downloadffmpeg-6c4975eaafd7f8f91e81ad8d6be744a434241fd3.tar.gz
libavutil: add saturating addition functions
Fixed-point audio codecs often use saturating arithmetic, and special instructions for these operations are common. Signed-off-by: Mans Rullgard <mans@mansr.com>
-rw-r--r--libavutil/arm/intmath.h15
-rw-r--r--libavutil/common.h30
2 files changed, 45 insertions, 0 deletions
diff --git a/libavutil/arm/intmath.h b/libavutil/arm/intmath.h
index ce73404b37..d5a343c95f 100644
--- a/libavutil/arm/intmath.h
+++ b/libavutil/arm/intmath.h
@@ -83,6 +83,21 @@ static av_always_inline av_const unsigned av_clip_uintp2_arm(int a, int p)
return x;
}
+#define av_sat_add32 av_sat_add32_arm
+static av_always_inline int av_sat_add32_arm(int a, int b)
+{
+ int r;
+ __asm__ ("qadd %0, %1, %2" : "=r"(r) : "r"(a), "r"(b));
+ return r;
+}
+
+#define av_sat_dadd32 av_sat_dadd32_arm
+static av_always_inline int av_sat_dadd32_arm(int a, int b)
+{
+ int r;
+ __asm__ ("qdadd %0, %1, %2" : "=r"(r) : "r"(a), "r"(b));
+ return r;
+}
#else /* HAVE_ARMV6 */
diff --git a/libavutil/common.h b/libavutil/common.h
index c99d858472..433e8e490a 100644
--- a/libavutil/common.h
+++ b/libavutil/common.h
@@ -182,6 +182,30 @@ static av_always_inline av_const unsigned av_clip_uintp2_c(int a, int p)
}
/**
+ * Add two signed 32-bit values with saturation.
+ *
+ * @param a one value
+ * @param b another value
+ * @return sum with signed saturation
+ */
+static av_always_inline int av_sat_add32_c(int a, int b)
+{
+ return av_clipl_int32((int64_t)a + b);
+}
+
+/**
+ * Add a doubled value to another value with saturation at both stages.
+ *
+ * @param a first value
+ * @param b value doubled and added to a
+ * @return sum 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));
+}
+
+/**
* Clip a float value into the amin-amax range.
* @param a value to clip
* @param amin minimum value of the clip range
@@ -387,6 +411,12 @@ static av_always_inline av_const int av_popcount64_c(uint64_t x)
#ifndef av_clip_uintp2
# define av_clip_uintp2 av_clip_uintp2_c
#endif
+#ifndef av_sat_add32
+# define av_sat_add32 av_sat_add32_c
+#endif
+#ifndef av_sat_dadd32
+# define av_sat_dadd32 av_sat_dadd32_c
+#endif
#ifndef av_clipf
# define av_clipf av_clipf_c
#endif