[MPlayer-dev-eng] [PATCH] LZO decompression in AVI files
Tilmann Bitterberg
transcode at tibit.org
Sun Oct 13 21:55:38 CEST 2002
Hi
Recently a feature was added to transcode[1] to encode video to
LZO[2] compressed AVIs. This is intended for intermediate lossless
storage (ie when grabbing from a v4l device)
MPlayer is my favourite movie player but had no support for
playing LZO compressed AVIs so I wrote a decoder for it.
The FOURCC is "LZO1", the compressed video can either be in
YV12/I420 or BGR24 format. The decoder will automatically detect
this and tell mplayer about it. The decoder is direct rendering
only.
The patch touches/adds the following files.
- configure: check for liblzo
- Makefile: add -lzo dependend on configure result
- etc/codecs.conf: definition of codec
- libmpcodecs/Makefile: build the codec file
- libmpcodecs/vd.c: hooks for vd_lzo
- libmpcodecs/vd_lzo.c: the main codec file (new).
Its quite impressive how fast and efficient the LZO compression
is. I encoded 1000 frames of some random stream in YV12 format
with no audio
173M test-lzo.avi
356M test-yuv4mpeg.avi
Thanks,
Tilmann
[1] http://www.theorie.physik.uni-goettingen.de/~ostreich/transcode/
pre/ChangeLog-0.6.2.20021010
[2] http://www.oberhumer.com/opensource/lzo/
--
Sometimes transcode changes or | Searchable
adds new features while your | mailing-list archives
are encoding. | http://itdp.de/transcode-users/
-- ThOe | http://itdp.de/transcode-devel/
-------------- next part --------------
diff -Nur -X dontdiff MPlayer-orig-cvs/main/Makefile MPlayer-cvs/main/Makefile
--- MPlayer-orig-cvs/main/Makefile Fri Oct 11 18:32:41 2002
+++ MPlayer-cvs/main/Makefile Fri Oct 11 18:42:49 2002
@@ -45,7 +45,7 @@
A_LIBS = $(ALSA_LIB) $(ARTS_LIB) $(NAS_LIB) $(MAD_LIB) $(VORBIS_LIB) $(FAAD_LIB) $(SGIAUDIO_LIB)
CODEC_LIBS = libmpcodecs/libmpcodecs.a mp3lib/libMP3.a liba52/liba52.a libmpeg2/libmpeg2.a $(AV_LIB) $(FAME_LIB)
-COMMON_LIBS = $(CODEC_LIBS) libaf/libaf.a libmpdemux/libmpdemux.a input/libinput.a postproc/libpostproc.a linux/libosdep.a $(LIB_LOADER) $(FREETYPE_LIB) $(A_LIBS) $(CSS_LIB) $(XVID_LIB) $(DECORE_LIB) $(TERMCAP_LIB) $(STREAMING_LIB) $(Z_LIB) $(GTK_LIBS) $(PNG_LIB) $(JPEG_LIB) $(GIF_LIB) $(CDPARANOIA_LIB) $(ARCH_LIB) -lm
+COMMON_LIBS = $(CODEC_LIBS) libaf/libaf.a libmpdemux/libmpdemux.a input/libinput.a postproc/libpostproc.a linux/libosdep.a $(LIB_LOADER) $(FREETYPE_LIB) $(A_LIBS) $(CSS_LIB) $(XVID_LIB) $(DECORE_LIB) $(TERMCAP_LIB) $(STREAMING_LIB) $(Z_LIB) $(GTK_LIBS) $(PNG_LIB) $(JPEG_LIB) $(LZO_LIB) $(GIF_LIB) $(CDPARANOIA_LIB) $(ARCH_LIB) -lm
ifeq ($(VIDIX),yes)
MISC_LIBS += -Llibdha -ldha vidix/libvidix.a
endif
diff -Nur -X dontdiff MPlayer-orig-cvs/main/configure MPlayer-cvs/main/configure
--- MPlayer-orig-cvs/main/configure Fri Oct 11 18:32:42 2002
+++ MPlayer-cvs/main/configure Fri Oct 11 18:40:52 2002
@@ -155,6 +155,7 @@
--enable-gif enable gif89a output support [autodetect]
--enable-png enable png input/output support [autodetect]
--enable-jpeg enable jpeg input/output support [autodetect]
+ --enable-lzo enable lzo input support [autodetect]
--disable-win32 disable Win32 DLL support [autodetect]
--disable-dshow disable Win32/DirectShow support [autodetect]
--disable-xanim disable XAnim DLL support [autodetect]
@@ -949,6 +950,7 @@
_rtc=auto
_ossaudio=auto
_arts=auto
+_lzo=auto
_mad=auto
_vorbis=auto
_faad=auto
@@ -1073,6 +1075,8 @@
--disable-arts) _arts=no ;;
--enable-mad) _mad=yes ;;
--disable-mad) _mad=no ;;
+ --enable-lzo) _lzo=yes ;;
+ --disable-lzo) _lzo=no ;;
--enable-vorbis) _vorbis=yes ;;
--disable-vorbis) _vorbis=no ;;
--enable-faad) _faad=yes ;;
@@ -3395,6 +3399,28 @@
fi
+echocheck "lzo support"
+if test "$_lzo" = auto ; then
+ _lzo=no
+ cat > $TMPC << EOF
+#include <lzo1x.h>
+int main(void) { lzo_init();return 0; }
+EOF
+ cc_check -llzo && _lzo=yes
+fi
+if test "$_lzo" = yes ; then
+ _def_lzo='#define USE_LZO 1'
+ _ld_lzo='-llzo'
+ _codecmodules="lzo $_codecmodules"
+ _mkf_lzo="yes"
+else
+ _def_lzo='#undef USE_LZO'
+ _nocodecmodules="lzo $_nocodecmodules"
+ _mkf_lzo="no"
+fi
+echores "$_lzo"
+
+
echocheck "mad support"
if test "$_mad" = auto ; then
_mad=no
@@ -4455,6 +4481,8 @@
CDPARANOIA_LIB = $_ld_cdparanoia
FREETYPE_INC = $_inc_freetype
FREETYPE_LIB = $_ld_freetype
+LZO= $_mkf_lzo
+LZO_LIB= $_ld_lzo
# --- Some stuff for autoconfigure ----
$_target_arch
@@ -4796,6 +4824,9 @@
/* enable FreeType support */
$_def_freetype
+
+/* liblzo support */
+$_def_lzo
/* libmad support */
$_def_mad
diff -Nur -X dontdiff MPlayer-orig-cvs/main/etc/codecs.conf MPlayer-cvs/main/etc/codecs.conf
--- MPlayer-orig-cvs/main/etc/codecs.conf Fri Oct 11 18:33:41 2002
+++ MPlayer-cvs/main/etc/codecs.conf Fri Oct 11 20:43:17 2002
@@ -122,6 +122,14 @@
driver roqvideo
out YV12
+videocodec lzo
+ info "LZO compressed"
+ status working
+ fourcc LZO1
+ driver lzo
+ out YV12,I420
+ out BGR24 flip
+
; prefer native codecs over win32?
; the win32 codecs probably are (better) optimized and support direct
; rendering, so this may be not the best idea...
diff -Nur -X dontdiff MPlayer-orig-cvs/main/libmpcodecs/Makefile MPlayer-cvs/main/libmpcodecs/Makefile
--- MPlayer-orig-cvs/main/libmpcodecs/Makefile Fri Oct 11 18:34:15 2002
+++ MPlayer-cvs/main/libmpcodecs/Makefile Fri Oct 11 18:40:52 2002
@@ -22,6 +22,10 @@
VIDEO_SRCS += vd_ijpg.c
endif
+ifeq ($(LZO),yes)
+VIDEO_SRCS += vd_lzo.c
+endif
+
SRCS=$(AUDIO_SRCS) $(VIDEO_SRCS) $(VFILTER_SRCS) $(NATIVE_SRCS) img_format.c
OBJS=$(SRCS:.c=.o)
diff -Nur -X dontdiff MPlayer-orig-cvs/main/libmpcodecs/vd.c MPlayer-cvs/main/libmpcodecs/vd.c
--- MPlayer-orig-cvs/main/libmpcodecs/vd.c Fri Oct 11 18:34:18 2002
+++ MPlayer-cvs/main/libmpcodecs/vd.c Fri Oct 11 18:40:52 2002
@@ -55,6 +55,7 @@
extern vd_functions_t mpcodecs_vd_xvid;
extern vd_functions_t mpcodecs_vd_libdv;
extern vd_functions_t mpcodecs_vd_lcl;
+extern vd_functions_t mpcodecs_vd_lzo;
vd_functions_t* mpcodecs_vd_drivers[] = {
&mpcodecs_vd_null,
@@ -75,6 +76,9 @@
#ifdef NEW_DECORE
&mpcodecs_vd_divx4,
#endif
+#endif
+#ifdef USE_LZO
+ &mpcodecs_vd_lzo,
#endif
&mpcodecs_vd_raw,
&mpcodecs_vd_msrle,
diff -Nur -X dontdiff MPlayer-orig-cvs/main/libmpcodecs/vd_lzo.c MPlayer-cvs/main/libmpcodecs/vd_lzo.c
--- MPlayer-orig-cvs/main/libmpcodecs/vd_lzo.c Thu Jan 1 01:00:00 1970
+++ MPlayer-cvs/main/libmpcodecs/vd_lzo.c Fri Oct 11 20:59:41 2002
@@ -0,0 +1,148 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "mp_msg.h"
+
+#include "vd_internal.h"
+
+#include <lzo1x.h>
+
+#define MOD_NAME "DecLZO"
+
+static vd_info_t info = {
+ "LZO compressed Video",
+ "lzo",
+ "Tilmann Bitterberg",
+ "Transcode development team <http://www.theorie.physik.uni-goettingen.de/~ostreich/transcode/>",
+ "based on liblzo"
+};
+
+LIBVD_EXTERN(lzo)
+
+
+static lzo_byte *wrkmem=NULL;
+static int codec = -1;
+
+// to set/get/query special features/parameters
+static int control (sh_video_t *sh, int cmd, void* arg, ...)
+{
+
+ //printf("[%s] Query!! (%s)\n", MOD_NAME, (codec==IMGFMT_BGR24)?"BGR":"none");
+ //printf("[%s] Query!! (%s)\n", MOD_NAME, (codec==IMGFMT_YV12)?"YV12":"none");
+ switch(cmd){
+ case VDCTRL_QUERY_FORMAT:
+ if( (*((int*)arg)) == IMGFMT_BGR24 && codec == IMGFMT_BGR24) return CONTROL_TRUE;
+ if( (*((int*)arg)) == IMGFMT_YV12 && codec == IMGFMT_YV12) return CONTROL_TRUE;
+ return CONTROL_FALSE;
+ }
+ return CONTROL_UNKNOWN;
+}
+
+
+// init driver
+static int init(sh_video_t *sh)
+{
+
+ if (lzo_init() != LZO_E_OK) {
+ mp_msg (MSGT_DECVIDEO, MSGL_WARN, "[%s] lzo_init() failed\n", MOD_NAME);
+ return 0;
+ }
+
+ if (!wrkmem) wrkmem = (lzo_bytep) lzo_malloc(LZO1X_1_MEM_COMPRESS);
+
+ if (wrkmem == NULL) {
+ mp_msg (MSGT_DECVIDEO, MSGL_ERR, "[%s] Cannot alloc work memory\n", MOD_NAME);
+ return 0;
+ }
+
+ return 1;
+}
+
+// uninit driver
+static void uninit(sh_video_t *sh)
+{
+ if (wrkmem) { lzo_free(wrkmem); wrkmem = NULL;}
+}
+
+//mp_image_t* mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, int w, int h);
+
+// decode a frame
+static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags)
+{
+ static int init_done = 0;
+ int r;
+ int cb = 1;
+ int cr = 2;
+ mp_image_t* mpi;
+ int w, h;
+
+ if (len <= 0) {
+ return NULL; // skipped frame
+ }
+
+
+ if (!init_done) {
+ lzo_byte *tmp=NULL;
+
+ // decompress one frame to see if its
+ // either YV12 or RGB24
+ if (!tmp) tmp = lzo_malloc(sh->bih->biSizeImage);
+
+ mp_msg (MSGT_DECVIDEO, MSGL_V, "[%s] 2 depth %d, format %d data %p len (%d) (%d)\n",
+ MOD_NAME, sh->bih->biBitCount, sh->format, data, len, sh->bih->biSizeImage
+ );
+
+ /* decompress the frame */
+ r = lzo1x_decompress (data, len, tmp, &w, wrkmem);
+
+ if (r != LZO_E_OK) {
+ /* this should NEVER happen */
+ mp_msg (MSGT_DECVIDEO, MSGL_ERR,
+ "[%s] internal error - decompression failed: %d\n", MOD_NAME, r);
+ return NULL;
+ }
+
+ if (w == (sh->bih->biSizeImage)) {
+ codec = IMGFMT_BGR24;
+ mp_msg (MSGT_DECVIDEO, MSGL_V, "[%s] codec choosen is BGR24\n", MOD_NAME);
+ } else if (w == (sh->bih->biSizeImage)/2) {
+ codec = IMGFMT_YV12;
+ mp_msg (MSGT_DECVIDEO, MSGL_V, "[%s] codec choosen is YV12\n", MOD_NAME);
+ } else {
+ codec = -1;
+ mp_msg(MSGT_DECVIDEO,MSGL_ERR,"[%s] Unsupported out_fmt\n", MOD_NAME);
+ return NULL;
+ }
+
+ mpcodecs_config_vo(sh,sh->disp_w,sh->disp_h,codec);
+ init_done++;
+ free(tmp);
+ }
+
+ mpi = mpcodecs_get_image(sh, MP_IMGTYPE_TEMP, 0,
+ sh->disp_w, sh->disp_h);
+
+
+ if (!mpi) {
+ mp_msg (MSGT_DECVIDEO, MSGL_ERR, "[%s] mpcodecs_get_image failed\n", MOD_NAME);
+ return NULL;
+ }
+
+ r = lzo1x_decompress (data, len, mpi->planes[0], &w, wrkmem);
+ if (r == LZO_E_OK) {
+ mp_msg (MSGT_DECVIDEO, MSGL_V,
+ "[%s] decompressed %lu bytes into %lu bytes\n", MOD_NAME,
+ (long) len, (long)w);
+ } else {
+ /* this should NEVER happen */
+ mp_msg (MSGT_DECVIDEO, MSGL_ERR,
+ "[%s] internal error - decompression failed: %d\n", MOD_NAME, r);
+ return NULL;
+ }
+
+ return mpi;
+}
+
+/* vim: sw=4
+ */
More information about the MPlayer-dev-eng
mailing list