[FFmpeg-devel] [PATCH] avcodec/utils/avpriv_find_start_code: optimization. If HAVE_FAST_UNALIGNED is true, handle "1 + sizeof(long)" bytes per step.

zhaoxiu.zeng zhaoxiu.zeng at gmail.com
Thu Jan 1 03:13:58 CET 2015


 libavcodec/utils.c | 68 ++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 56 insertions(+), 12 deletions(-)

diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 1ec5cae..14a43e2 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -3772,30 +3772,74 @@ const uint8_t *avpriv_find_start_code(const uint8_t *av_restrict p,
                                       uint32_t *av_restrict state)
 {
     int i;
+    uint32_t stat;
 
     av_assert0(p <= end);
     if (p >= end)
         return end;
 
+    stat = *state;
     for (i = 0; i < 3; i++) {
-        uint32_t tmp = *state << 8;
-        *state = tmp + *(p++);
-        if (tmp == 0x100 || p == end)
+        uint32_t tmp = stat << 8;
+        stat = tmp + *(p++);
+        if (tmp == 0x100 || p == end) {
+            *state = stat;
             return p;
+        }
     }
 
-    while (p < end) {
-        if      (p[-1] > 1      ) p += 3;
-        else if (p[-2]          ) p += 2;
-        else if (p[-3]|(p[-1]-1)) p++;
-        else {
+#if HAVE_FAST_UNALIGNED
+#if HAVE_FAST_64BIT
+    for (; p + 6 <= end; p += 9) {
+        uint64_t t = AV_RN64A(p - 2);
+        if (!((t - 0x0100010001000101ULL) & ~(t | 0x7fff7fff7fff7f7fULL)))
+            continue;
+#else
+    for (; p + 2 <= end; p += 5) {
+        uint32_t t = AV_RN32A(p - 2);
+        if (!((t - 0x01000101U) & ~(t | 0x7fff7f7fU)))
+            continue;
+#endif
+        /* find the first zero byte in t */
+#if HAVE_BIGENDIAN
+        while (t >> (sizeof(t) * 8 - 8)) {
+            t <<= 8;
+            p++;
+        }
+#else
+        while (t & 0xff) {
+            t >>= 8;
+            p++;
+        }
+#endif
+        /* the first zero is p[-2], goto the end of continuous zero */
+        for (;;) {
+            if (p >= end)
+                goto _out;
+            if (p[-1])
+                break;
             p++;
-            break;
         }
+        if (p[-3] == 0 && /*p[-2] == 0 &&*/ p[-1] == 1) {
+            *state = 0x100 + *(p++);
+            return p;
+        }
+        p -= sizeof(t) - 1;
     }
+#endif
 
-    p = FFMIN(p, end) - 4;
-    *state = AV_RB32(p);
+    while (p < end) {
+        if      (p[-1] > 1 ) p += 3;
+        else if (p[-2]     ) p += 2 + p[-1];
+        else if (p[-3]     ) p += 1 + p[-1] * 2;
+        else if (p[-1] != 1) p += 1;
+        else {
+            *state = 0x100 + *(p++);
+            return p;
+        }
+    }
 
-    return p + 4;
+_out:
+    *state = AV_RB32(end - 4);
+    return end;
 }



More information about the ffmpeg-devel mailing list