summaryrefslogtreecommitdiff
path: root/libvo
diff options
context:
space:
mode:
Diffstat (limited to 'libvo')
-rw-r--r--libvo/Makefile.am5
-rw-r--r--libvo/Makefile.in462
-rw-r--r--libvo/video_out.c63
-rw-r--r--libvo/video_out_dx.c524
-rw-r--r--libvo/video_out_null.c144
-rw-r--r--libvo/video_out_pgm.c345
-rw-r--r--libvo/video_out_sdl.c171
-rw-r--r--libvo/video_out_x11.c638
-rw-r--r--libvo/vo_internal.h38
9 files changed, 2390 insertions, 0 deletions
diff --git a/libvo/Makefile.am b/libvo/Makefile.am
new file mode 100644
index 0000000..9fee50a
--- /dev/null
+++ b/libvo/Makefile.am
@@ -0,0 +1,5 @@
+AM_CFLAGS = $(OPT_CFLAGS) $(LIBVO_CFLAGS)
+
+noinst_LIBRARIES = libvo.a
+libvo_a_SOURCES = video_out.c video_out_x11.c video_out_dx.c video_out_sdl.c \
+ video_out_null.c video_out_pgm.c vo_internal.h
diff --git a/libvo/Makefile.in b/libvo/Makefile.in
new file mode 100644
index 0000000..8707fe0
--- /dev/null
+++ b/libvo/Makefile.in
@@ -0,0 +1,462 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = libvo
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/cflags.m4 \
+ $(top_srcdir)/m4/inttypes.m4 $(top_srcdir)/m4/keywords.m4 \
+ $(top_srcdir)/m4/nonpic.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+libvo_a_AR = $(AR) $(ARFLAGS)
+libvo_a_LIBADD =
+am_libvo_a_OBJECTS = video_out.$(OBJEXT) video_out_x11.$(OBJEXT) \
+ video_out_dx.$(OBJEXT) video_out_sdl.$(OBJEXT) \
+ video_out_null.$(OBJEXT) video_out_pgm.$(OBJEXT)
+libvo_a_OBJECTS = $(am_libvo_a_OBJECTS)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include
+depcomp = $(SHELL) $(top_srcdir)/.auto/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libvo_a_SOURCES)
+DIST_SOURCES = $(libvo_a_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+AR = @AR@
+ARCH_OPT_CFLAGS = @ARCH_OPT_CFLAGS@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBMPEG2_CFLAGS = @LIBMPEG2_CFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBVO_CFLAGS = @LIBVO_CFLAGS@
+LIBVO_LIBS = @LIBVO_LIBS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MPEG2DEC_CFLAGS = @MPEG2DEC_CFLAGS@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPT_CFLAGS = @OPT_CFLAGS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SDLCONFIG = @SDLCONFIG@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+XMKMF = @XMKMF@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CFLAGS = $(OPT_CFLAGS) $(LIBVO_CFLAGS)
+noinst_LIBRARIES = libvo.a
+libvo_a_SOURCES = video_out.c video_out_x11.c video_out_dx.c video_out_sdl.c \
+ video_out_null.c video_out_pgm.c vo_internal.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libvo/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign libvo/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libvo.a: $(libvo_a_OBJECTS) $(libvo_a_DEPENDENCIES)
+ -rm -f libvo.a
+ $(libvo_a_AR) libvo.a $(libvo_a_OBJECTS) $(libvo_a_LIBADD)
+ $(RANLIB) libvo.a
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_out.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_out_dx.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_out_null.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_out_pgm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_out_sdl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_out_x11.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libvo/video_out.c b/libvo/video_out.c
new file mode 100644
index 0000000..ebe0c53
--- /dev/null
+++ b/libvo/video_out.c
@@ -0,0 +1,63 @@
+/*
+ * video_out.c
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ * See http://libmpeg2.sourceforge.net/ for updates.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include "video_out.h"
+#include "vo_internal.h"
+
+/* Externally visible list of all vo drivers */
+
+static vo_driver_t video_out_drivers[] = {
+#ifdef LIBVO_XV
+ {"xv", vo_xv_open},
+ {"xv2", vo_xv2_open},
+#endif
+#ifdef LIBVO_X11
+ {"x11", vo_x11_open},
+#endif
+#ifdef LIBVO_DX
+ {"dxrgb", vo_dxrgb_open},
+ {"dx", vo_dx_open},
+#endif
+#ifdef LIBVO_SDL
+ {"sdl", vo_sdl_open},
+#endif
+ {"null", vo_null_open},
+ {"nullslice", vo_nullslice_open},
+ {"nullskip", vo_nullskip_open},
+ {"nullrgb16", vo_nullrgb16_open},
+ {"nullrgb32", vo_nullrgb32_open},
+ {"pgm", vo_pgm_open},
+ {"pgmpipe", vo_pgmpipe_open},
+ {"md5", vo_md5_open},
+ {NULL, NULL}
+};
+
+vo_driver_t const * vo_drivers (void)
+{
+ return video_out_drivers;
+}
diff --git a/libvo/video_out_dx.c b/libvo/video_out_dx.c
new file mode 100644
index 0000000..36de68a
--- /dev/null
+++ b/libvo/video_out_dx.c
@@ -0,0 +1,524 @@
+/*
+ * video_out_dx.c
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
+ *
+ * Contributed by Gildas Bazin <gbazin@netcourrier.com>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ * See http://libmpeg2.sourceforge.net/ for updates.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#ifdef LIBVO_DX
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "mpeg2.h"
+#include "video_out.h"
+#include "mpeg2convert.h"
+
+#include <ddraw.h>
+#include <initguid.h>
+
+#define USE_OVERLAY_TRIPLE_BUFFERING 0
+
+/*
+ * DirectDraw GUIDs.
+ * Defining them here allows us to get rid of the dxguid library during link.
+ */
+DEFINE_GUID (IID_IDirectDraw2, 0xB3A6F3E0,0x2B43,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56);
+DEFINE_GUID (IID_IDirectDrawSurface2, 0x57805885,0x6eec,0x11cf,0x94,0x41,0xa8,0x23,0x03,0xc1,0x0e,0x27);
+
+#define FOURCC_YV12 0x32315659
+
+typedef struct {
+ vo_instance_t vo;
+ int width;
+ int height;
+
+ HWND window;
+ RECT window_coords;
+ HINSTANCE hddraw_dll;
+ LPDIRECTDRAW2 ddraw;
+ LPDIRECTDRAWSURFACE2 display;
+ LPDIRECTDRAWCLIPPER clipper;
+ LPDIRECTDRAWSURFACE2 frame[3];
+ int index;
+
+ LPDIRECTDRAWSURFACE2 overlay;
+ uint8_t * yuv[3];
+ int stride;
+} dx_instance_t;
+
+static void update_overlay (dx_instance_t * instance)
+{
+ DDOVERLAYFX ddofx;
+ DWORD dwFlags;
+
+ memset (&ddofx, 0, sizeof (DDOVERLAYFX));
+ ddofx.dwSize = sizeof (DDOVERLAYFX);
+ dwFlags = DDOVER_SHOW | DDOVER_KEYDESTOVERRIDE;
+ IDirectDrawSurface2_UpdateOverlay (instance->overlay, NULL,
+ instance->display,
+ &instance->window_coords,
+ dwFlags, &ddofx);
+}
+
+static long FAR PASCAL event_procedure (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ RECT rect_window;
+ POINT point_window;
+ dx_instance_t * instance;
+
+ switch (message) {
+
+ case WM_WINDOWPOSCHANGED:
+ instance = (dx_instance_t *) GetWindowLong (hwnd, GWL_USERDATA);
+
+ /* update the window position and size */
+ point_window.x = 0;
+ point_window.y = 0;
+ ClientToScreen (hwnd, &point_window);
+ instance->window_coords.left = point_window.x;
+ instance->window_coords.top = point_window.y;
+ GetClientRect (hwnd, &rect_window);
+ instance->window_coords.right = rect_window.right + point_window.x;
+ instance->window_coords.bottom = rect_window.bottom + point_window.y;
+
+ /* update the overlay */
+ if (instance->overlay && instance->display)
+ update_overlay (instance);
+
+ return 0;
+
+ case WM_CLOSE: /* forbid the user to close the window */
+ return 0;
+
+ case WM_DESTROY: /* just destroy the window */
+ PostQuitMessage (0);
+ return 0;
+ }
+
+ return DefWindowProc (hwnd, message, wParam, lParam);
+}
+
+static void check_events (dx_instance_t * instance)
+{
+ MSG msg;
+
+ while (PeekMessage (&msg, instance->window, 0, 0, PM_REMOVE)) {
+ TranslateMessage (&msg);
+ DispatchMessage (&msg);
+ }
+}
+
+static int create_window (dx_instance_t * instance)
+{
+ RECT rect_window;
+ WNDCLASSEX wc;
+
+ wc.cbSize = sizeof (WNDCLASSEX);
+ wc.style = CS_DBLCLKS;
+ wc.lpfnWndProc = (WNDPROC) event_procedure;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = GetModuleHandle (NULL);
+ wc.hIcon = NULL;
+ wc.hCursor = LoadCursor (NULL, IDC_ARROW);
+ wc.hbrBackground = CreateSolidBrush (RGB (0, 0, 0));
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = "libvo_dx";
+ wc.hIconSm = NULL;
+ if (!RegisterClassEx (&wc)) {
+ fprintf (stderr, "Can not register window class\n");
+ return 1;
+ }
+
+ rect_window.top = 10;
+ rect_window.left = 10;
+ rect_window.right = rect_window.left + instance->width;
+ rect_window.bottom = rect_window.top + instance->height;
+ AdjustWindowRect (&rect_window, WS_OVERLAPPEDWINDOW|WS_SIZEBOX, 0);
+
+ instance->window = CreateWindow ("libvo_dx", "mpeg2dec",
+ WS_OVERLAPPEDWINDOW | WS_SIZEBOX,
+ CW_USEDEFAULT, 0,
+ rect_window.right - rect_window.left,
+ rect_window.bottom - rect_window.top,
+ NULL, NULL, GetModuleHandle (NULL), NULL);
+ if (instance->window == NULL) {
+ fprintf (stderr, "Can not create window\n");
+ return 1;
+ }
+
+ /* store a directx_instance pointer into the window local storage
+ * (for later use in event_handler).
+ * We need to use SetWindowLongPtr when it is available in mingw */
+ SetWindowLong (instance->window, GWL_USERDATA, (LONG) instance);
+
+ ShowWindow (instance->window, SW_SHOW);
+
+ return 0;
+}
+
+static LPDIRECTDRAWSURFACE2 alloc_surface (dx_instance_t * instance,
+ DDSURFACEDESC * ddsd)
+{
+ LPDIRECTDRAWSURFACE surface;
+ LPDIRECTDRAWSURFACE2 surface2;
+
+ if (DD_OK != IDirectDraw2_CreateSurface (instance->ddraw, ddsd,
+ &surface, NULL) ||
+ DD_OK != IDirectDrawSurface_QueryInterface (surface,
+ &IID_IDirectDrawSurface2,
+ (LPVOID *) &surface2)) {
+ fprintf (stderr, "Can not create directDraw frame surface\n");
+ return NULL;
+ }
+ IDirectDrawSurface_Release (surface);
+
+ return surface2;
+}
+
+static int dx_init (dx_instance_t *instance)
+{
+ HRESULT (WINAPI * OurDirectDrawCreate) (GUID *, LPDIRECTDRAW *,
+ IUnknown *);
+ LPDIRECTDRAW ddraw;
+ DDSURFACEDESC ddsd;
+
+ /* load direct draw DLL */
+ instance->hddraw_dll = LoadLibrary ("DDRAW.DLL");
+ if (instance->hddraw_dll == NULL) {
+ fprintf (stderr, "Can not load DDRAW.DLL\n");
+ return 1;
+ }
+
+ ddraw = NULL;
+ OurDirectDrawCreate = (void *) GetProcAddress (instance->hddraw_dll,
+ "DirectDrawCreate");
+ if (OurDirectDrawCreate == NULL ||
+ DD_OK != OurDirectDrawCreate (NULL, &ddraw, NULL) ||
+ DD_OK != IDirectDraw_QueryInterface (ddraw, &IID_IDirectDraw2,
+ (LPVOID *) &instance->ddraw) ||
+ DD_OK != IDirectDraw_SetCooperativeLevel (instance->ddraw,
+ instance->window,
+ DDSCL_NORMAL)) {
+ fprintf (stderr, "Can not initialize directDraw interface\n");
+ return 1;
+ }
+ IDirectDraw_Release (ddraw);
+
+ memset (&ddsd, 0, sizeof (DDSURFACEDESC));
+ ddsd.dwSize = sizeof (DDSURFACEDESC);
+ ddsd.dwFlags = DDSD_CAPS;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+ instance->display = alloc_surface (instance, &ddsd);
+ if (instance->display == NULL) {
+ fprintf (stderr, "Can not create directDraw display surface\n");
+ return 1;
+ }
+
+ if (DD_OK != IDirectDraw2_CreateClipper (instance->ddraw, 0,
+ &instance->clipper, NULL) ||
+ DD_OK != IDirectDrawClipper_SetHWnd (instance->clipper, 0,
+ instance->window) ||
+ DD_OK != IDirectDrawSurface_SetClipper (instance->display,
+ instance->clipper)) {
+ fprintf (stderr, "Can not initialize directDraw clipper\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+static int common_setup (dx_instance_t * instance, int width, int height)
+{
+ instance->width = width;
+ instance->height = height;
+ instance->index = 0;
+
+ if (create_window (instance) || dx_init (instance))
+ return 1;
+ return 0;
+}
+
+static int dxrgb_setup (vo_instance_t * _instance, unsigned int width,
+ unsigned int height, unsigned int chroma_width,
+ unsigned int chroma_height, vo_setup_result_t * result)
+{
+ dx_instance_t * instance = (dx_instance_t *) _instance;
+ HDC hdc;
+ int bpp;
+
+ if (common_setup (instance, width, height))
+ return 1;
+
+ hdc = GetDC (NULL);
+ bpp = GetDeviceCaps (hdc, BITSPIXEL);
+ ReleaseDC (NULL, hdc);
+
+ result->convert = mpeg2convert_rgb (MPEG2CONVERT_RGB, bpp);
+ return 0;
+}
+
+static LPDIRECTDRAWSURFACE2 alloc_frame (dx_instance_t * instance)
+{
+ DDSURFACEDESC ddsd;
+ LPDIRECTDRAWSURFACE2 surface;
+
+ memset (&ddsd, 0, sizeof (DDSURFACEDESC));
+ ddsd.dwSize = sizeof (DDSURFACEDESC);
+ ddsd.ddpfPixelFormat.dwSize = sizeof (DDPIXELFORMAT);
+ ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS;
+ ddsd.dwHeight = instance->height;
+ ddsd.dwWidth = instance->width;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
+
+ surface = alloc_surface (instance, &ddsd);
+ if (surface == NULL)
+ fprintf (stderr, "Can not create directDraw frame surface\n");
+ return surface;
+}
+
+static void * surface_addr (LPDIRECTDRAWSURFACE2 surface, int * stride)
+{
+ DDSURFACEDESC ddsd;
+
+ memset (&ddsd, 0, sizeof (DDSURFACEDESC));
+ ddsd.dwSize = sizeof (DDSURFACEDESC);
+ IDirectDrawSurface2_Lock (surface, NULL, &ddsd,
+ DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL);
+ IDirectDrawSurface2_Unlock (surface, NULL);
+ *stride = ddsd.lPitch;
+ return ddsd.lpSurface;
+}
+
+static void dx_setup_fbuf (vo_instance_t * _instance,
+ uint8_t ** buf, void ** id)
+{
+ dx_instance_t * instance = (dx_instance_t *) _instance;
+ int stride;
+
+ *id = instance->frame[instance->index++] = alloc_frame (instance);
+ buf[0] = surface_addr (*id, &stride);
+ buf[1] = NULL; buf[2] = NULL;
+}
+
+static void dxrgb_draw_frame (vo_instance_t * _instance,
+ uint8_t * const * buf, void * id)
+{
+ dx_instance_t * instance = (dx_instance_t *) _instance;
+ LPDIRECTDRAWSURFACE2 surface = (LPDIRECTDRAWSURFACE2) id;
+ DDBLTFX ddbltfx;
+
+ check_events (instance);
+
+ memset (&ddbltfx, 0, sizeof (DDBLTFX));
+ ddbltfx.dwSize = sizeof (DDBLTFX);
+ ddbltfx.dwDDFX = DDBLTFX_NOTEARING;
+ if (DDERR_SURFACELOST ==
+ IDirectDrawSurface2_Blt (instance->display, &instance->window_coords,
+ surface, NULL, DDBLT_WAIT, &ddbltfx)) {
+ /* restore surface and try again */
+ IDirectDrawSurface2_Restore (instance->display);
+ IDirectDrawSurface2_Blt (instance->display, &instance->window_coords,
+ surface, NULL, DDBLT_WAIT, &ddbltfx);
+ }
+}
+
+static vo_instance_t * common_open (int setup (vo_instance_t *,
+ unsigned int, unsigned int,
+ unsigned int, unsigned int,
+ vo_setup_result_t *),
+ void setup_fbuf (vo_instance_t *,
+ uint8_t **, void **),
+ void draw (vo_instance_t *,
+ uint8_t * const *, void * id))
+{
+ dx_instance_t * instance;
+
+ instance = malloc (sizeof (dx_instance_t));
+ if (instance == NULL)
+ return NULL;
+
+ memset (instance, 0, sizeof (dx_instance_t));
+ instance->vo.setup = setup;
+ instance->vo.setup_fbuf = setup_fbuf;
+ instance->vo.set_fbuf = NULL;
+ instance->vo.start_fbuf = NULL;
+ instance->vo.draw = draw;
+ instance->vo.discard = NULL;
+ instance->vo.close = NULL; //dx_close;
+
+ return (vo_instance_t *) instance;
+}
+
+vo_instance_t * vo_dxrgb_open (void)
+{
+ return common_open (dxrgb_setup, dx_setup_fbuf, dxrgb_draw_frame);
+}
+
+static LPDIRECTDRAWSURFACE2 alloc_overlay (dx_instance_t * instance)
+{
+ DDSURFACEDESC ddsd;
+ LPDIRECTDRAWSURFACE2 surface;
+
+ memset (&ddsd, 0, sizeof (DDSURFACEDESC));
+ ddsd.dwSize = sizeof (DDSURFACEDESC);
+ ddsd.ddpfPixelFormat.dwSize = sizeof (DDPIXELFORMAT);
+ ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS;
+ ddsd.dwHeight = instance->height;
+ ddsd.dwWidth = instance->width;
+ ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
+ ddsd.ddpfPixelFormat.dwFourCC = FOURCC_YV12;
+ ddsd.dwFlags |= DDSD_PIXELFORMAT;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;
+#if USE_OVERLAY_TRIPLE_BUFFERING
+ ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT;
+ ddsd.ddsCaps.dwCaps |= DDSCAPS_COMPLEX | DDSCAPS_FLIP;
+#endif
+ ddsd.dwBackBufferCount = 2;
+
+ surface = alloc_surface (instance, &ddsd);
+ if (surface == NULL)
+ fprintf (stderr, "Can not create directDraw frame surface\n");
+ return surface;
+}
+
+static int dx_setup (vo_instance_t * _instance, unsigned int width,
+ unsigned int height, unsigned int chroma_width,
+ unsigned int chroma_height, vo_setup_result_t * result)
+{
+ dx_instance_t * instance = (dx_instance_t *) _instance;
+ LPDIRECTDRAWSURFACE2 surface;
+ DDSURFACEDESC ddsd;
+
+ if (common_setup (instance, width, height))
+ return 1;
+
+ instance->overlay = alloc_overlay (instance);
+ if (!instance->overlay)
+ return 1;
+ update_overlay (instance);
+
+ surface = instance->overlay;
+
+ /* Get the back buffer */
+ memset (&ddsd.ddsCaps, 0, sizeof (DDSCAPS));
+ ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
+ if (DD_OK != IDirectDrawSurface2_GetAttachedSurface (instance->overlay,
+ &ddsd.ddsCaps,
+ &surface))
+ surface = instance->overlay;
+
+ instance->yuv[0] = surface_addr (surface, &instance->stride);
+ instance->yuv[2] = instance->yuv[0] + instance->stride * instance->height;
+ instance->yuv[1] =
+ instance->yuv[2] + (instance->stride * instance->height >> 2);
+
+ result->convert = NULL;
+ return 0;
+}
+
+static void copy_yuv_picture (dx_instance_t * instance,
+ uint8_t * const * buf, void * id)
+{
+ uint8_t * dest[3];
+ int width, i;
+
+ dest[0] = instance->yuv[0];
+ dest[1] = instance->yuv[1];
+ dest[2] = instance->yuv[2];
+
+ width = instance->width;
+ for (i = 0; i < instance->height >> 1; i++) {
+ memcpy (dest[0], buf[0] + 2 * i * width, width);
+ dest[0] += instance->stride;
+ memcpy (dest[0], buf[0] + (2 * i + 1) * width, width);
+ dest[0] += instance->stride;
+ memcpy (dest[1], buf[1] + i * (width >> 1), width >> 1);
+ dest[1] += instance->stride >> 1;
+ memcpy (dest[2], buf[2] + i * (width >> 1), width >> 1);
+ dest[2] += instance->stride >> 1;
+ }
+}
+
+static void dx_draw_frame (vo_instance_t * _instance,
+ uint8_t * const * buf, void * id)
+{
+ dx_instance_t * instance = (dx_instance_t *) _instance;
+
+ check_events (instance);
+
+ copy_yuv_picture (instance, buf, id);
+
+ if (DDERR_SURFACELOST ==
+ IDirectDrawSurface2_Flip (instance->overlay, NULL, DDFLIP_WAIT)) {
+ /* restore surfaces and try again */
+ IDirectDrawSurface2_Restore (instance->display);
+ IDirectDrawSurface2_Restore (instance->overlay);
+ IDirectDrawSurface2_Flip (instance->overlay, NULL, DDFLIP_WAIT);
+ }
+}
+
+vo_instance_t * vo_dx_open (void)
+{
+ return common_open (dx_setup, NULL, dx_draw_frame);
+}
+
+#if 0
+static void dx_close (vo_instance_t * _instance)
+{
+ dx_instance_t * instance;
+ int i;
+
+ instance = (dx_instance_t *) _instance;
+
+ if (instance->using_overlay && instance->overlay) {
+ IDirectDrawSurface2_Release (instance->overlay);
+ instance->overlay = NULL;
+ } else
+ for (i = 0; i < 3; i++) {
+ if (instance->frame[i].p_surface != NULL)
+ IDirectDrawSurface2_Release (instance->frame[i].p_surface);
+ instance->frame[i].p_surface = NULL;
+ }
+
+ if (instance->clipper != NULL)
+ IDirectDrawClipper_Release (instance->clipper);
+
+ if (instance->display != NULL)
+ IDirectDrawSurface2_Release (instance->display);
+
+ if (instance->ddraw != NULL)
+ IDirectDraw2_Release (instance->ddraw);
+
+ if (instance->hddraw_dll != NULL)
+ FreeLibrary (instance->hddraw_dll);
+
+ if (instance->window != NULL)
+ DestroyWindow (instance->window);
+}
+
+#endif
+#endif
diff --git a/libvo/video_out_null.c b/libvo/video_out_null.c
new file mode 100644
index 0000000..eb2608f
--- /dev/null
+++ b/libvo/video_out_null.c
@@ -0,0 +1,144 @@
+/*
+ * video_out_null.c
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ * See http://libmpeg2.sourceforge.net/ for updates.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include "mpeg2.h"
+#include "video_out.h"
+#include "vo_internal.h"
+#include "mpeg2convert.h"
+
+static void null_draw_frame (vo_instance_t * instance,
+ uint8_t * const * buf, void * id)
+{
+}
+
+static vo_instance_t * internal_open (int setup (vo_instance_t *, unsigned int,
+ unsigned int, unsigned int,
+ unsigned int,
+ vo_setup_result_t *),
+ void draw (vo_instance_t *,
+ uint8_t * const *, void *))
+{
+ vo_instance_t * instance;
+
+ instance = (vo_instance_t *) malloc (sizeof (vo_instance_t));
+ if (instance == NULL)
+ return NULL;
+
+ instance->setup = setup;
+ instance->setup_fbuf = NULL;
+ instance->set_fbuf = NULL;
+ instance->start_fbuf = NULL;
+ instance->draw = draw;
+ instance->discard = NULL;
+ instance->close = (void (*) (vo_instance_t *)) free;
+
+ return instance;
+}
+
+static int null_setup (vo_instance_t * instance, unsigned int width,
+ unsigned int height, unsigned int chroma_width,
+ unsigned int chroma_height, vo_setup_result_t * result)
+{
+ result->convert = NULL;
+ return 0;
+}
+
+vo_instance_t * vo_null_open (void)
+{
+ return internal_open (null_setup, null_draw_frame);
+}
+
+vo_instance_t * vo_nullskip_open (void)
+{
+ return internal_open (null_setup, NULL);
+}
+
+static void nullslice_start (void * id, const mpeg2_fbuf_t * fbuf,
+ const mpeg2_picture_t * picture,
+ const mpeg2_gop_t * gop)
+{
+}
+
+static void nullslice_copy (void * id, uint8_t * const * src,
+ unsigned int v_offset)
+{
+}
+
+static int nullslice_convert (int stage, void * id,
+ const mpeg2_sequence_t * seq,
+ int stride, uint32_t accel, void * arg,
+ mpeg2_convert_init_t * result)
+{
+ result->id_size = 0;
+ result->buf_size[0] = result->buf_size[1] = result->buf_size[2] = 0;
+ result->start = nullslice_start;
+ result->copy = nullslice_copy;
+ return 0;
+}
+
+static int nullslice_setup (vo_instance_t * instance, unsigned int width,
+ unsigned int height, unsigned int chroma_width,
+ unsigned int chroma_height,
+ vo_setup_result_t * result)
+{
+ result->convert = nullslice_convert;
+ return 0;
+}
+
+vo_instance_t * vo_nullslice_open (void)
+{
+ return internal_open (nullslice_setup, null_draw_frame);
+}
+
+static int nullrgb16_setup (vo_instance_t * instance, unsigned int width,
+ unsigned int height, unsigned int chroma_width,
+ unsigned int chroma_height,
+ vo_setup_result_t * result)
+{
+ result->convert = mpeg2convert_rgb16;
+ return 0;
+}
+
+static int nullrgb32_setup (vo_instance_t * instance, unsigned int width,
+ unsigned int height, unsigned int chroma_width,
+ unsigned int chroma_height,
+ vo_setup_result_t * result)
+{
+ result->convert = mpeg2convert_rgb32;
+ return 0;
+}
+
+vo_instance_t * vo_nullrgb16_open (void)
+{
+ return internal_open (nullrgb16_setup, null_draw_frame);
+}
+
+vo_instance_t * vo_nullrgb32_open (void)
+{
+ return internal_open (nullrgb32_setup, null_draw_frame);
+}
diff --git a/libvo/video_out_pgm.c b/libvo/video_out_pgm.c
new file mode 100644
index 0000000..ef9ad65
--- /dev/null
+++ b/libvo/video_out_pgm.c
@@ -0,0 +1,345 @@
+/*
+ * video_out_pgm.c
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 2003 Regis Duchesne <hpreg@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ * MD5 code derived from linux kernel GPL implementation
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ * See http://libmpeg2.sourceforge.net/ for updates.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "video_out.h"
+#include "vo_internal.h"
+
+typedef struct pgm_instance_s {
+ vo_instance_t vo;
+ int framenum;
+ int width;
+ int height;
+ int chroma_width;
+ int chroma_height;
+ char header[1024];
+ void (* writer) (struct pgm_instance_s *, uint8_t *, size_t);
+ FILE * file;
+ uint32_t md5_hash[4];
+ uint32_t md5_block[16];
+ uint32_t md5_bytes;
+} pgm_instance_t;
+
+static void file_writer (pgm_instance_t * instance, uint8_t * ptr, size_t size)
+{
+ fwrite (ptr, size, 1, instance->file);
+}
+
+static void internal_draw_frame (pgm_instance_t * instance,
+ uint8_t * const * buf)
+{
+ static uint8_t black[16384] = { 0 };
+ int i;
+
+ instance->writer (instance, (uint8_t *)instance->header,
+ strlen (instance->header));
+ for (i = 0; i < instance->height; i++) {
+ instance->writer (instance, buf[0] + i * instance->width,
+ instance->width);
+ instance->writer (instance, black,
+ 2 * instance->chroma_width - instance->width);
+ }
+ for (i = 0; i < instance->chroma_height; i++) {
+ instance->writer (instance, buf[1] + i * instance->chroma_width,
+ instance->chroma_width);
+ instance->writer (instance, buf[2] + i * instance->chroma_width,
+ instance->chroma_width);
+ }
+}
+
+static void pgm_draw_frame (vo_instance_t * _instance,
+ uint8_t * const * buf, void * id)
+{
+ pgm_instance_t * instance = (pgm_instance_t *) _instance;
+ char filename[128];
+
+ sprintf (filename, "%d.pgm", instance->framenum++);
+ instance->file = fopen (filename, "wb");
+ if (instance->file == NULL)
+ return;
+ internal_draw_frame (instance, buf);
+ fclose (instance->file);
+}
+
+static int pgm_setup (vo_instance_t * _instance, unsigned int width,
+ unsigned int height, unsigned int chroma_width,
+ unsigned int chroma_height, vo_setup_result_t * result)
+{
+ pgm_instance_t * instance;
+
+ instance = (pgm_instance_t *) _instance;
+
+ /*
+ * Layout of the Y, U, and V buffers in our pgm image
+ *
+ * YY YY YY
+ * 420: YY 422: YY 444: YY
+ * UV UV UUVV
+ * UV UUVV
+ */
+ if (width > 2 * chroma_width)
+ return 1;
+
+ instance->width = width;
+ instance->height = height;
+ instance->chroma_width = chroma_width;
+ instance->chroma_height = chroma_height;
+ sprintf (instance->header, "P5\n%d %d\n255\n", 2 * chroma_width,
+ height + chroma_height);
+ result->convert = NULL;
+ return 0;
+}
+
+static vo_instance_t * internal_open (void draw (vo_instance_t *,
+ uint8_t * const *, void *),
+ void writer (pgm_instance_t *,
+ uint8_t *, size_t))
+{
+ pgm_instance_t * instance;
+
+ instance = (pgm_instance_t *) malloc (sizeof (pgm_instance_t));
+ if (instance == NULL)
+ return NULL;
+
+ instance->vo.setup = pgm_setup;
+ instance->vo.setup_fbuf = NULL;
+ instance->vo.set_fbuf = NULL;
+ instance->vo.start_fbuf = NULL;
+ instance->vo.draw = draw;
+ instance->vo.discard = NULL;
+ instance->vo.close = (void (*) (vo_instance_t *)) free;
+ instance->framenum = 0;
+ instance->writer = writer;
+ instance->file = stdout;
+
+ return (vo_instance_t *) instance;
+}
+
+vo_instance_t * vo_pgm_open (void)
+{
+ return internal_open (pgm_draw_frame, file_writer);
+}
+
+static void pgmpipe_draw_frame (vo_instance_t * _instance,
+ uint8_t * const * buf, void * id)
+{
+ pgm_instance_t * instance = (pgm_instance_t *) _instance;
+ internal_draw_frame (instance, buf);
+}
+
+vo_instance_t * vo_pgmpipe_open (void)
+{
+ return internal_open (pgmpipe_draw_frame, file_writer);
+}
+
+#define F1(x,y,z) (z ^ (x & (y ^ z)))
+#define F2(x,y,z) F1 (z, x, y)
+#define F3(x,y,z) (x ^ y ^ z)
+#define F4(x,y,z) (y ^ (x | ~z))
+
+#define MD5STEP(f,w,x,y,z,in,s) do { \
+ w += f (x, y, z) + in; w = ((w << s) | (w >> (32 - s))) + x; \
+} while (0)
+
+static void md5_transform (uint32_t * hash, uint32_t const * in)
+{
+ uint32_t a, b, c, d;
+
+ a = hash[0];
+ b = hash[1];
+ c = hash[2];
+ d = hash[3];
+
+ MD5STEP (F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ MD5STEP (F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ MD5STEP (F1, c, d, a, b, in[2] + 0x242070db, 17);
+ MD5STEP (F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ MD5STEP (F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ MD5STEP (F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ MD5STEP (F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ MD5STEP (F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ MD5STEP (F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ MD5STEP (F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ MD5STEP (F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ MD5STEP (F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ MD5STEP (F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ MD5STEP (F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ MD5STEP (F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ MD5STEP (F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ MD5STEP (F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ MD5STEP (F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ MD5STEP (F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ MD5STEP (F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ MD5STEP (F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ MD5STEP (F2, d, a, b, c, in[10] + 0x02441453, 9);
+ MD5STEP (F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ MD5STEP (F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ MD5STEP (F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ MD5STEP (F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ MD5STEP (F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ MD5STEP (F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ MD5STEP (F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ MD5STEP (F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ MD5STEP (F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ MD5STEP (F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ MD5STEP (F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ MD5STEP (F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ MD5STEP (F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ MD5STEP (F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ MD5STEP (F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ MD5STEP (F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ MD5STEP (F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ MD5STEP (F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ MD5STEP (F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ MD5STEP (F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ MD5STEP (F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ MD5STEP (F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ MD5STEP (F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ MD5STEP (F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ MD5STEP (F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ MD5STEP (F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ MD5STEP (F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ MD5STEP (F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ MD5STEP (F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ MD5STEP (F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ MD5STEP (F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ MD5STEP (F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ MD5STEP (F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ MD5STEP (F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ MD5STEP (F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ MD5STEP (F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ MD5STEP (F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ MD5STEP (F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ MD5STEP (F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ MD5STEP (F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ MD5STEP (F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ MD5STEP (F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+ hash[0] += a;
+ hash[1] += b;
+ hash[2] += c;
+ hash[3] += d;
+}
+
+static inline uint32_t swap (uint32_t x)
+{
+ return (((x & 0xff) << 24) | ((x & 0xff00) << 8) |
+ ((x & 0xff0000) >> 8) | ((x & 0xff000000) >> 24));
+}
+
+static inline void little_endian (uint32_t * buf, unsigned int words)
+{
+#ifdef WORDS_BIGENDIAN
+ while (words--)
+ buf[words] = swap (buf[words]);
+#endif
+}
+
+static void md5_writer (pgm_instance_t * instance, uint8_t * ptr, size_t size)
+{
+ const unsigned int offset = instance->md5_bytes & 0x3f;
+
+ instance->md5_bytes += size;
+
+ if (offset + size < 64) {
+ memcpy ((char *)instance->md5_block + offset, ptr, size);
+ return;
+ } else if (offset) {
+ const int avail = 64 - offset;
+ memcpy ((char *)instance->md5_block + offset, ptr, avail);
+ little_endian (instance->md5_block, 16);
+ md5_transform (instance->md5_hash, instance->md5_block);
+ ptr += avail;
+ size -= avail;
+ }
+
+ while (size >= 64) {
+#ifndef ARCH_X86
+ memcpy (instance->md5_block, ptr, 64);
+ little_endian (instance->md5_block, 16);
+ md5_transform (instance->md5_hash, instance->md5_block);
+#else
+ md5_transform (instance->md5_hash, (uint32_t *)ptr);
+#endif
+ ptr += 64;
+ size -= 64;
+ }
+
+ memcpy (instance->md5_block, ptr, size);
+}
+
+static void md5_draw_frame (vo_instance_t * _instance,
+ uint8_t * const * buf, void * id)
+{
+ pgm_instance_t * instance = (pgm_instance_t *) _instance;
+ unsigned int offset;
+ uint8_t * p;
+ int padding;
+
+ instance->md5_hash[0] = 0x67452301;
+ instance->md5_hash[1] = 0xefcdab89;
+ instance->md5_hash[2] = 0x98badcfe;
+ instance->md5_hash[3] = 0x10325476;
+ instance->md5_bytes = 0;
+
+ internal_draw_frame (instance, buf);
+
+ offset = instance->md5_bytes & 0x3f;
+ p = (uint8_t *)instance->md5_block + offset;
+ padding = 55 - offset;
+
+ *p++ = 0x80;
+ if (padding < 0) {
+ memset (p, 0, padding + 8);
+ little_endian (instance->md5_block, 16);
+ md5_transform (instance->md5_hash, instance->md5_block);
+ p = (uint8_t *)instance->md5_block;
+ padding = 56;
+ }
+
+ memset (p, 0, padding);
+ instance->md5_block[14] = instance->md5_bytes << 3;
+ instance->md5_block[15] = instance->md5_bytes >> 29;
+ little_endian (instance->md5_block, 14);
+ md5_transform (instance->md5_hash, instance->md5_block);
+
+ printf ("%08x%08x%08x%08x *%d.pgm\n", swap (instance->md5_hash[0]),
+ swap (instance->md5_hash[1]) , swap (instance->md5_hash[2]),
+ swap (instance->md5_hash[3]), instance->framenum++);
+}
+
+vo_instance_t * vo_md5_open (void)
+{
+ return internal_open (md5_draw_frame, md5_writer);
+}
diff --git a/libvo/video_out_sdl.c b/libvo/video_out_sdl.c
new file mode 100644
index 0000000..6dc32f5
--- /dev/null
+++ b/libvo/video_out_sdl.c
@@ -0,0 +1,171 @@
+/*
+ * video_out_sdl.c
+ *
+ * Copyright (C) 2000-2003 Ryan C. Gordon <icculus@lokigames.com> and
+ * Dominik Schnitzer <aeneas@linuxvideo.org>
+ *
+ * SDL info, source, and binaries can be found at http://www.libsdl.org/
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ * See http://libmpeg2.sourceforge.net/ for updates.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#ifdef LIBVO_SDL
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <SDL/SDL.h>
+#include <inttypes.h>
+
+#include "video_out.h"
+#include "vo_internal.h"
+
+typedef struct {
+ vo_instance_t vo;
+ int width;
+ int height;
+ SDL_Surface * surface;
+ Uint32 sdlflags;
+ Uint8 bpp;
+} sdl_instance_t;
+
+static void sdl_setup_fbuf (vo_instance_t * _instance,
+ uint8_t ** buf, void ** id)
+{
+ sdl_instance_t * instance = (sdl_instance_t *) _instance;
+ SDL_Overlay * overlay;
+
+ *id = overlay = SDL_CreateYUVOverlay (instance->width, instance->height,
+ SDL_YV12_OVERLAY, instance->surface);
+ buf[0] = overlay->pixels[0];
+ buf[1] = overlay->pixels[2];
+ buf[2] = overlay->pixels[1];
+ if (((long)buf[0] & 15) || ((long)buf[1] & 15) || ((long)buf[2] & 15)) {
+ fprintf (stderr, "Unaligned buffers. Anyone know how to fix this ?\n");
+ exit (1);
+ }
+}
+
+static void sdl_start_fbuf (vo_instance_t * instance,
+ uint8_t * const * buf, void * id)
+{
+ SDL_LockYUVOverlay ((SDL_Overlay *) id);
+}
+
+static void sdl_draw_frame (vo_instance_t * _instance,
+ uint8_t * const * buf, void * id)
+{
+ sdl_instance_t * instance = (sdl_instance_t *) _instance;
+ SDL_Overlay * overlay = (SDL_Overlay *) id;
+ SDL_Event event;
+
+ while (SDL_PollEvent (&event))
+ if (event.type == SDL_VIDEORESIZE)
+ instance->surface =
+ SDL_SetVideoMode (event.resize.w, event.resize.h,
+ instance->bpp, instance->sdlflags);
+ SDL_DisplayYUVOverlay (overlay, &(instance->surface->clip_rect));
+}
+
+static void sdl_discard (vo_instance_t * _instance,
+ uint8_t * const * buf, void * id)
+{
+ SDL_UnlockYUVOverlay ((SDL_Overlay *) id);
+}
+
+#if 0
+static void sdl_close (vo_instance_t * _instance)
+{
+ sdl_instance_t * instance;
+ int i;
+
+ instance = (sdl_instance_t *) _instance;
+ for (i = 0; i < 3; i++)
+ SDL_FreeYUVOverlay (instance->frame[i].overlay);
+ SDL_FreeSurface (instance->surface);
+ SDL_QuitSubSystem (SDL_INIT_VIDEO);
+}
+#endif
+
+static int sdl_setup (vo_instance_t * _instance, unsigned int width,
+ unsigned int height, unsigned int chroma_width,
+ unsigned int chroma_height, vo_setup_result_t * result)
+{
+ sdl_instance_t * instance;
+
+ instance = (sdl_instance_t *) _instance;
+
+ instance->width = width;
+ instance->height = height;
+ instance->surface = SDL_SetVideoMode (width, height, instance->bpp,
+ instance->sdlflags);
+ if (! (instance->surface)) {
+ fprintf (stderr, "sdl could not set the desired video mode\n");
+ return 1;
+ }
+
+ result->convert = NULL;
+ return 0;
+}
+
+vo_instance_t * vo_sdl_open (void)
+{
+ sdl_instance_t * instance;
+ const SDL_VideoInfo * vidInfo;
+
+ instance = (sdl_instance_t *) malloc (sizeof (sdl_instance_t));
+ if (instance == NULL)
+ return NULL;
+
+ instance->vo.setup = sdl_setup;
+ instance->vo.setup_fbuf = sdl_setup_fbuf;
+ instance->vo.set_fbuf = NULL;
+ instance->vo.start_fbuf = sdl_start_fbuf;
+ instance->vo.discard = sdl_discard;
+ instance->vo.draw = sdl_draw_frame;
+ instance->vo.close = NULL; /* sdl_close; */
+ instance->sdlflags = SDL_HWSURFACE | SDL_RESIZABLE;
+
+ putenv((char *)"SDL_VIDEO_YUV_HWACCEL=1");
+ putenv((char *)"SDL_VIDEO_X11_NODIRECTCOLOR=1");
+
+ if (SDL_Init (SDL_INIT_VIDEO)) {
+ fprintf (stderr, "sdl video initialization failed.\n");
+ return NULL;
+ }
+
+ vidInfo = SDL_GetVideoInfo ();
+ if (!SDL_ListModes (vidInfo->vfmt, SDL_HWSURFACE | SDL_RESIZABLE)) {
+ instance->sdlflags = SDL_RESIZABLE;
+ if (!SDL_ListModes (vidInfo->vfmt, SDL_RESIZABLE)) {
+ fprintf (stderr, "sdl couldn't get any acceptable video mode\n");
+ return NULL;
+ }
+ }
+ instance->bpp = vidInfo->vfmt->BitsPerPixel;
+ if (instance->bpp < 16) {
+ fprintf(stderr, "sdl has to emulate a 16 bit surfaces, "
+ "that will slow things down.\n");
+ instance->bpp = 16;
+ }
+
+ return (vo_instance_t *) instance;
+}
+#endif
diff --git a/libvo/video_out_x11.c b/libvo/video_out_x11.c
new file mode 100644
index 0000000..afc7fc2
--- /dev/null
+++ b/libvo/video_out_x11.c
@@ -0,0 +1,638 @@
+/*
+ * video_out_x11.c
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 2003 Regis Duchesne <hpreg@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ * See http://libmpeg2.sourceforge.net/ for updates.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#ifdef LIBVO_X11
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <X11/extensions/XShm.h>
+#include <inttypes.h>
+#include <unistd.h>
+/* since it doesn't seem to be defined on some platforms */
+int XShmGetEventBase (Display *);
+
+#ifdef LIBVO_XV
+#include <string.h> /* strcmp */
+#include <X11/extensions/Xvlib.h>
+#define FOURCC_YV12 0x32315659
+#define FOURCC_UYVY 0x59565955
+#endif
+
+#include "mpeg2.h"
+#include "video_out.h"
+#include "vo_internal.h"
+#include "mpeg2convert.h"
+
+typedef struct {
+ void * data;
+ int wait_completion;
+ XImage * ximage;
+#ifdef LIBVO_XV
+ XvImage * xvimage;
+#endif
+} x11_frame_t;
+
+typedef struct x11_instance_s {
+ vo_instance_t vo;
+ x11_frame_t frame[3];
+ int index;
+ int width;
+ int height;
+ Display * display;
+ Window window;
+ GC gc;
+ XVisualInfo vinfo;
+ XShmSegmentInfo shminfo;
+ int xshm_extension;
+ int completion_type;
+ int xshm;
+#ifdef LIBVO_XV
+ unsigned int adaptors;
+ XvAdaptorInfo * adaptorInfo;
+ XvPortID port;
+ int xv;
+#endif
+ void (* teardown) (struct x11_instance_s * instance);
+} x11_instance_t;
+
+static int open_display (x11_instance_t * instance, int width, int height)
+{
+ int major;
+ int minor;
+ Bool pixmaps;
+ XVisualInfo visualTemplate;
+ XVisualInfo * XvisualInfoTable;
+ XVisualInfo * XvisualInfo;
+ int number;
+ int i;
+ XSetWindowAttributes attr;
+ XGCValues gcValues;
+
+ instance->display = XOpenDisplay (NULL);
+ if (! (instance->display)) {
+ fprintf (stderr, "Can not open display\n");
+ return 1;
+ }
+
+ instance->xshm_extension = 0;
+ if (XShmQueryVersion (instance->display, &major, &minor,
+ &pixmaps) != 0 &&
+ (major > 1 || (major == 1 && minor >= 1))) {
+ instance->xshm_extension = 1;
+ instance->completion_type =
+ XShmGetEventBase (instance->display) + ShmCompletion;
+ } else
+ fprintf (stderr, "No xshm extension\n");
+
+ /* list truecolor visuals for the default screen */
+#ifdef __cplusplus
+ visualTemplate.c_class = TrueColor;
+#else
+ visualTemplate.class = TrueColor;
+#endif
+ visualTemplate.screen = DefaultScreen (instance->display);
+ XvisualInfoTable = XGetVisualInfo (instance->display,
+ VisualScreenMask | VisualClassMask,
+ &visualTemplate, &number);
+ if (XvisualInfoTable == NULL) {
+ fprintf (stderr, "No truecolor visual\n");
+ return 1;
+ }
+
+ /* find the visual with the highest depth */
+ XvisualInfo = XvisualInfoTable;
+ for (i = 1; i < number; i++)
+ if (XvisualInfoTable[i].depth > XvisualInfo->depth)
+ XvisualInfo = XvisualInfoTable + i;
+
+ instance->vinfo = *XvisualInfo;
+ XFree (XvisualInfoTable);
+
+ attr.background_pixmap = None;
+ attr.backing_store = NotUseful;
+ attr.border_pixel = 0;
+ attr.event_mask = 0;
+ /* fucking sun blows me - you have to create a colormap there... */
+ attr.colormap = XCreateColormap (instance->display,
+ RootWindow (instance->display,
+ instance->vinfo.screen),
+ instance->vinfo.visual, AllocNone);
+ instance->window =
+ XCreateWindow (instance->display,
+ DefaultRootWindow (instance->display),
+ 0 /* x */, 0 /* y */, width, height,
+ 0 /* border_width */, instance->vinfo.depth,
+ InputOutput, instance->vinfo.visual,
+ (CWBackPixmap | CWBackingStore | CWBorderPixel |
+ CWEventMask | CWColormap), &attr);
+
+ instance->gc = XCreateGC (instance->display, instance->window, 0,
+ &gcValues);
+
+#ifdef LIBVO_XV
+ instance->adaptors = 0;
+ instance->adaptorInfo = NULL;
+#endif
+
+ return 0;
+}
+
+static int shmerror = 0;
+
+static int handle_error (Display * display, XErrorEvent * error)
+{
+ shmerror = 1;
+ return 0;
+}
+
+static void * create_shm (x11_instance_t * instance, int size)
+{
+ instance->shminfo.shmid = shmget (IPC_PRIVATE, size, IPC_CREAT | 0777);
+ if (instance->shminfo.shmid == -1)
+ goto error;
+
+ instance->shminfo.shmaddr = (char *) shmat (instance->shminfo.shmid, 0, 0);
+ if (instance->shminfo.shmaddr == (char *)-1)
+ goto error;
+
+ /* on linux the IPC_RMID only kicks off once everyone detaches the shm */
+ /* doing this early avoids shm leaks when we are interrupted. */
+ /* this would break the solaris port though :-/ */
+ /* shmctl (instance->shminfo.shmid, IPC_RMID, 0); */
+
+ /* XShmAttach fails on remote displays, so we have to catch this event */
+
+ XSync (instance->display, False);
+ XSetErrorHandler (handle_error);
+
+ instance->shminfo.readOnly = True;
+ if (! (XShmAttach (instance->display, &(instance->shminfo))))
+ shmerror = 1;
+
+ XSync (instance->display, False);
+ XSetErrorHandler (NULL);
+ if (shmerror) {
+ error:
+ fprintf (stderr, "cannot create shared memory\n");
+ if (instance->shminfo.shmid != -1) {
+ shmdt (instance->shminfo.shmaddr);
+ shmctl (instance->shminfo.shmid, IPC_RMID, 0);
+ }
+ return NULL;
+ }
+
+ return instance->shminfo.shmaddr;
+}
+
+static void destroy_shm (x11_instance_t * instance)
+{
+ XShmDetach (instance->display, &(instance->shminfo));
+ shmdt (instance->shminfo.shmaddr);
+ shmctl (instance->shminfo.shmid, IPC_RMID, 0);
+}
+
+static void x11_event (x11_instance_t * instance)
+{
+ XEvent event;
+ char * addr;
+ int i;
+
+ XNextEvent (instance->display, &event);
+ if (event.type == instance->completion_type) {
+ addr = (instance->shminfo.shmaddr +
+ ((XShmCompletionEvent *)&event)->offset);
+ for (i = 0; i < 3; i++)
+ if (addr == instance->frame[i].data)
+ instance->frame[i].wait_completion = 0;
+ }
+}
+
+static void x11_start_fbuf (vo_instance_t * _instance,
+ uint8_t * const * buf, void * id)
+{
+ x11_instance_t * instance = (x11_instance_t *) _instance;
+ x11_frame_t * frame = (x11_frame_t *) id;
+
+ while (frame->wait_completion)
+ x11_event (instance);
+}
+
+static void x11_setup_fbuf (vo_instance_t * _instance,
+ uint8_t ** buf, void ** id)
+{
+ x11_instance_t * instance = (x11_instance_t *) _instance;
+
+ buf[0] = (uint8_t *) instance->frame[instance->index].data;
+ buf[1] = buf[2] = NULL;
+ *id = instance->frame + instance->index++;
+}
+
+static void x11_draw_frame (vo_instance_t * _instance,
+ uint8_t * const * buf, void * id)
+{
+ x11_frame_t * frame;
+ x11_instance_t * instance;
+
+ frame = (x11_frame_t *) id;
+ instance = (x11_instance_t *) _instance;
+ if (instance->xshm)
+ XShmPutImage (instance->display, instance->window, instance->gc,
+ frame->ximage, 0, 0, 0, 0,
+ instance->width, instance->height, True);
+ else
+ XPutImage (instance->display, instance->window, instance->gc,
+ frame->ximage, 0, 0, 0, 0,
+ instance->width, instance->height);
+ XFlush (instance->display);
+ frame->wait_completion = instance->xshm;
+}
+
+static int x11_alloc_frames (x11_instance_t * instance, int xshm)
+{
+ int size;
+ char * alloc;
+ int i = 0;
+
+ if (xshm && !instance->xshm_extension)
+ return 1;
+
+ size = 0;
+ alloc = NULL;
+ while (i < 3) {
+ instance->frame[i].wait_completion = 0;
+ instance->frame[i].ximage = xshm ?
+ XShmCreateImage (instance->display, instance->vinfo.visual,
+ instance->vinfo.depth, ZPixmap, NULL /* data */,
+ &(instance->shminfo),
+ instance->width, instance->height) :
+ XCreateImage(instance->display, instance->vinfo.visual,
+ instance->vinfo.depth, ZPixmap, 0, NULL /* data */,
+ instance->width, instance->height, 8, 0);
+ if (instance->frame[i].ximage == NULL) {
+ fprintf (stderr, "Cannot create ximage\n");
+ return 1;
+ } else if (xshm) {
+ if (i == 0) {
+ size = (instance->frame[0].ximage->bytes_per_line *
+ instance->frame[0].ximage->height);
+ alloc = (char *) create_shm (instance, 3 * size);
+ } else if (size != (instance->frame[i].ximage->bytes_per_line *
+ instance->frame[i].ximage->height)) {
+ fprintf (stderr, "unexpected ximage data size\n");
+ return 1;
+ }
+ } else
+ alloc =
+ (char *) malloc (instance->frame[i].ximage->bytes_per_line *
+ instance->frame[i].ximage->height);
+ instance->frame[i].data = instance->frame[i].ximage->data = alloc;
+ i++;
+ if (alloc == NULL) {
+ while (--i >= 0)
+ XDestroyImage (instance->frame[i].ximage);
+ return 1;
+ }
+ alloc += size;
+ }
+
+ instance->xshm = xshm;
+ return 0;
+}
+
+static void x11_teardown (x11_instance_t * instance)
+{
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ while (instance->frame[i].wait_completion)
+ x11_event (instance);
+ XDestroyImage (instance->frame[i].ximage);
+ }
+ if (instance->xshm)
+ destroy_shm (instance);
+}
+
+static void x11_close (vo_instance_t * _instance)
+{
+ x11_instance_t * instance = (x11_instance_t *) _instance;
+
+ if (instance->teardown != NULL)
+ instance->teardown (instance);
+ XFreeGC (instance->display, instance->gc);
+ XDestroyWindow (instance->display, instance->window);
+#ifdef LIBVO_XV
+ if (instance->adaptors)
+ XvFreeAdaptorInfo (instance->adaptorInfo);
+#endif
+ XCloseDisplay (instance->display);
+ free (instance);
+}
+
+#ifdef LIBVO_XV
+static void xv_setup_fbuf (vo_instance_t * _instance,
+ uint8_t ** buf, void ** id)
+{
+ x11_instance_t * instance = (x11_instance_t *) _instance;
+ uint8_t * data;
+
+ data = (uint8_t *) instance->frame[instance->index].xvimage->data;
+ buf[0] = data + instance->frame[instance->index].xvimage->offsets[0];
+ buf[1] = data + instance->frame[instance->index].xvimage->offsets[2];
+ buf[2] = data + instance->frame[instance->index].xvimage->offsets[1];
+ *id = instance->frame + instance->index++;
+}
+
+static void xv_draw_frame (vo_instance_t * _instance,
+ uint8_t * const * buf, void * id)
+{
+ x11_frame_t * frame = (x11_frame_t *) id;
+ x11_instance_t * instance = (x11_instance_t *) _instance;
+
+ if (instance->xshm)
+ XvShmPutImage (instance->display, instance->port, instance->window,
+ instance->gc, frame->xvimage, 0, 0,
+ instance->width, instance->height, 0, 0,
+ instance->width, instance->height, True);
+ else
+ XvPutImage (instance->display, instance->port, instance->window,
+ instance->gc, frame->xvimage, 0, 0,
+ instance->width, instance->height, 0, 0,
+ instance->width, instance->height);
+ XFlush (instance->display);
+ frame->wait_completion = instance->xshm;
+}
+
+static int xv_check_fourcc (x11_instance_t * instance, XvPortID port,
+ int fourcc, const char * fourcc_str)
+{
+ XvImageFormatValues * formatValues;
+ int formats;
+ int i;
+
+ formatValues = XvListImageFormats (instance->display, port, &formats);
+ for (i = 0; i < formats; i++)
+ if ((formatValues[i].id == fourcc) &&
+ (! (strcmp (formatValues[i].guid, fourcc_str)))) {
+ XFree (formatValues);
+ return 0;
+ }
+ XFree (formatValues);
+ return 1;
+}
+
+static int xv_check_extension (x11_instance_t * instance,
+ int fourcc, const char * fourcc_str)
+{
+ unsigned int i;
+ unsigned long j;
+
+ if (!instance->adaptorInfo) {
+ unsigned int version;
+ unsigned int release;
+ unsigned int dummy;
+
+ if ((XvQueryExtension (instance->display, &version, &release,
+ &dummy, &dummy, &dummy) != Success) ||
+ (version < 2) || ((version == 2) && (release < 2))) {
+ fprintf (stderr, "No xv extension\n");
+ return 1;
+ }
+
+ XvQueryAdaptors (instance->display, instance->window,
+ &instance->adaptors, &instance->adaptorInfo);
+ }
+
+ for (i = 0; i < instance->adaptors; i++)
+ if (instance->adaptorInfo[i].type & XvImageMask)
+ for (j = 0; j < instance->adaptorInfo[i].num_ports; j++)
+ if ((! (xv_check_fourcc (instance,
+ instance->adaptorInfo[i].base_id + j,
+ fourcc, fourcc_str))) &&
+ (XvGrabPort (instance->display,
+ instance->adaptorInfo[i].base_id + j,
+ 0) == Success)) {
+ instance->port = instance->adaptorInfo[i].base_id + j;
+ return 0;
+ }
+
+ fprintf (stderr, "Cannot find xv %s port\n", fourcc_str);
+ return 1;
+}
+
+static int xv_alloc_frames (x11_instance_t * instance, int size,
+ int fourcc)
+{
+ char * alloc;
+ int i = 0;
+
+ instance->xshm = 1;
+ alloc = instance->xshm_extension ?
+ (char *) create_shm (instance, 3 * size) : NULL;
+ if (alloc == NULL) {
+ instance->xshm = 0;
+ alloc = (char *) malloc (3 * size);
+ if (alloc == NULL)
+ return 1;
+ }
+
+ while (i < 3) {
+ instance->frame[i].wait_completion = 0;
+ instance->frame[i].xvimage = instance->xshm ?
+ XvShmCreateImage (instance->display, instance->port, fourcc,
+ alloc, instance->width, instance->height,
+ &(instance->shminfo)) :
+ XvCreateImage (instance->display, instance->port, fourcc,
+ alloc, instance->width, instance->height);
+ instance->frame[i].data = alloc;
+ alloc += size;
+ if ((instance->frame[i].xvimage == NULL) ||
+ (instance->frame[i++].xvimage->data_size != size)) {
+ while (--i >= 0)
+ XFree (instance->frame[i].xvimage);
+ if (instance->xshm)
+ destroy_shm (instance);
+ else
+ free (instance->frame[0].data);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static void xv_teardown (x11_instance_t * instance)
+{
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ while (instance->frame[i].wait_completion)
+ x11_event (instance);
+ XFree (instance->frame[i].xvimage);
+ }
+ if (instance->xshm)
+ destroy_shm (instance);
+ else
+ free (instance->frame[0].data);
+ XvUngrabPort (instance->display, instance->port, 0);
+}
+#endif
+
+static int common_setup (vo_instance_t * _instance, unsigned int width,
+ unsigned int height, unsigned int chroma_width,
+ unsigned int chroma_height,
+ vo_setup_result_t * result)
+{
+ x11_instance_t * instance = (x11_instance_t *) _instance;
+
+ if (instance->display != NULL) {
+ /* Already setup, just adjust to the new size */
+ if (instance->teardown != NULL)
+ instance->teardown (instance);
+ XResizeWindow (instance->display, instance->window, width, height);
+ } else {
+ /* Not setup yet, do the full monty */
+ if (open_display (instance, width, height))
+ return 1;
+ XMapWindow (instance->display, instance->window);
+ }
+ instance->vo.setup_fbuf = NULL;
+ instance->vo.start_fbuf = NULL;
+ instance->vo.set_fbuf = NULL;
+ instance->vo.draw = NULL;
+ instance->vo.discard = NULL;
+ instance->vo.close = x11_close;
+ instance->width = width;
+ instance->height = height;
+ instance->index = 0;
+ instance->teardown = NULL;
+ result->convert = NULL;
+
+#ifdef LIBVO_XV
+ if (instance->xv == 1 &&
+ (chroma_width == width >> 1) && (chroma_height == height >> 1) &&
+ !xv_check_extension (instance, FOURCC_YV12, "YV12") &&
+ !xv_alloc_frames (instance, 3 * width * height / 2, FOURCC_YV12)) {
+ instance->vo.setup_fbuf = xv_setup_fbuf;
+ instance->vo.start_fbuf = x11_start_fbuf;
+ instance->vo.draw = xv_draw_frame;
+ instance->teardown = xv_teardown;
+ } else if (instance->xv && (chroma_width == width >> 1) &&
+ !xv_check_extension (instance, FOURCC_UYVY, "UYVY") &&
+ !xv_alloc_frames (instance, 2 * width * height, FOURCC_UYVY)) {
+ instance->vo.setup_fbuf = x11_setup_fbuf;
+ instance->vo.start_fbuf = x11_start_fbuf;
+ instance->vo.draw = xv_draw_frame;
+ instance->teardown = xv_teardown;
+ result->convert = mpeg2convert_uyvy;
+ } else
+#endif
+ if (!x11_alloc_frames (instance, 1) || !x11_alloc_frames (instance, 0)) {
+ int bpp;
+
+ instance->vo.setup_fbuf = x11_setup_fbuf;
+ instance->vo.start_fbuf = x11_start_fbuf;
+ instance->vo.draw = x11_draw_frame;
+ instance->teardown = x11_teardown;
+
+#ifdef WORDS_BIGENDIAN
+ if (instance->frame[0].ximage->byte_order != MSBFirst) {
+ fprintf (stderr, "No support for non-native byte order\n");
+ return 1;
+ }
+#else
+ if (instance->frame[0].ximage->byte_order != LSBFirst) {
+ fprintf (stderr, "No support for non-native byte order\n");
+ return 1;
+ }
+#endif
+
+ /*
+ * depth in X11 terminology land is the number of bits used to
+ * actually represent the colour.
+ *
+ * bpp in X11 land means how many bits in the frame buffer per
+ * pixel.
+ *
+ * ex. 15 bit color is 15 bit depth and 16 bpp. Also 24 bit
+ * color is 24 bit depth, but can be 24 bpp or 32 bpp.
+ *
+ * If we have blue in the lowest bit then "obviously" RGB
+ * (the guy who wrote this convention never heard of endianness ?)
+ */
+
+ bpp = ((instance->vinfo.depth == 24) ?
+ instance->frame[0].ximage->bits_per_pixel :
+ instance->vinfo.depth);
+ result->convert =
+ mpeg2convert_rgb (((instance->frame[0].ximage->blue_mask & 1) ?
+ MPEG2CONVERT_RGB : MPEG2CONVERT_BGR), bpp);
+ if (result->convert == NULL) {
+ fprintf (stderr, "%dbpp not supported\n", bpp);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static vo_instance_t * common_open (int xv)
+{
+ x11_instance_t * instance;
+
+ instance = (x11_instance_t *) malloc (sizeof (x11_instance_t));
+ if (instance == NULL)
+ return NULL;
+
+ instance->vo.setup = common_setup;
+ instance->vo.close = (void (*) (vo_instance_t *)) free;
+ instance->display = NULL;
+#ifdef LIBVO_XV
+ instance->xv = xv;
+#endif
+ return (vo_instance_t *) instance;
+}
+
+vo_instance_t * vo_x11_open (void)
+{
+ return common_open (0);
+}
+
+#ifdef LIBVO_XV
+vo_instance_t * vo_xv_open (void)
+{
+ return common_open (1);
+}
+
+vo_instance_t * vo_xv2_open (void)
+{
+ return common_open (2);
+}
+#endif
+#endif
diff --git a/libvo/vo_internal.h b/libvo/vo_internal.h
new file mode 100644
index 0000000..d8d57ba
--- /dev/null
+++ b/libvo/vo_internal.h
@@ -0,0 +1,38 @@
+/*
+ * vo_internal.h
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ * See http://libmpeg2.sourceforge.net/ for updates.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+extern vo_open_t vo_xv_open;
+extern vo_open_t vo_xv2_open;
+extern vo_open_t vo_x11_open;
+extern vo_open_t vo_dxrgb_open;
+extern vo_open_t vo_dx_open;
+extern vo_open_t vo_sdl_open;
+extern vo_open_t vo_null_open;
+extern vo_open_t vo_nullslice_open;
+extern vo_open_t vo_nullskip_open;
+extern vo_open_t vo_nullrgb16_open;
+extern vo_open_t vo_nullrgb32_open;
+extern vo_open_t vo_pgm_open;
+extern vo_open_t vo_pgmpipe_open;
+extern vo_open_t vo_md5_open;
+