]> granicus.if.org Git - libvpx/commitdiff
Use divide by multiply in the ans writer.
authorAlex Converse <aconverse@google.com>
Tue, 28 Jun 2016 20:46:19 +0000 (13:46 -0700)
committerYaowu Xu <yaowu@google.com>
Fri, 21 Oct 2016 16:54:41 +0000 (09:54 -0700)
Change-Id: Ide4e9b3a605571ec41c265347217e103df8d0821

aom_dsp/answriter.h

index 298b25589b95e74c875b07fb9b60ce9a324cca10..370472ae7fb3cc226b9a2f292d63ba191948b834 100644 (file)
 #include "aom_dsp/ans.h"
 #include "aom_dsp/prob.h"
 #include "aom_ports/mem_ops.h"
+#include "av1/common/odintrin.h"
 
-#define ANS_DIV(dividend, divisor) ((dividend) / (divisor))
+#if RANS_PRECISION <= OD_DIVU_DMAX
+#define ANS_DIVREM(quotient, remainder, dividend, divisor) \
+  do {                                                     \
+    quotient = OD_DIVU_SMALL((dividend), (divisor));       \
+    remainder = (dividend) - (quotient) * (divisor);       \
+  } while (0)
+#else
+#define ANS_DIVREM(quotient, remainder, dividend, divisor) \
+  do {                                                     \
+    quotient = (dividend) / (divisor);                     \
+    remainder = (dividend) % (divisor);                    \
+  } while (0)
+#endif
+
+#define ANS_DIV8(dividend, divisor) OD_DIVU_SMALL((dividend), (divisor))
 
 #ifdef __cplusplus
 extern "C" {
@@ -72,9 +87,9 @@ static INLINE void uabs_write(struct AnsCoder *ans, int val, AnsP8 p0) {
     ans->state /= IO_BASE;
   }
   if (!val)
-    ans->state = ANS_DIV(ans->state * ANS_P8_PRECISION, p0);
+    ans->state = ANS_DIV8(ans->state * ANS_P8_PRECISION, p0);
   else
-    ans->state = ANS_DIV((ans->state + 1) * ANS_P8_PRECISION + p - 1, p) - 1;
+    ans->state = ANS_DIV8((ans->state + 1) * ANS_P8_PRECISION + p - 1, p) - 1;
 }
 
 struct rans_sym {
@@ -88,15 +103,17 @@ struct rans_sym {
 static INLINE void rans_write(struct AnsCoder *ans,
                               const struct rans_sym *const sym) {
   const aom_cdf_prob p = sym->prob;
+  unsigned quot, rem;
   while (ans->state >= L_BASE / RANS_PRECISION * IO_BASE * p) {
     ans->buf[ans->buf_offset++] = ans->state % IO_BASE;
     ans->state /= IO_BASE;
   }
-  ans->state =
-      (ans->state / p) * RANS_PRECISION + ans->state % p + sym->cum_prob;
+  ANS_DIVREM(quot, rem, ans->state, p);
+  ans->state = quot * RANS_PRECISION + rem + sym->cum_prob;
 }
 
-#undef ANS_DIV
+#undef ANS_DIV8
+#undef ANS_DIVREM
 #ifdef __cplusplus
 }  // extern "C"
 #endif  // __cplusplus