[Ffmpeg-devel] [PATCH] some lzo optimizations and test code

Reimar Döffinger Reimar.Doeffinger
Sat Jan 27 12:56:38 CET 2007


Hello,
attached code avoids checks for input buffer end where not needed due to
padding (up to 5% speedup when decompressing e.g. my mplayer binary, 85
bytes smaller code size) and adds test code.
It might (did not think that properly about it) require the input buffer
to be padded a bit more to avoid crashes on invalid data, but it is not
above FF_INPUT_BUFFER_PADDING_SIZE.
I would apply the two parts separately of course.
Does it look fine to you?
And any comments about moving it to libavutil? It is not used anywhere
else in ffmpeg yet, though it might be used in the matroska demuxer in
the future and would allow to reduce the lzo dependency in MPlayer.

Greetings,
Reimar D?ffinger
-------------- next part --------------
Index: libavcodec/lzo.c
===================================================================
--- libavcodec/lzo.c	(revision 7718)
+++ libavcodec/lzo.c	(working copy)
@@ -26,7 +26,7 @@
 
 //! define if we may write up to 12 bytes beyond the output buffer
 #define OUTBUF_PADDED 1
-//! define if we may read up to 4 bytes beyond the input buffer
+//! define if we may read up to 8 bytes beyond the input buffer
 #define INBUF_PADDED 1
 typedef struct LZOContext {
     uint8_t *in, *in_end;
@@ -45,6 +45,12 @@
     return 1;
 }
 
+#ifdef INBUF_PADDED
+#define GETB(c) (*(c).in++)
+#else
+#define GETB(c) get_byte(&(c))
+#endif
+
 /**
  * \brief decode a length value in the coding used by lzo
  * \param x previous byte value
@@ -170,10 +176,10 @@
     c.out = c.out_start = out;
     c.out_end = (uint8_t *)out + * outlen;
     c.error = 0;
-    x = get_byte(&c);
+    x = GETB(c);
     if (x > 17) {
         copy(&c, x - 17);
-        x = get_byte(&c);
+        x = GETB(c);
         if (x < 16) c.error |= LZO_ERROR;
     }
     while (!c.error) {
@@ -181,16 +187,16 @@
         if (x >> 4) {
             if (x >> 6) {
                 cnt = (x >> 5) - 1;
-                back = (get_byte(&c) << 3) + ((x >> 2) & 7) + 1;
+                back = (GETB(c) << 3) + ((x >> 2) & 7) + 1;
             } else if (x >> 5) {
                 cnt = get_len(&c, x, 31);
-                x = get_byte(&c);
-                back = (get_byte(&c) << 6) + (x >> 2) + 1;
+                x = GETB(c);
+                back = (GETB(c) << 6) + (x >> 2) + 1;
             } else {
                 cnt = get_len(&c, x, 7);
                 back = (1 << 14) + ((x & 8) << 11);
-                x = get_byte(&c);
-                back += (get_byte(&c) << 6) + (x >> 2);
+                x = GETB(c);
+                back += (GETB(c) << 6) + (x >> 2);
                 if (back == (1 << 14)) {
                     if (cnt != 1)
                         c.error |= LZO_ERROR;
@@ -202,15 +208,15 @@
             case COPY:
                 cnt = get_len(&c, x, 15);
                 copy(&c, cnt + 3);
-                x = get_byte(&c);
+                x = GETB(c);
                 if (x >> 4)
                     continue;
                 cnt = 1;
-                back = (1 << 11) + (get_byte(&c) << 2) + (x >> 2) + 1;
+                back = (1 << 11) + (GETB(c) << 2) + (x >> 2) + 1;
                 break;
             case BACKPTR:
                 cnt = 0;
-                back = (get_byte(&c) << 2) + (x >> 2) + 1;
+                back = (GETB(c) << 2) + (x >> 2) + 1;
                 break;
         }
         copy_backptr(&c, back, cnt + 2);
@@ -218,9 +224,40 @@
         state = cnt ? BACKPTR : COPY;
         if (cnt)
             copy(&c, cnt);
-        x = get_byte(&c);
+        x = GETB(c);
     }
     *inlen = c.in_end - c.in;
     *outlen = c.out_end - c.out;
     return c.error;
 }
+
+#ifdef TEST
+#include <stdio.h>
+#include <lzo/lzo1x.h>
+#include "log.h"
+#define MAXSZ (10*1024*1024)
+int main(int argc, char *argv[]) {
+    FILE *in = fopen(argv[1], "rb");
+    uint8_t *orig = av_malloc(MAXSZ + 16);
+    uint8_t *comp = av_malloc(2*MAXSZ + 16);
+    uint8_t *decomp = av_malloc(MAXSZ + 16);
+    size_t s = fread(orig, 1, MAXSZ, in);
+    lzo_uint clen = 0;
+    long tmp[LZO1X_MEM_COMPRESS];
+    int inlen, outlen;
+    int i;
+    av_log_level = AV_LOG_DEBUG;
+    lzo1x_999_compress(orig, s, comp, &clen, tmp);
+    for (i = 0; i < 300; i++) {
+START_TIMER
+        inlen = clen; outlen = MAXSZ;
+        lzo1x_decode(decomp, &outlen, comp, &inlen);
+STOP_TIMER("lzod")
+    }
+    if (memcmp(orig, decomp, s))
+        av_log(NULL, AV_LOG_ERROR, "decompression failed\n");
+    else
+        av_log(NULL, AV_LOG_ERROR, "decompression ok\n");
+    return 0;
+}
+#endif



More information about the ffmpeg-devel mailing list