[FFmpeg-devel] [PATCH] Unroll base64 decode loop.

Reimar Döffinger Reimar.Doeffinger at gmx.de
Sat Jan 21 12:45:09 CET 2012


Around 50% faster.
decode:       374139 -> 248852 decicycles
syntax check: 236955 -> 123854 decicycles

Signed-off-by: Reimar Döffinger <Reimar.Doeffinger at gmx.de>
---
 libavutil/base64.c |   49 ++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 36 insertions(+), 13 deletions(-)

diff --git a/libavutil/base64.c b/libavutil/base64.c
index 6eccd9c..5c65fa5 100644
--- a/libavutil/base64.c
+++ b/libavutil/base64.c
@@ -26,7 +26,6 @@
 
 #include "common.h"
 #include "base64.h"
-#include "avassert.h"
 #include "intreadwrite.h"
 
 /* ---------------- private code */
@@ -69,29 +68,53 @@ static const uint8_t map2[256] =
     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 };
 
+#define BASE64_DEC_STEP(i) \
+    bits = map2[in[i]]; \
+    if (bits & 0x80) \
+        goto out; \
+    v = (v << 6) + bits; \
+    if (i & 3) \
+        *dst++ = v >> (6 - 2 * (i & 3)); \
+
 int av_base64_decode(uint8_t *out, const char *in_str, int out_size)
 {
-    int i, v;
+    int v;
     uint8_t *dst = out;
     uint8_t *end = out + out_size;
     // no sign extension
     const uint8_t *in = in_str;
+    unsigned bits = 0xff;
 
     v = 0;
-    for (i = 0; ; i++) {
-        unsigned bits = map2[in[i]];
-        if (bits & 0x80)
-            return bits & 1 ? -1 : dst - out;
-        v = (v << 6) + bits;
-        if (i & 3) {
-            if (dst < end) {
-                *dst++ = v >> (6 - 2 * (i & 3));
-            }
+    while (end - dst > 2) {
+        BASE64_DEC_STEP(0)
+        BASE64_DEC_STEP(1)
+        BASE64_DEC_STEP(2)
+        BASE64_DEC_STEP(3)
+        in  += 4;
+    }
+    if (end - dst) {
+        BASE64_DEC_STEP(0)
+        BASE64_DEC_STEP(1)
+        if (end - dst) {
+            BASE64_DEC_STEP(2)
+            in++;
         }
+        in += 2;
+    }
+    while (1) {
+        BASE64_DEC_STEP(0)
+        in++;
+        BASE64_DEC_STEP(0)
+        in++;
+        BASE64_DEC_STEP(0)
+        in++;
+        BASE64_DEC_STEP(0)
+        in++;
     }
 
-    av_assert1(0);
-    return 0;
+out:
+    return bits & 1 ? -1 : dst - out;
 }
 
 /*****************************************************************************
-- 
1.7.8.3



More information about the ffmpeg-devel mailing list