[Ffmpeg-devel] [PATCH] simple internal lzo decoder

Reimar Döffinger Reimar.Doeffinger
Sat Jan 14 16:21:44 CET 2006


Hi,
On Sat, Jan 14, 2006 at 02:37:59PM +0100, Diego Biurrun wrote:
> On Sat, Jan 14, 2006 at 02:07:30PM +0100, Reimar D?ffinger wrote:
> > liblzo lzo.c (lzo.c + patch)
> 
> What about minilzo, the one included in the MPlayer sources?

Seems to be the same as liblzo, it probably is even mostly the same
code.

> > only zeros, 56325B comp:
> > 8.89s 9.15s 8.48s
> > 
> > nwnmod, 2675408B comp:
> > 6.68s 12.32s 7.98s
> 
> What is nwnmod?  Since I suppose this is the common case, there still
> seems to be a bit of a performance gap to liblzo.

It is a module for Neverwinter Nights.
And yes, there is a performance gap, and it seems to be even bigger,
since I seem to have screwed up the last number it obviously should be
something around 9s.
Also instead of the last patch I'd like to propose the attached one,
although it is still a bit slower in this case (10.04s), it is much
faster for the other two cases:
only zeros: 1.20s
/dev/urandom: 1.71s
(though I guess the assembler version of the original LZO implementation
would still be faster :-) ).

Greetings,
Reimar D?ffinger
-------------- next part --------------
Index: libavcodec/lzo.c
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/libavcodec/lzo.c,v
retrieving revision 1.4
diff -u -r1.4 lzo.c
--- libavcodec/lzo.c	14 Jan 2006 14:59:11 -0000	1.4
+++ libavcodec/lzo.c	14 Jan 2006 15:04:43 -0000
@@ -17,12 +17,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "common.h"
+#include <string.h>
 #include "lzo.h"
 
 typedef struct LZOContext {
     uint8_t *in, *in_end;
-    uint8_t *out, *out_end;
-    int out_size;
+    uint8_t *out_start, *out, *out_end;
     int error;
 } LZOContext;
 
@@ -65,9 +65,9 @@
         cnt = c->out_end - c->out;
         c->error |= LZO_OUTPUT_FULL;
     }
-    do {
-        *c->out++ = *c->in++;
-    } while (--cnt);
+    memcpy(c->out, c->in, cnt);
+    c->in += cnt;
+    c->out += cnt;
 }
 
 /**
@@ -78,7 +78,7 @@
  * cnt > back is valid, this will copy the bytes we just copied.
  */
 static inline void copy_backptr(LZOContext *c, int back, int cnt) {
-    if (c->out - back < c->out_end - c->out_size) {
+    if (c->out - back < c->out_start) {
         c->error |= LZO_INVALID_BACKPTR;
         return;
     }
@@ -86,9 +86,20 @@
         cnt = c->out_end - c->out;
         c->error |= LZO_OUTPUT_FULL;
     }
-    do {
-        *c->out++ = c->out[-back];
-    } while (--cnt);
+    if (back == 1)
+        memset(c->out, c->out[-1], cnt);
+    else {
+        int blocklen = (cnt > back) ? back : cnt;
+        uint8_t *start = &c->out[-back];
+        while (cnt > blocklen) {
+           memcpy(c->out, start, blocklen);
+           c->out += blocklen;
+           cnt -= blocklen;
+           blocklen <<= 1;
+        }
+        memcpy(c->out, start, cnt);
+    }
+    c->out += cnt;
 }
 
 /**
@@ -105,9 +116,8 @@
     LZOContext c;
     c.in = in;
     c.in_end = in + *inlen;
-    c.out = out;
+    c.out = c.out_start = out;
     c.out_end = out + * outlen;
-    c.out_size = *outlen;
     c.error = 0;
     x = get_byte(&c);
     if (x > 17) {



More information about the ffmpeg-devel mailing list