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
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4