From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- .../interfaces/IDirectFBVideoProvider/Makefile.am | 57 + .../interfaces/IDirectFBVideoProvider/Makefile.in | 635 ++++++++ .../idirectfbvideoprovider_gif.c | 1075 ++++++++++++++ .../idirectfbvideoprovider_v4l.c | 1523 ++++++++++++++++++++ .../interfaces/IDirectFBVideoProvider/videodev.h | 353 +++++ .../interfaces/IDirectFBVideoProvider/videodev2.h | 897 ++++++++++++ 6 files changed, 4540 insertions(+) create mode 100755 Source/DirectFB/interfaces/IDirectFBVideoProvider/Makefile.am create mode 100755 Source/DirectFB/interfaces/IDirectFBVideoProvider/Makefile.in create mode 100755 Source/DirectFB/interfaces/IDirectFBVideoProvider/idirectfbvideoprovider_gif.c create mode 100755 Source/DirectFB/interfaces/IDirectFBVideoProvider/idirectfbvideoprovider_v4l.c create mode 100755 Source/DirectFB/interfaces/IDirectFBVideoProvider/videodev.h create mode 100755 Source/DirectFB/interfaces/IDirectFBVideoProvider/videodev2.h (limited to 'Source/DirectFB/interfaces/IDirectFBVideoProvider') diff --git a/Source/DirectFB/interfaces/IDirectFBVideoProvider/Makefile.am b/Source/DirectFB/interfaces/IDirectFBVideoProvider/Makefile.am new file mode 100755 index 0000000..affe5ef --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBVideoProvider/Makefile.am @@ -0,0 +1,57 @@ +## Makefile.am for DirectFB/interfaces/IDirectFBVideoProvider + +idirectfbvideoproviderdir = $(MODULEDIR)/interfaces/IDirectFBVideoProvider + +EXTRA_DIST = videodev.h videodev2.h + +if V4L_PROVIDER +V4L_PROVIDER_LTLIB = libidirectfbvideoprovider_v4l.la +else +V4L_PROVIDER_LTLIB = +endif + +if GIF_PROVIDER +GIF_PROVIDER_LTLIB = libidirectfbvideoprovider_gif.la +else +GIF_PROVIDER_LTLIB = +endif + +INCLUDES = \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/src \ + -DDATADIR=\"${RUNTIME_SYSROOT}@DATADIR@\" + + +idirectfbvideoprovider_LTLIBRARIES = \ + $(GIF_PROVIDER_LTLIB) \ + $(V4L_PROVIDER_LTLIB) + +if BUILD_STATIC +idirectfbvideoprovider_DATA = $(idirectfbvideoprovider_LTLIBRARIES:.la=.o) +endif + + +libidirectfbvideoprovider_v4l_la_SOURCES = idirectfbvideoprovider_v4l.c + +libidirectfbvideoprovider_v4l_la_LDFLAGS = -avoid-version -module + +libidirectfbvideoprovider_v4l_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/lib/fusion/libfusion.la \ + $(top_builddir)/src/libdirectfb.la + + +libidirectfbvideoprovider_gif_la_SOURCES = idirectfbvideoprovider_gif.c + +libidirectfbvideoprovider_gif_la_LDFLAGS = -avoid-version -module + +libidirectfbvideoprovider_gif_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/lib/fusion/libfusion.la \ + $(top_builddir)/src/libdirectfb.la + + +include $(top_srcdir)/rules/libobject.make diff --git a/Source/DirectFB/interfaces/IDirectFBVideoProvider/Makefile.in b/Source/DirectFB/interfaces/IDirectFBVideoProvider/Makefile.in new file mode 100755 index 0000000..33f8f5e --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBVideoProvider/Makefile.in @@ -0,0 +1,635 @@ +# 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@ +target_triplet = @target@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/rules/libobject.make +subdir = interfaces/IDirectFBVideoProvider +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(idirectfbvideoproviderdir)" \ + "$(DESTDIR)$(idirectfbvideoproviderdir)" +idirectfbvideoproviderLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(idirectfbvideoprovider_LTLIBRARIES) +libidirectfbvideoprovider_gif_la_DEPENDENCIES = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/lib/fusion/libfusion.la \ + $(top_builddir)/src/libdirectfb.la +am_libidirectfbvideoprovider_gif_la_OBJECTS = \ + idirectfbvideoprovider_gif.lo +libidirectfbvideoprovider_gif_la_OBJECTS = \ + $(am_libidirectfbvideoprovider_gif_la_OBJECTS) +libidirectfbvideoprovider_gif_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(libidirectfbvideoprovider_gif_la_LDFLAGS) $(LDFLAGS) -o $@ +@GIF_PROVIDER_TRUE@am_libidirectfbvideoprovider_gif_la_rpath = -rpath \ +@GIF_PROVIDER_TRUE@ $(idirectfbvideoproviderdir) +libidirectfbvideoprovider_v4l_la_DEPENDENCIES = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/lib/fusion/libfusion.la \ + $(top_builddir)/src/libdirectfb.la +am_libidirectfbvideoprovider_v4l_la_OBJECTS = \ + idirectfbvideoprovider_v4l.lo +libidirectfbvideoprovider_v4l_la_OBJECTS = \ + $(am_libidirectfbvideoprovider_v4l_la_OBJECTS) +libidirectfbvideoprovider_v4l_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(libidirectfbvideoprovider_v4l_la_LDFLAGS) $(LDFLAGS) -o $@ +@V4L_PROVIDER_TRUE@am_libidirectfbvideoprovider_v4l_la_rpath = -rpath \ +@V4L_PROVIDER_TRUE@ $(idirectfbvideoproviderdir) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/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 = $(libidirectfbvideoprovider_gif_la_SOURCES) \ + $(libidirectfbvideoprovider_v4l_la_SOURCES) +DIST_SOURCES = $(libidirectfbvideoprovider_gif_la_SOURCES) \ + $(libidirectfbvideoprovider_v4l_la_SOURCES) +idirectfbvideoproviderDATA_INSTALL = $(INSTALL_DATA) +DATA = $(idirectfbvideoprovider_DATA) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +ASFLAGS = @ASFLAGS@ +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@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DFB_CFLAGS_OMIT_FRAME_POINTER = @DFB_CFLAGS_OMIT_FRAME_POINTER@ +DFB_INTERNAL_CFLAGS = @DFB_INTERNAL_CFLAGS@ +DFB_LDFLAGS = @DFB_LDFLAGS@ +DFB_SMOOTH_SCALING = @DFB_SMOOTH_SCALING@ +DIRECTFB_BINARY_AGE = @DIRECTFB_BINARY_AGE@ +DIRECTFB_CSOURCE = @DIRECTFB_CSOURCE@ +DIRECTFB_INTERFACE_AGE = @DIRECTFB_INTERFACE_AGE@ +DIRECTFB_MAJOR_VERSION = @DIRECTFB_MAJOR_VERSION@ +DIRECTFB_MICRO_VERSION = @DIRECTFB_MICRO_VERSION@ +DIRECTFB_MINOR_VERSION = @DIRECTFB_MINOR_VERSION@ +DIRECTFB_VERSION = @DIRECTFB_VERSION@ +DIRECT_BUILD_DEBUG = @DIRECT_BUILD_DEBUG@ +DIRECT_BUILD_DEBUGS = @DIRECT_BUILD_DEBUGS@ +DIRECT_BUILD_GETTID = @DIRECT_BUILD_GETTID@ +DIRECT_BUILD_NETWORK = @DIRECT_BUILD_NETWORK@ +DIRECT_BUILD_STDBOOL = @DIRECT_BUILD_STDBOOL@ +DIRECT_BUILD_TEXT = @DIRECT_BUILD_TEXT@ +DIRECT_BUILD_TRACE = @DIRECT_BUILD_TRACE@ +DSYMUTIL = @DSYMUTIL@ +DYNLIB = @DYNLIB@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ +FREETYPE_LIBS = @FREETYPE_LIBS@ +FREETYPE_PROVIDER = @FREETYPE_PROVIDER@ +FUSION_BUILD_KERNEL = @FUSION_BUILD_KERNEL@ +FUSION_BUILD_MULTI = @FUSION_BUILD_MULTI@ +FUSION_MESSAGE_SIZE = @FUSION_MESSAGE_SIZE@ +GIF_PROVIDER = @GIF_PROVIDER@ +GREP = @GREP@ +HAVE_LINUX = @HAVE_LINUX@ +INCLUDEDIR = @INCLUDEDIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTERNALINCLUDEDIR = @INTERNALINCLUDEDIR@ +JPEG_PROVIDER = @JPEG_PROVIDER@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBJPEG = @LIBJPEG@ +LIBOBJS = @LIBOBJS@ +LIBPNG = @LIBPNG@ +LIBPNG_CONFIG = @LIBPNG_CONFIG@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_AGE = @LT_AGE@ +LT_BINARY = @LT_BINARY@ +LT_CURRENT = @LT_CURRENT@ +LT_RELEASE = @LT_RELEASE@ +LT_REVISION = @LT_REVISION@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MAN2HTML = @MAN2HTML@ +MKDIR_P = @MKDIR_P@ +MODULEDIR = @MODULEDIR@ +MODULEDIRNAME = @MODULEDIRNAME@ +NMEDIT = @NMEDIT@ +OBJEXT = @OBJEXT@ +OSX_LIBS = @OSX_LIBS@ +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@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PNG_PROVIDER = @PNG_PROVIDER@ +RANLIB = @RANLIB@ +RUNTIME_SYSROOT = @RUNTIME_SYSROOT@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_LIBS = @SDL_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOPATH = @SOPATH@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +SYSFS_LIBS = @SYSFS_LIBS@ +THREADFLAGS = @THREADFLAGS@ +THREADLIB = @THREADLIB@ +TSLIB_CFLAGS = @TSLIB_CFLAGS@ +TSLIB_LIBS = @TSLIB_LIBS@ +VERSION = @VERSION@ +VNC_CFLAGS = @VNC_CFLAGS@ +VNC_CONFIG = @VNC_CONFIG@ +VNC_LIBS = @VNC_LIBS@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +ZLIB_LIBS = @ZLIB_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 = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +idirectfbvideoproviderdir = $(MODULEDIR)/interfaces/IDirectFBVideoProvider +EXTRA_DIST = videodev.h videodev2.h +@V4L_PROVIDER_FALSE@V4L_PROVIDER_LTLIB = +@V4L_PROVIDER_TRUE@V4L_PROVIDER_LTLIB = libidirectfbvideoprovider_v4l.la +@GIF_PROVIDER_FALSE@GIF_PROVIDER_LTLIB = +@GIF_PROVIDER_TRUE@GIF_PROVIDER_LTLIB = libidirectfbvideoprovider_gif.la +INCLUDES = \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/src \ + -DDATADIR=\"${RUNTIME_SYSROOT}@DATADIR@\" + +idirectfbvideoprovider_LTLIBRARIES = \ + $(GIF_PROVIDER_LTLIB) \ + $(V4L_PROVIDER_LTLIB) + +@BUILD_STATIC_TRUE@idirectfbvideoprovider_DATA = $(idirectfbvideoprovider_LTLIBRARIES:.la=.o) +libidirectfbvideoprovider_v4l_la_SOURCES = idirectfbvideoprovider_v4l.c +libidirectfbvideoprovider_v4l_la_LDFLAGS = -avoid-version -module +libidirectfbvideoprovider_v4l_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/lib/fusion/libfusion.la \ + $(top_builddir)/src/libdirectfb.la + +libidirectfbvideoprovider_gif_la_SOURCES = idirectfbvideoprovider_gif.c +libidirectfbvideoprovider_gif_la_LDFLAGS = -avoid-version -module +libidirectfbvideoprovider_gif_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/lib/fusion/libfusion.la \ + $(top_builddir)/src/libdirectfb.la + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/rules/libobject.make $(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) --gnu interfaces/IDirectFBVideoProvider/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu interfaces/IDirectFBVideoProvider/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 +install-idirectfbvideoproviderLTLIBRARIES: $(idirectfbvideoprovider_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(idirectfbvideoproviderdir)" || $(MKDIR_P) "$(DESTDIR)$(idirectfbvideoproviderdir)" + @list='$(idirectfbvideoprovider_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(idirectfbvideoproviderLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(idirectfbvideoproviderdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(idirectfbvideoproviderLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(idirectfbvideoproviderdir)/$$f"; \ + else :; fi; \ + done + +uninstall-idirectfbvideoproviderLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(idirectfbvideoprovider_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(idirectfbvideoproviderdir)/$$p'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(idirectfbvideoproviderdir)/$$p"; \ + done + +clean-idirectfbvideoproviderLTLIBRARIES: + -test -z "$(idirectfbvideoprovider_LTLIBRARIES)" || rm -f $(idirectfbvideoprovider_LTLIBRARIES) + @list='$(idirectfbvideoprovider_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libidirectfbvideoprovider_gif.la: $(libidirectfbvideoprovider_gif_la_OBJECTS) $(libidirectfbvideoprovider_gif_la_DEPENDENCIES) + $(libidirectfbvideoprovider_gif_la_LINK) $(am_libidirectfbvideoprovider_gif_la_rpath) $(libidirectfbvideoprovider_gif_la_OBJECTS) $(libidirectfbvideoprovider_gif_la_LIBADD) $(LIBS) +libidirectfbvideoprovider_v4l.la: $(libidirectfbvideoprovider_v4l_la_OBJECTS) $(libidirectfbvideoprovider_v4l_la_DEPENDENCIES) + $(libidirectfbvideoprovider_v4l_la_LINK) $(am_libidirectfbvideoprovider_v4l_la_rpath) $(libidirectfbvideoprovider_v4l_la_OBJECTS) $(libidirectfbvideoprovider_v4l_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbvideoprovider_gif.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbvideoprovider_v4l.Plo@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 +install-idirectfbvideoproviderDATA: $(idirectfbvideoprovider_DATA) + @$(NORMAL_INSTALL) + test -z "$(idirectfbvideoproviderdir)" || $(MKDIR_P) "$(DESTDIR)$(idirectfbvideoproviderdir)" + @list='$(idirectfbvideoprovider_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(idirectfbvideoproviderDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(idirectfbvideoproviderdir)/$$f'"; \ + $(idirectfbvideoproviderDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(idirectfbvideoproviderdir)/$$f"; \ + done + +uninstall-idirectfbvideoproviderDATA: + @$(NORMAL_UNINSTALL) + @list='$(idirectfbvideoprovider_DATA)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(idirectfbvideoproviderdir)/$$f'"; \ + rm -f "$(DESTDIR)$(idirectfbvideoproviderdir)/$$f"; \ + done + +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 $(LTLIBRARIES) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(idirectfbvideoproviderdir)" "$(DESTDIR)$(idirectfbvideoproviderdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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-idirectfbvideoproviderLTLIBRARIES \ + clean-libtool 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-idirectfbvideoproviderDATA \ + install-idirectfbvideoproviderLTLIBRARIES + +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: uninstall-idirectfbvideoproviderDATA \ + uninstall-idirectfbvideoproviderLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-idirectfbvideoproviderLTLIBRARIES clean-libtool 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-idirectfbvideoproviderDATA \ + install-idirectfbvideoproviderLTLIBRARIES 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 \ + uninstall-idirectfbvideoproviderDATA \ + uninstall-idirectfbvideoproviderLTLIBRARIES + +%.o: .libs/%.a %.la + rm -f $<.tmp/*.o + if test -d $<.tmp; then rmdir $<.tmp; fi + mkdir $<.tmp + (cd $<.tmp && $(AR) x ../../$<) + $(LD) -o $@ -r $<.tmp/*.o + rm -f $<.tmp/*.o && rmdir $<.tmp + +.PHONY: $(LTLIBRARIES:%.la=.libs/%.a) +# 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/Source/DirectFB/interfaces/IDirectFBVideoProvider/idirectfbvideoprovider_gif.c b/Source/DirectFB/interfaces/IDirectFBVideoProvider/idirectfbvideoprovider_gif.c new file mode 100755 index 0000000..65f3fbb --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBVideoProvider/idirectfbvideoprovider_gif.c @@ -0,0 +1,1075 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include +#include + +#include + + +static DFBResult Probe( IDirectFBVideoProvider_ProbeContext *ctx ); + +static DFBResult Construct( IDirectFBVideoProvider *thiz, + IDirectFBDataBuffer *buffer ); + + +#include + +DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBVideoProvider, Gif ) + +/*****************************************************************************/ + +#define MAXCOLORMAPSIZE 256 + +#define CM_RED 0 +#define CM_GREEN 1 +#define CM_BLUE 2 + +#define MAX_LWZ_BITS 12 + +#define INTERLACE 0x40 +#define LOCALCOLORMAP 0x80 + +#define BitSet(byte, bit) (((byte) & (bit)) == (bit)) + +#define LM_to_uint(a,b) (((b)<<8)|(a)) + +typedef struct { + int ref; /* reference counter */ + + IDirectFBDataBuffer *buffer; + DFBBoolean seekable; + + IDirectFBSurface *destination; + IDirectFBSurface_data *dst_data; + DFBRectangle dst_rect; + + u32 *image; + + DirectThread *thread; + pthread_mutex_t lock; + pthread_cond_t cond; + + DFBVideoProviderStatus status; + DFBVideoProviderPlaybackFlags flags; + double speed; + + unsigned int start_pos; + + char Version[4]; + unsigned int Width; + unsigned int Height; + u8 ColorMap[3][MAXCOLORMAPSIZE]; + unsigned int BitPixel; + unsigned int ColorResolution; + u32 Background; + unsigned int AspectRatio; + + int transparent; + unsigned int delayTime; + int inputFlag; + int disposal; + + u8 buf[280]; + int curbit, lastbit, done, last_byte; + + int fresh; + int code_size, set_code_size; + int max_code, max_code_size; + int firstcode, oldcode; + int clear_code, end_code; + int table[2][(1<< MAX_LWZ_BITS)]; + int stack[(1<<(MAX_LWZ_BITS))*2], *sp; + + DVFrameCallback callback; + void *callback_ctx; +} IDirectFBVideoProvider_GIF_data; + +#define GIFERRORMSG(x, ...) \ + D_ERROR( "IDirectFBVideoProvider_GIF: " #x "!\n", ## __VA_ARGS__ ) + +#define GIFDEBUGMSG(x, ...) \ + D_DEBUG( "IDirectFBVideoProvider_GIF: " #x "!\n", ## __VA_ARGS__ ) + +/*****************************************************************************/ + +static int ZeroDataBlock = 0; + +static DFBResult +FetchData( IDirectFBDataBuffer *buffer, void *data, unsigned int len ) +{ + DFBResult ret = DFB_OK; + + do { + unsigned int read = 0; + + ret = buffer->WaitForData( buffer, len ); + if (ret == DFB_OK) + ret = buffer->GetData( buffer, len, data, &read ); + if (ret) + break; + + data += read; + len -= read; + } while (len); + + return ret; +} + +static int ReadColorMap( IDirectFBDataBuffer *buffer, int number, + u8 buf[3][MAXCOLORMAPSIZE] ) +{ + int i; + u8 rgb[3*number]; + + if (FetchData( buffer, rgb, sizeof(rgb) )) { + GIFERRORMSG("bad colormap"); + return -1; + } + + for (i = 0; i < number; ++i) { + buf[CM_RED][i] = rgb[i*3+0]; + buf[CM_GREEN][i] = rgb[i*3+1]; + buf[CM_BLUE][i] = rgb[i*3+2]; + } + + return 0; +} + +static int GetDataBlock(IDirectFBDataBuffer *buffer, u8 *buf) +{ + unsigned char count; + + if (FetchData( buffer, &count, 1 )) { + GIFERRORMSG("error in getting DataBlock size"); + return -1; + } + ZeroDataBlock = (count == 0); + + if ((count != 0) && FetchData( buffer, buf, count )) { + GIFERRORMSG("error in reading DataBlock"); + return -1; + } + + return count; +} + +static int GetCode(IDirectFBVideoProvider_GIF_data *data, int code_size, int flag) +{ + int i, j, ret; + unsigned char count; + + if (flag) { + data->curbit = 0; + data->lastbit = 0; + data->done = false; + return 0; + } + + if ( (data->curbit+code_size) >= data->lastbit) { + if (data->done) { + if (data->curbit >= data->lastbit) { + GIFERRORMSG("ran off the end of my bits"); + } + return -1; + } + data->buf[0] = data->buf[data->last_byte-2]; + data->buf[1] = data->buf[data->last_byte-1]; + + if ((count = GetDataBlock( data->buffer, &data->buf[2] )) == 0) { + data->done = true; + } + + data->last_byte = 2 + count; + data->curbit = (data->curbit - data->lastbit) + 16; + data->lastbit = (2+count) * 8; + } + + ret = 0; + for (i = data->curbit, j = 0; j < code_size; ++i, ++j) { + ret |= ((data->buf[ i / 8 ] & (1 << (i % 8))) != 0) << j; + } + data->curbit += code_size; + + return ret; +} + +static int DoExtension( IDirectFBVideoProvider_GIF_data *data, int label ) +{ + unsigned char buf[256] = { 0 }; + char *str; + + switch (label) { + case 0x01: /* Plain Text Extension */ + str = "Plain Text Extension"; + break; + case 0xff: /* Application Extension */ + str = "Application Extension"; + break; + case 0xfe: /* Comment Extension */ + str = "Comment Extension"; + while (GetDataBlock( data->buffer, (u8*) buf ) != 0) + GIFDEBUGMSG("gif comment: %s", buf); + return false; + case 0xf9: /* Graphic Control Extension */ + str = "Graphic Control Extension"; + (void) GetDataBlock( data->buffer, (u8*) buf ); + data->disposal = (buf[0] >> 2) & 0x7; + data->inputFlag = (buf[0] >> 1) & 0x1; + if (LM_to_uint( buf[1], buf[2] )) + data->delayTime = LM_to_uint( buf[1], buf[2] ) * 10000; + if ((buf[0] & 0x1) != 0) + data->transparent = buf[3]; + else + data->transparent = -1; + while (GetDataBlock( data->buffer, (u8*) buf ) != 0) + ; + return false; + default: + str = (char*) buf; + snprintf(str, 256, "UNKNOWN (0x%02x)", label); + break; + } + + GIFDEBUGMSG("got a '%s' extension", str ); + + while (GetDataBlock( data->buffer, (u8*) buf ) != 0); + + return 0; +} + +static int LWZReadByte( IDirectFBVideoProvider_GIF_data *data, int flag, int input_code_size ) +{ + int code, incode; + int i; + + if (flag) { + data->set_code_size = input_code_size; + data->code_size = data->set_code_size+1; + data->clear_code = 1 << data->set_code_size ; + data->end_code = data->clear_code + 1; + data->max_code_size = 2*data->clear_code; + data->max_code = data->clear_code+2; + + GetCode(data, 0, true); + + data->fresh = true; + + for (i = 0; i < data->clear_code; ++i) { + data->table[0][i] = 0; + data->table[1][i] = i; + } + for (; i < (1<table[0][i] = data->table[1][0] = 0; + } + data->sp = data->stack; + + return 0; + } + else if (data->fresh) { + data->fresh = false; + do { + data->firstcode = data->oldcode = GetCode( data, data->code_size, false ); + } while (data->firstcode == data->clear_code); + + return data->firstcode; + } + + if (data->sp > data->stack) { + return *--data->sp; + } + + while ((code = GetCode( data, data->code_size, false )) >= 0) { + if (code == data->clear_code) { + for (i = 0; i < data->clear_code; ++i) { + data->table[0][i] = 0; + data->table[1][i] = i; + } + for (; i < (1<table[0][i] = data->table[1][i] = 0; + } + data->code_size = data->set_code_size+1; + data->max_code_size = 2*data->clear_code; + data->max_code = data->clear_code+2; + data->sp = data->stack; + data->firstcode = data->oldcode = GetCode( data, data->code_size, false ); + + return data->firstcode; + } + else if (code == data->end_code) { + int count; + u8 buf[260]; + + if (ZeroDataBlock) { + return -2; + } + + while ((count = GetDataBlock( data->buffer, buf )) > 0) + ; + + if (count != 0) + GIFERRORMSG("missing EOD in data stream (common occurence)"); + + return -2; + } + + incode = code; + + if (code >= data->max_code) { + *data->sp++ = data->firstcode; + code = data->oldcode; + } + + while (code >= data->clear_code) { + *data->sp++ = data->table[1][code]; + if (code == data->table[0][code]) { + GIFERRORMSG("circular table entry BIG ERROR"); + } + code = data->table[0][code]; + } + + *data->sp++ = data->firstcode = data->table[1][code]; + + if ((code = data->max_code) <(1<table[0][code] = data->oldcode; + data->table[1][code] = data->firstcode; + ++data->max_code; + if ((data->max_code >= data->max_code_size) + && (data->max_code_size < (1<max_code_size *= 2; + ++data->code_size; + } + } + + data->oldcode = incode; + + if (data->sp > data->stack) { + return *--data->sp; + } + } + return code; +} + +static int ReadImage( IDirectFBVideoProvider_GIF_data *data, + int left, int top, int width, int height, + u8 cmap[3][MAXCOLORMAPSIZE], bool interlace, bool ignore ) +{ + u8 c; + int v; + int xpos = 0, ypos = 0, pass = 0; + u32 *image, *dst; + + /* + ** Initialize the decompression routines + */ + if (FetchData( data->buffer, &c, 1 )) + GIFERRORMSG("EOF / read error on image data"); + + if (LWZReadByte( data, true, c ) < 0) + GIFERRORMSG("error reading image"); + + /* + ** If this is an "uninteresting picture" ignore it. + */ + if (ignore) { + GIFDEBUGMSG("skipping image..."); + + while (LWZReadByte( data, false, c ) >= 0) + ; + return 0; + } + + switch (data->disposal) { + case 2: + GIFDEBUGMSG("restoring to background color..."); + memset( data->image, 0, data->Width * data->Height * 4 ); + break; + case 3: + GIFERRORMSG("restoring to previous frame is unsupported"); + break; + default: + break; + } + + dst = image = data->image + (top * data->Width + left); + + GIFDEBUGMSG("reading %dx%d at %dx%d %sGIF image", + width, height, left, top, interlace ? " interlaced " : "" ); + + while ((v = LWZReadByte( data, false, c )) >= 0 ) { + if (v != data->transparent) { + dst[xpos] = (0xFF000000 | + cmap[CM_RED][v] << 16 | + cmap[CM_GREEN][v] << 8 | + cmap[CM_BLUE][v]); + } + + ++xpos; + if (xpos == width) { + xpos = 0; + if (interlace) { + switch (pass) { + case 0: + case 1: + ypos += 8; + break; + case 2: + ypos += 4; + break; + case 3: + ypos += 2; + break; + } + + if (ypos >= height) { + ++pass; + switch (pass) { + case 1: + ypos = 4; + break; + case 2: + ypos = 2; + break; + case 3: + ypos = 1; + break; + default: + goto fini; + } + } + } + else { + ++ypos; + } + dst = image + ypos * data->Width; + } + if (ypos >= height) { + break; + } + } + +fini: + + if (LWZReadByte( data, false, c ) >= 0) { + GIFERRORMSG("too much input data, ignoring extra..."); + //while (LWZReadByte( data, false, c ) >= 0); + } + + return 0; +} + +static void GIFReset( IDirectFBVideoProvider_GIF_data *data ) +{ + data->transparent = -1; + data->delayTime = 1000000; /* default: 1s */ + data->inputFlag = -1; + data->disposal = 0; + + if (data->image) + memset( data->image, 0, data->Width*data->Height*4 ); +} + +static DFBResult GIFReadHeader( IDirectFBVideoProvider_GIF_data *data ) +{ + DFBResult ret; + u8 buf[7]; + + ret = FetchData( data->buffer, buf, 6 ); + if (ret) { + GIFERRORMSG("error reading header"); + return ret; + } + + if (memcmp( buf, "GIF", 3 )) { + GIFERRORMSG("bad magic"); + return DFB_UNSUPPORTED; + } + + memcpy( data->Version, &buf[3], 3 ); + data->Version[3] = '\0'; + + ret = FetchData( data->buffer, buf, 7 ); + if (ret) { + GIFERRORMSG("error reading screen descriptor"); + return ret; + } + + data->Width = LM_to_uint( buf[0], buf[1] ); + data->Height = LM_to_uint( buf[2], buf[3] ); + data->BitPixel = 2 << (buf[4] & 0x07); + data->ColorResolution = (((buf[4] & 0x70) >> 3) + 1); + data->Background = buf[5]; + data->AspectRatio = buf[6]; + if (data->AspectRatio) + data->AspectRatio = ((data->AspectRatio + 15) << 8) >> 6; + else + data->AspectRatio = (data->Width << 8) / data->Height; + + if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */ + if (ReadColorMap( data->buffer, data->BitPixel, data->ColorMap )) { + GIFERRORMSG("error reading global colormap"); + return DFB_FAILURE; + } + } + + return DFB_OK; +} + +static DFBResult GIFReadFrame( IDirectFBVideoProvider_GIF_data *data ) +{ + u8 buf[16], c; + int top, left; + int width, height; + u8 localColorMap[3][MAXCOLORMAPSIZE]; + bool useGlobalColormap; + + data->curbit = data->lastbit = data->done = data->last_byte = 0; + + data->fresh = + data->code_size = data->set_code_size = + data->max_code = data->max_code_size = + data->firstcode = data->oldcode = + data->clear_code = data->end_code = 0; + + for (;;) { + DFBResult ret; + + ret = FetchData( data->buffer, &c, 1); + if (ret) { + GIFERRORMSG("EOF / read error on image data" ); + return DFB_EOF; + } + + if (c == ';') /* GIF terminator */ + return DFB_EOF; + + if (c == '!') { /* Extension */ + if (FetchData( data->buffer, &c, 1)) { + GIFERRORMSG("EOF / read error on extention function code"); + return DFB_EOF; + } + DoExtension( data, c ); + continue; + } + + if (c != ',') { /* Not a valid start character */ + GIFERRORMSG("bogus character 0x%02x, ignoring", (int) c ); + continue; + } + + ret = FetchData( data->buffer, buf, 9 ); + if (ret) { + GIFERRORMSG("couldn't read left/top/width/height"); + return ret; + } + + left = LM_to_uint( buf[0], buf[1] ); + top = LM_to_uint( buf[2], buf[3] ); + width = LM_to_uint( buf[4], buf[5] ); + height = LM_to_uint( buf[6], buf[7] ); + + useGlobalColormap = !BitSet( buf[8], LOCALCOLORMAP ); + + if (!useGlobalColormap) { + int bitPixel = 2 << (buf[8] & 0x07); + if (ReadColorMap( data->buffer, bitPixel, localColorMap )) + GIFERRORMSG("error reading local colormap"); + } + + if (ReadImage( data, left, top, width, height, + (useGlobalColormap ? + data->ColorMap : localColorMap), + BitSet( buf[8], INTERLACE ), 0 )) { + GIFERRORMSG("error reading image"); + return DFB_FAILURE; + } + + break; + } + + return DFB_OK; +} + +/*****************************************************************************/ + +static void +IDirectFBVideoProvider_GIF_Destruct( IDirectFBVideoProvider *thiz ) +{ + IDirectFBVideoProvider_GIF_data *data = thiz->priv; + + thiz->Stop( thiz ); + + if (data->image) + D_FREE( data->image ); + + if (data->buffer) + data->buffer->Release( data->buffer ); + + pthread_cond_destroy( &data->cond ); + pthread_mutex_destroy( &data->lock ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); +} + +static DirectResult +IDirectFBVideoProvider_GIF_AddRef( IDirectFBVideoProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + data->ref++; + + return DFB_OK; +} + +static DirectResult +IDirectFBVideoProvider_GIF_Release( IDirectFBVideoProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (--data->ref == 0) + IDirectFBVideoProvider_GIF_Destruct( thiz ); + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_GIF_GetCapabilities( IDirectFBVideoProvider *thiz, + DFBVideoProviderCapabilities *caps ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (!caps) + return DFB_INVARG; + + *caps = DVCAPS_BASIC | DVCAPS_SCALE | DVCAPS_SPEED; + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_GIF_GetSurfaceDescription( IDirectFBVideoProvider *thiz, + DFBSurfaceDescription *desc ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (!desc) + return DFB_INVARG; + + desc->flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; + desc->width = data->Width; + desc->height = data->Height; + desc->pixelformat = DSPF_ARGB; + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_GIF_GetStreamDescription( IDirectFBVideoProvider *thiz, + DFBStreamDescription *desc ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (!desc) + return DFB_INVARG; + + desc->caps = DVSCAPS_VIDEO; + + snprintf( desc->video.encoding, + DFB_STREAM_DESC_ENCODING_LENGTH, "GIF %s", data->Version ); + desc->video.framerate = 0; + desc->video.aspect = (double)data->AspectRatio/256.0; + desc->video.bitrate = 0; + + desc->title[0] = desc->author[0] = + desc->album[0] = desc->genre[0] = desc->comment[0] = 0; + desc->year = 0; + + return DFB_OK; +} + +static void* +GIFVideo( DirectThread *self, void *arg ) +{ + IDirectFBVideoProvider_GIF_data *data = arg; + + pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, NULL ); + + while (!direct_thread_is_canceled( self )) { + DFBResult ret; + DFBRectangle rect; + DFBRegion clip; + CoreSurface *surface; + CoreSurfaceBufferLock lock; + + pthread_mutex_lock( &data->lock ); + + if (direct_thread_is_canceled( self )) { + pthread_mutex_unlock( &data->lock ); + break; + } + + ret = GIFReadFrame( data ); + if (ret) { + if (ret == DFB_EOF) { + GIFReset( data ); + if (data->flags & DVPLAY_LOOPING) { + data->buffer->SeekTo( data->buffer, data->start_pos ); + } + else { + data->status = DVSTATE_FINISHED; + pthread_mutex_unlock( &data->lock ); + break; + } + } + pthread_mutex_unlock( &data->lock ); + continue; + } + + rect = (data->dst_rect.w == 0) + ? data->dst_data->area.wanted : data->dst_rect; + dfb_region_from_rectangle( &clip, &data->dst_data->area.current ); + + surface = data->dst_data->surface; + D_MAGIC_ASSERT( surface, CoreSurface ); + + if (dfb_rectangle_region_intersects( &rect, &clip ) && + dfb_surface_lock_buffer( surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock ) == DFB_OK) + { + dfb_scale_linear_32( data->image, data->Width, data->Height, + lock.addr, lock.pitch, &rect, data->dst_data->surface, &clip ); + + dfb_surface_unlock_buffer( surface, &lock ); + + if (data->callback) + data->callback( data->callback_ctx ); + } + + if (!data->speed) { + pthread_cond_wait( &data->cond, &data->lock ); + } + else { + struct timespec ts; + unsigned long us; + + us = data->delayTime; + if (data->speed != 1.0) + us = ((double)us / data->speed + .5); + + direct_util_get_monotonic_pthread_timeout(&ts, + us/1000000, + (us%1000000) * 1000); + + pthread_cond_timedwait( &data->cond, &data->lock, &ts ); + } + + pthread_mutex_unlock( &data->lock ); + } + + return (void*)0; +} + +static DFBResult +IDirectFBVideoProvider_GIF_PlayTo( IDirectFBVideoProvider *thiz, + IDirectFBSurface *destination, + const DFBRectangle *dest_rect, + DVFrameCallback callback, + void *ctx ) +{ + IDirectFBSurface_data *dst_data; + DFBRectangle rect = { 0, 0, 0, 0 }; + DFBResult ret; + + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (!destination) + return DFB_INVARG; + + dst_data = destination->priv; + if (!dst_data || !dst_data->surface) + return DFB_DESTROYED; + + if (dest_rect) { + if (dest_rect->w < 1 || dest_rect->h < 1) + return DFB_INVARG; + + rect = *dest_rect; + rect.x += dst_data->area.wanted.x; + rect.y += dst_data->area.wanted.y; + } + + pthread_mutex_lock( &data->lock ); + + if (data->status == DVSTATE_FINISHED) { + ret = data->buffer->SeekTo( data->buffer, data->start_pos ); + if (ret) { + pthread_mutex_unlock( &data->lock ); + return ret; + } + } + data->status = DVSTATE_PLAY; + + if (!data->image) { + data->image = D_CALLOC( 4, data->Width * data->Height ); + if (!data->image) { + pthread_mutex_unlock( &data->lock ); + return D_OOM(); + } + } + + if (data->destination) + data->destination->Release( data->destination ); + + destination->AddRef( destination ); + data->destination = destination; + data->dst_data = dst_data; + data->dst_rect = rect; + + data->callback = callback; + data->callback_ctx = ctx; + + if (!data->thread) { + data->thread = direct_thread_create( DTT_DEFAULT, GIFVideo, + (void*)data, "GIF Video" ); + } + + pthread_mutex_unlock( &data->lock ); + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_GIF_Stop( IDirectFBVideoProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (data->thread) { + direct_thread_cancel( data->thread ); + pthread_mutex_lock( &data->lock ); + pthread_cond_signal( &data->cond ); + pthread_mutex_unlock( &data->lock ); + direct_thread_join( data->thread ); + direct_thread_destroy( data->thread ); + data->thread = NULL; + } + + if (data->destination) { + data->destination->Release( data->destination ); + data->destination = NULL; + data->dst_data = NULL; + } + + data->status = DVSTATE_STOP; + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_GIF_GetStatus( IDirectFBVideoProvider *thiz, + DFBVideoProviderStatus *status ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (!status) + return DFB_INVARG; + + *status = data->status; + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_GIF_SeekTo( IDirectFBVideoProvider *thiz, + double seconds ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (seconds < 0.0) + return DFB_INVARG; + + return DFB_UNSUPPORTED; +} + +static DFBResult +IDirectFBVideoProvider_GIF_GetPos( IDirectFBVideoProvider *thiz, + double *seconds ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (!seconds) + return DFB_INVARG; + + *seconds = 0.0; + + return DFB_UNSUPPORTED; +} + +static DFBResult +IDirectFBVideoProvider_GIF_GetLength( IDirectFBVideoProvider *thiz, + double *seconds ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (!seconds) + return DFB_INVARG; + + *seconds = 0.0; + + return DFB_UNSUPPORTED; +} + +static DFBResult +IDirectFBVideoProvider_GIF_SetPlaybackFlags( IDirectFBVideoProvider *thiz, + DFBVideoProviderPlaybackFlags flags ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (flags & ~DVPLAY_LOOPING) + return DFB_UNSUPPORTED; + + if (flags & DVPLAY_LOOPING && !data->seekable) + return DFB_UNSUPPORTED; + + data->flags = flags; + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_GIF_SetSpeed( IDirectFBVideoProvider *thiz, + double multiplier ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (multiplier < 0.0) + return DFB_INVARG; + + if (data->speed != multiplier) { + pthread_mutex_lock( &data->lock ); + data->speed = multiplier; + pthread_cond_signal( &data->cond ); + pthread_mutex_unlock( &data->lock ); + } + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_GIF_GetSpeed( IDirectFBVideoProvider *thiz, + double *multiplier ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (!multiplier) + return DFB_INVARG; + + *multiplier = data->speed; + + return DFB_OK; +} + +/* exported symbols */ +static DFBResult +Probe( IDirectFBVideoProvider_ProbeContext *ctx ) +{ + if (!memcmp( ctx->header, "GIF89", 5 )) + return DFB_OK; + + return DFB_UNSUPPORTED; +} + +static DFBResult +Construct( IDirectFBVideoProvider *thiz, + IDirectFBDataBuffer *buffer ) +{ + DFBResult ret; + + DIRECT_ALLOCATE_INTERFACE_DATA( thiz, IDirectFBVideoProvider_GIF ) + + data->ref = 1; + data->status = DVSTATE_STOP; + data->buffer = buffer; + data->speed = 1.0; + + buffer->AddRef( buffer ); + data->seekable = (buffer->SeekTo( buffer, 0 ) == DFB_OK); + + GIFReset( data ); + ret = GIFReadHeader( data ); + if (ret) { + IDirectFBVideoProvider_GIF_Destruct( thiz ); + return ret; + } + + data->buffer->GetPosition( data->buffer, &data->start_pos ); + + direct_util_recursive_pthread_mutex_init( &data->lock ); + direct_util_monotonic_pthread_cond_init( &data->cond ); + + thiz->AddRef = IDirectFBVideoProvider_GIF_AddRef; + thiz->Release = IDirectFBVideoProvider_GIF_Release; + thiz->GetCapabilities = IDirectFBVideoProvider_GIF_GetCapabilities; + thiz->GetSurfaceDescription = IDirectFBVideoProvider_GIF_GetSurfaceDescription; + thiz->GetStreamDescription = IDirectFBVideoProvider_GIF_GetStreamDescription; + thiz->PlayTo = IDirectFBVideoProvider_GIF_PlayTo; + thiz->Stop = IDirectFBVideoProvider_GIF_Stop; + thiz->GetStatus = IDirectFBVideoProvider_GIF_GetStatus; + thiz->SeekTo = IDirectFBVideoProvider_GIF_SeekTo; + thiz->GetPos = IDirectFBVideoProvider_GIF_GetPos; + thiz->GetLength = IDirectFBVideoProvider_GIF_GetLength; + thiz->SetPlaybackFlags = IDirectFBVideoProvider_GIF_SetPlaybackFlags; + thiz->SetSpeed = IDirectFBVideoProvider_GIF_SetSpeed; + thiz->GetSpeed = IDirectFBVideoProvider_GIF_GetSpeed; + + return DFB_OK; +} diff --git a/Source/DirectFB/interfaces/IDirectFBVideoProvider/idirectfbvideoprovider_v4l.c b/Source/DirectFB/interfaces/IDirectFBVideoProvider/idirectfbvideoprovider_v4l.c new file mode 100755 index 0000000..6d7df13 --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBVideoProvider/idirectfbvideoprovider_v4l.c @@ -0,0 +1,1523 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#if defined(__dietlibc__) && !defined(_BSD_SOURCE) +#define _BSD_SOURCE +#endif + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_LINUX_COMPILER_H +#include +#endif +#include "videodev.h" + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#ifdef DFB_HAVE_V4L2 +#include "videodev2.h" +#endif + +static DFBResult +Probe( IDirectFBVideoProvider_ProbeContext *ctx ); + +static DFBResult +Construct( IDirectFBVideoProvider *thiz, ... ); + +#include + +DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBVideoProvider, V4L ) + +/* + * private data struct of IDirectFBVideoProvider + */ +typedef struct { + int ref; /* reference counter */ + + char *filename; + int fd; +#ifdef DFB_HAVE_V4L2 +#define NUMBER_OF_BUFFERS 2 + bool is_v4l2; + + struct v4l2_format fmt; + struct v4l2_capability caps; + + struct v4l2_queryctrl brightness; + struct v4l2_queryctrl contrast; + struct v4l2_queryctrl saturation; + struct v4l2_queryctrl hue; + + struct v4l2_requestbuffers req; + struct v4l2_buffer vidbuf[NUMBER_OF_BUFFERS]; + char *ptr[NUMBER_OF_BUFFERS]; /* only used for capture to system memory */ + bool framebuffer_or_system; +#endif + struct video_capability vcap; + struct video_mmap vmmap; + struct video_mbuf vmbuf; + void *buffer; + bool grab_mode; + + DirectThread *thread; + CoreSurface *destination; + CoreSurfaceBufferLock destinationlock; + DVFrameCallback callback; + void *ctx; + + CoreCleanup *cleanup; + + bool running; + pthread_mutex_t lock; + + Reaction reaction; /* for the destination listener */ + + CoreDFB *core; +} IDirectFBVideoProvider_V4L_data; + +static const unsigned int zero = 0; +static const unsigned int one = 1; + +static void* OverlayThread( DirectThread *thread, void *context ); +static void* GrabThread( DirectThread *thread, void *context ); +static ReactionResult v4l_videosurface_listener( const void *msg_data, void *ctx ); +static ReactionResult v4l_systemsurface_listener( const void *msg_data, void *ctx ); +static DFBResult v4l_to_surface_overlay( CoreSurface *surface, DFBRectangle *rect, + IDirectFBVideoProvider_V4L_data *data ); +static DFBResult v4l_to_surface_grab( CoreSurface *surface, DFBRectangle *rect, + IDirectFBVideoProvider_V4L_data *data ); +static DFBResult v4l_stop( IDirectFBVideoProvider_V4L_data *data, bool detach ); +static void v4l_deinit( IDirectFBVideoProvider_V4L_data *data ); +static void v4l_cleanup( void *data, int emergency ); + +#ifdef DFB_HAVE_V4L2 +static DFBResult v4l2_playto( CoreSurface *surface, DFBRectangle *rect, IDirectFBVideoProvider_V4L_data *data ); +#endif + +static void +IDirectFBVideoProvider_V4L_Destruct( IDirectFBVideoProvider *thiz ) +{ + IDirectFBVideoProvider_V4L_data *data = + (IDirectFBVideoProvider_V4L_data*)thiz->priv; + + if (data->cleanup) + dfb_core_cleanup_remove( NULL, data->cleanup ); + + v4l_deinit( data ); + + D_FREE( data->filename ); + + pthread_mutex_destroy( &data->lock ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); +} + +static DirectResult +IDirectFBVideoProvider_V4L_AddRef( IDirectFBVideoProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + data->ref++; + + return DFB_OK; +} + +static DirectResult +IDirectFBVideoProvider_V4L_Release( IDirectFBVideoProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + if (--data->ref == 0) { + IDirectFBVideoProvider_V4L_Destruct( thiz ); + } + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_V4L_GetCapabilities( IDirectFBVideoProvider *thiz, + DFBVideoProviderCapabilities *caps ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + if (!caps) + return DFB_INVARG; + +#ifdef DFB_HAVE_V4L2 + if (data->is_v4l2) { + *caps = 0; + + data->saturation.id = V4L2_CID_SATURATION; + if (ioctl( data->fd, VIDIOC_G_CTRL, &data->saturation )) { + *caps |= DVCAPS_SATURATION; + } + else { + data->saturation.id = 0; + } + data->brightness.id = V4L2_CID_BRIGHTNESS; + if (ioctl( data->fd, VIDIOC_G_CTRL, &data->brightness )) { + *caps |= DVCAPS_BRIGHTNESS; + } + else { + data->brightness.id = 0; + } + data->contrast.id = V4L2_CID_CONTRAST; + if (ioctl( data->fd, VIDIOC_G_CTRL, &data->contrast )) { + *caps |= DVCAPS_CONTRAST; + } + else { + data->contrast.id = 0; + } + data->hue.id = V4L2_CID_HUE; + if (ioctl( data->fd, VIDIOC_G_CTRL, &data->hue )) { + *caps |= DVCAPS_HUE; + } + else { + data->hue.id = 0; + } + /* fixme: interlaced might not be true for field capture */ + *caps |= DVCAPS_BASIC | DVCAPS_SCALE | DVCAPS_INTERLACED; + } + else +#endif + { + *caps = ( DVCAPS_BASIC | + DVCAPS_BRIGHTNESS | + DVCAPS_CONTRAST | + DVCAPS_HUE | + DVCAPS_SATURATION | + DVCAPS_INTERLACED ); + + if (data->vcap.type & VID_TYPE_SCALES) + *caps |= DVCAPS_SCALE; + } + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_V4L_GetSurfaceDescription( IDirectFBVideoProvider *thiz, + DFBSurfaceDescription *desc ) +{ + IDirectFBVideoProvider_V4L_data *data; + + if (!thiz || !desc) + return DFB_INVARG; + + data = (IDirectFBVideoProvider_V4L_data*)thiz->priv; + + if (!data) + return DFB_DEAD; + + desc->flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS; +#ifdef DFB_HAVE_V4L2 + if (data->is_v4l2) { + desc->width = 720; /* fimxe: depends on the selected standard: query standard and set accordingly */ + desc->height = 576; + } + else +#endif + { + desc->width = data->vcap.maxwidth; + desc->height = data->vcap.maxheight; + } + desc->pixelformat = dfb_primary_layer_pixelformat(); + desc->caps = DSCAPS_INTERLACED; + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_V4L_GetStreamDescription( IDirectFBVideoProvider *thiz, + DFBStreamDescription *desc ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + if (!desc) + return DFB_INVARG; + + desc->caps = DVSCAPS_VIDEO; + + desc->video.encoding[0] = 0; + desc->video.framerate = 10; // assume 10fps +#ifdef DFB_HAVE_V4L2 + desc->video.aspect = 720.0/576.0; +#else + desc->video.aspect = (double)data->vcap.maxwidth / + (double)data->vcap.maxheight; +#endif + desc->video.bitrate = 0; + + desc->title[0] = desc->author[0] = desc->album[0] = + desc->year = desc->genre[0] = desc->comment[0] = 0; + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_V4L_PlayTo( IDirectFBVideoProvider *thiz, + IDirectFBSurface *destination, + const DFBRectangle *dstrect, + DVFrameCallback callback, + void *ctx ) +{ + DFBRectangle rect; + IDirectFBSurface_data *dst_data; + CoreSurface *surface = 0; + DFBResult ret; + + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + if (!destination) + return DFB_INVARG; + + dst_data = (IDirectFBSurface_data*)destination->priv; + + if (!dst_data) + return DFB_DEAD; + + if (!dst_data->area.current.w || !dst_data->area.current.h) + return DFB_INVAREA; + + if (dstrect) { + if (dstrect->w < 1 || dstrect->h < 1) + return DFB_INVARG; + + rect = *dstrect; + + rect.x += dst_data->area.wanted.x; + rect.y += dst_data->area.wanted.y; + } + else + rect = dst_data->area.wanted; + + if (!dfb_rectangle_intersect( &rect, &dst_data->area.current )) + return DFB_INVAREA; + + v4l_stop( data, true ); + + pthread_mutex_lock( &data->lock ); + + data->callback = callback; + data->ctx = ctx; + + surface = dst_data->surface; + +#ifdef DFB_HAVE_V4L2 + if (data->is_v4l2) { + ret = v4l2_playto( surface, &rect, data ); + } + else +#endif + { + data->grab_mode = false; + if (getenv( "DFB_V4L_GRAB" ) || + (surface->config.caps & DSCAPS_SYSTEMONLY) || + (surface->config.caps & DSCAPS_FLIPPING) || + !(VID_TYPE_OVERLAY & data->vcap.type)) + data->grab_mode = true; + else { + /* + * Because we're constantly writing to the surface we + * permanently lock it. + */ + ret = dfb_surface_lock_buffer( surface, CSBR_BACK, CSAID_GPU, + CSAF_WRITE, &data->destinationlock ); + + if (ret) { + pthread_mutex_unlock( &data->lock ); + return ret; + } + } + + if (data->grab_mode) + ret = v4l_to_surface_grab( surface, &rect, data ); + else + ret = v4l_to_surface_overlay( surface, &rect, data ); + } + if (ret && !data->grab_mode) + dfb_surface_unlock_buffer( surface, &data->destinationlock ); + + pthread_mutex_unlock( &data->lock ); + + return ret; +} + +static DFBResult +IDirectFBVideoProvider_V4L_Stop( IDirectFBVideoProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + return v4l_stop( data, true ); +} + +static DFBResult +IDirectFBVideoProvider_V4L_GetStatus( IDirectFBVideoProvider *thiz, + DFBVideoProviderStatus *status ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + if (!status) + return DFB_INVARG; + + *status = data->running ? DVSTATE_PLAY : DVSTATE_STOP; + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_V4L_SeekTo( IDirectFBVideoProvider *thiz, + double seconds ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + return DFB_UNIMPLEMENTED; +} + +static DFBResult +IDirectFBVideoProvider_V4L_GetPos( IDirectFBVideoProvider *thiz, + double *seconds ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + return DFB_UNSUPPORTED; +} + +static DFBResult +IDirectFBVideoProvider_V4L_GetLength( IDirectFBVideoProvider *thiz, + double *seconds ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + return DFB_UNSUPPORTED; +} + +static DFBResult +IDirectFBVideoProvider_V4L_GetColorAdjustment( IDirectFBVideoProvider *thiz, + DFBColorAdjustment *adj ) +{ + struct video_picture pic; + + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + if (!adj) + return DFB_INVARG; + +#ifdef DFB_HAVE_V4L2 + if (data->is_v4l2) { + struct v4l2_control ctrl; + + if (data->brightness.id) { + ctrl.id = data->brightness.id; + if (!ioctl( data->fd, VIDIOC_G_CTRL, &ctrl )) { + adj->flags |= DCAF_BRIGHTNESS; + adj->brightness = 0xffff * ctrl.value / (data->brightness.maximum - data->brightness.minimum); + } + } + if (data->contrast.id) { + ctrl.id = data->contrast.id; + if (!ioctl( data->fd, VIDIOC_G_CTRL, &ctrl )) { + adj->flags |= DCAF_CONTRAST; + adj->contrast = 0xffff * ctrl.value / (data->contrast.maximum - data->contrast.minimum); + } + } + if (data->hue.id) { + ctrl.id = data->hue.id; + if (!ioctl( data->fd, VIDIOC_G_CTRL, &ctrl )) { + adj->flags |= DCAF_HUE; + adj->hue = 0xffff * ctrl.value / (data->hue.maximum - data->hue.minimum); + } + } + if (data->saturation.id) { + ctrl.id = data->saturation.id; + if (!ioctl( data->fd, VIDIOC_G_CTRL, &ctrl )) { + adj->flags |= DCAF_SATURATION; + adj->saturation = 0xffff * ctrl.value / (data->saturation.maximum - data->saturation.minimum); + } + } + } + else +#endif + { + ioctl( data->fd, VIDIOCGPICT, &pic ); + + adj->flags = DCAF_BRIGHTNESS | DCAF_CONTRAST | DCAF_HUE | DCAF_SATURATION; + + adj->brightness = pic.brightness; + adj->contrast = pic.contrast; + adj->hue = pic.hue; + adj->saturation = pic.colour; + } + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_V4L_SetColorAdjustment( IDirectFBVideoProvider *thiz, + const DFBColorAdjustment *adj ) +{ + struct video_picture pic; + + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + if (!adj) + return DFB_INVARG; + + if (adj->flags == DCAF_NONE) + return DFB_OK; + +#ifdef DFB_HAVE_V4L2 + if (data->is_v4l2) { + struct v4l2_control ctrl; + if ((adj->flags & DCAF_BRIGHTNESS) && data->brightness.id) { + ctrl.id = data->brightness.id; + ctrl.value = (adj->brightness * (data->brightness.maximum - data->brightness.minimum)) / 0xfff; + ioctl( data->fd, VIDIOC_S_CTRL, &ctrl ); + } + if ((adj->flags & DCAF_CONTRAST) && data->contrast.id) { + ctrl.id = data->contrast.id; + ctrl.value = (adj->contrast * (data->contrast.maximum - data->contrast.minimum)) / 0xfff; + ioctl( data->fd, VIDIOC_S_CTRL, &ctrl ); + } + if ((adj->flags & DCAF_HUE) && data->hue.id) { + ctrl.id = data->hue.id; + ctrl.value = (adj->hue * (data->hue.maximum - data->hue.minimum)) / 0xfff; + ioctl( data->fd, VIDIOC_S_CTRL, &ctrl ); + } + if ((adj->flags & DCAF_SATURATION) && data->saturation.id) { + ctrl.id = data->saturation.id; + ctrl.value = (adj->saturation * (data->saturation.maximum - data->saturation.minimum)) / 0xfff; + ioctl( data->fd, VIDIOC_S_CTRL, &ctrl ); + } + } + else +#endif + { + if (ioctl( data->fd, VIDIOCGPICT, &pic ) < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux: VIDIOCGPICT failed!\n" ); + + return ret; + } + + if (adj->flags & DCAF_BRIGHTNESS) pic.brightness = adj->brightness; + if (adj->flags & DCAF_CONTRAST) pic.contrast = adj->contrast; + if (adj->flags & DCAF_HUE) pic.hue = adj->hue; + if (adj->flags & DCAF_SATURATION) pic.colour = adj->saturation; + + if (ioctl( data->fd, VIDIOCSPICT, &pic ) < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux: VIDIOCSPICT failed!\n" ); + + return ret; + } + } + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_V4L_SendEvent( IDirectFBVideoProvider *thiz, + const DFBEvent *evt ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + return DFB_UNSUPPORTED; +} + + +/* exported symbols */ + +static DFBResult +Probe( IDirectFBVideoProvider_ProbeContext *ctx ) +{ + if (ctx->filename) { + if (strncmp( ctx->filename, "/dev/video", 10 ) == 0) + return DFB_OK; + + if (strncmp( ctx->filename, "/dev/v4l/video", 14 ) == 0) + return DFB_OK; + } + + return DFB_UNSUPPORTED; +} + +static DFBResult +Construct( IDirectFBVideoProvider *thiz, ... ) +{ + int fd; + IDirectFBDataBuffer *buffer; + IDirectFBDataBuffer_data *buffer_data; + CoreDFB *core; + va_list tag; + + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBVideoProvider_V4L) + + va_start( tag, thiz ); + buffer = va_arg( tag, IDirectFBDataBuffer * ); + core = va_arg( tag, CoreDFB * ); + va_end( tag ); + + + data->ref = 1; + data->core = core; + + buffer_data = (IDirectFBDataBuffer_data*) buffer->priv; + + fd = open( buffer_data->filename, O_RDWR ); + if (fd < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux: Cannot open `%s'!\n", + buffer_data->filename ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); + return ret; + } + + direct_util_recursive_pthread_mutex_init( &data->lock ); + +#ifdef DFB_HAVE_V4L2 + data->is_v4l2 = 0; + + /* look if the device is a v4l2 device */ + if (!ioctl( fd, VIDIOC_QUERYCAP, &data->caps )) { + D_INFO( "DirectFB/Video4Linux: This is a Video4Linux-2 device.\n" ); + data->is_v4l2 = 1; + } + + if (data->is_v4l2) { + /* hmm, anything to do here? */ + } + else +#endif + { + D_INFO( "DirectFB/Video4Linux: This is a Video4Linux-1 device.\n" ); + + ioctl( fd, VIDIOCGCAP, &data->vcap ); + ioctl( fd, VIDIOCCAPTURE, &zero ); + + ioctl( fd, VIDIOCGMBUF, &data->vmbuf ); + + data->buffer = mmap( NULL, data->vmbuf.size, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 ); + } + + data->filename = D_STRDUP( buffer_data->filename ); + data->fd = fd; + + thiz->AddRef = IDirectFBVideoProvider_V4L_AddRef; + thiz->Release = IDirectFBVideoProvider_V4L_Release; + thiz->GetCapabilities = IDirectFBVideoProvider_V4L_GetCapabilities; + thiz->GetSurfaceDescription = IDirectFBVideoProvider_V4L_GetSurfaceDescription; + thiz->GetStreamDescription = IDirectFBVideoProvider_V4L_GetStreamDescription; + thiz->PlayTo = IDirectFBVideoProvider_V4L_PlayTo; + thiz->Stop = IDirectFBVideoProvider_V4L_Stop; + thiz->GetStatus = IDirectFBVideoProvider_V4L_GetStatus; + thiz->SeekTo = IDirectFBVideoProvider_V4L_SeekTo; + thiz->GetPos = IDirectFBVideoProvider_V4L_GetPos; + thiz->GetLength = IDirectFBVideoProvider_V4L_GetLength; + thiz->GetColorAdjustment = IDirectFBVideoProvider_V4L_GetColorAdjustment; + thiz->SetColorAdjustment = IDirectFBVideoProvider_V4L_SetColorAdjustment; + thiz->SendEvent = IDirectFBVideoProvider_V4L_SendEvent; + + return DFB_OK; +} + + +/*****************/ + +/* + * bogus thread to generate callback, + * because video4linux does not support syncing in overlay mode + */ +static void * +OverlayThread( DirectThread *thread, void *ctx ) +{ + IDirectFBVideoProvider_V4L_data *data = (IDirectFBVideoProvider_V4L_data*)ctx; + + int field = 0; + struct timeval tv; + + while (data->running) { + tv.tv_sec = 0; + tv.tv_usec = 20000; + select( 0, 0, 0, 0, &tv ); + + if (!data->running) + break; + + if (data->destination && + (data->destination->config.caps & DSCAPS_INTERLACED)) { + dfb_surface_set_field( data->destination, field ); + + field = !field; + } + + if (!data->running) + break; + + if (data->callback) + data->callback( data->ctx ); + } + + return NULL; +} + +/* + * thread to capture data from v4l buffers and generate callback + */ +static void * +GrabThread( DirectThread *thread, void *ctx ) +{ + IDirectFBVideoProvider_V4L_data *data = (IDirectFBVideoProvider_V4L_data*)ctx; + CoreSurface *surface = data->destination; + void *src, *dst; + int dst_pitch, src_pitch, h; + int frame = 0; + + D_DEBUG( "DirectFB/Video4Linux: %s started.\n", __FUNCTION__ ); + + src_pitch = DFB_BYTES_PER_LINE( surface->config.format, surface->config.size.w ); + + while (frame < data->vmbuf.frames) { + data->vmmap.frame = frame; + ioctl( data->fd, VIDIOCMCAPTURE, &data->vmmap ); + frame++; + } + + if (dfb_surface_ref( surface )) { + D_ERROR( "DirectFB/Video4Linux: dfb_surface_ref() failed!\n" ); + return NULL; + } + + frame = 0; + while (data->running) { + ioctl( data->fd, VIDIOCSYNC, &frame ); + + if (!data->running) + break; + + h = surface->config.size.h; + src = data->buffer + data->vmbuf.offsets[frame]; + + dfb_surface_lock_buffer( surface, CSBR_BACK, CSAID_CPU, + CSAF_WRITE, &data->destinationlock ); + dst = data->destinationlock.addr; + dst_pitch = data->destinationlock.pitch; + + while (h--) { + direct_memcpy( dst, src, src_pitch ); + dst += dst_pitch; + src += src_pitch; + } + if (surface->config.format == DSPF_I420) { + h = surface->config.size.h; + while (h--) { + direct_memcpy( dst, src, src_pitch >> 1 ); + dst += dst_pitch >> 1; + src += src_pitch >> 1; + } + } + else if (surface->config.format == DSPF_YV12) { + h = surface->config.size.h >> 1; + src += h * (src_pitch >> 1); + while (h--) { + direct_memcpy( dst, src, src_pitch >> 1 ); + dst += dst_pitch >> 1; + src += src_pitch >> 1; + } + h = surface->config.size.h >> 1; + src -= 2 * h * (src_pitch >> 1); + while (h--) { + direct_memcpy( dst, src, src_pitch >> 1 ); + dst += dst_pitch >> 1; + src += src_pitch >> 1; + } + } + dfb_surface_unlock_buffer( surface, &data->destinationlock ); + + data->vmmap.frame = frame; + ioctl( data->fd, VIDIOCMCAPTURE, &data->vmmap ); + + if (!data->running) + break; + + if (surface->config.caps & DSCAPS_INTERLACED) + dfb_surface_set_field( surface, 0 ); + + if (data->callback) + data->callback( data->ctx ); + + if (!data->running) + break; + + sched_yield(); + + if (surface->config.caps & DSCAPS_INTERLACED) { + if (!data->running) + break; + + dfb_surface_set_field( surface, 1 ); + + if (data->callback) + data->callback( data->ctx ); + + if (!data->running) + break; + + sched_yield(); + } + + if (++frame == data->vmbuf.frames) + frame = 0; + } + + dfb_surface_unref( surface ); + + return NULL; +} + +static ReactionResult +v4l_videosurface_listener( const void *msg_data, void *ctx ) +{ +// const CoreSurfaceNotification *notification = msg_data; +// IDirectFBVideoProvider_V4L_data *data = ctx; +// CoreSurface *surface = notification->surface; + + /* + if ((notification->flags & CSNF_SIZEFORMAT) || + (surface->back_buffer->video.health != CSH_STORED)) { + v4l_stop( data, false ); + return RS_REMOVE; + } + */ + + return RS_OK; +} + +static ReactionResult +v4l_systemsurface_listener( const void *msg_data, void *ctx ) +{ +// const CoreSurfaceNotification *notification = msg_data; +// IDirectFBVideoProvider_V4L_data *data = ctx; +// CoreSurface *surface = notification->surface; + + /* + if ((notification->flags & CSNF_SIZEFORMAT) || + (surface->back_buffer->system.health != CSH_STORED && + surface->back_buffer->video.health != CSH_STORED)) { + v4l_stop( data, false ); + return RS_REMOVE; + } + */ + + return RS_OK; +} + + +/************/ + +static DFBResult +v4l_to_surface_overlay( CoreSurface *surface, DFBRectangle *rect, + IDirectFBVideoProvider_V4L_data *data ) +{ + int bpp, palette; + + D_DEBUG( "DirectFB/Video4Linux: %s (%p, %d,%d - %dx%d)\n", __FUNCTION__, + surface, rect->x, rect->y, rect->w, rect->h ); + + /* + * Sanity check. Overlay to system surface isn't possible. + */ + if (surface->config.caps & DSCAPS_SYSTEMONLY) + return DFB_UNSUPPORTED; + + switch (surface->config.format) { + case DSPF_YUY2: + bpp = 16; + palette = VIDEO_PALETTE_YUYV; + break; + case DSPF_UYVY: + bpp = 16; + palette = VIDEO_PALETTE_UYVY; + break; + case DSPF_I420: + bpp = 8; + palette = VIDEO_PALETTE_YUV420P; + break; + case DSPF_ARGB1555: + bpp = 15; + palette = VIDEO_PALETTE_RGB555; + break; + case DSPF_RGB16: + bpp = 16; + palette = VIDEO_PALETTE_RGB565; + break; + case DSPF_RGB24: + bpp = 24; + palette = VIDEO_PALETTE_RGB24; + break; + case DSPF_ARGB: + case DSPF_AiRGB: + case DSPF_RGB32: + bpp = 32; + palette = VIDEO_PALETTE_RGB32; + break; + default: + return DFB_UNSUPPORTED; + } + + { + struct video_buffer b; + + /* in overlay mode, the destinationlock is already taken + * and pointing to the back buffer */ + CoreSurfaceBufferLock *lock = &data->destinationlock; + + b.base = (void*)dfb_gfxcard_memory_physical( NULL, lock->offset ); + b.width = lock->pitch / ((bpp + 7) / 8); + b.height = surface->config.size.h; + b.depth = bpp; + b.bytesperline = lock->pitch; + + if (ioctl( data->fd, VIDIOCSFBUF, &b ) < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux: VIDIOCSFBUF failed, must run being root!\n" ); + + return ret; + } + } + { + struct video_picture p; + + if (ioctl( data->fd, VIDIOCGPICT, &p ) < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux: VIDIOCGPICT failed!\n" ); + + return ret; + } + + p.depth = bpp; + p.palette = palette; + + if (ioctl( data->fd, VIDIOCSPICT, &p ) < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux: VIDIOCSPICT failed!\n" ); + + return ret; + } + } + { + struct video_window win; + + win.width = rect->w; + win.height = rect->h; + win.x = rect->x; + win.y = rect->y; + win.flags = 0; + win.clips = NULL; + win.clipcount = 0; + win.chromakey = 0; + + if (ioctl( data->fd, VIDIOCSWIN, &win ) < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux: VIDIOCSWIN failed!\n" ); + + return ret; + } + } + + if (!data->cleanup) + data->cleanup = dfb_core_cleanup_add( NULL, v4l_cleanup, data, true ); + + if (ioctl( data->fd, VIDIOCCAPTURE, &one ) < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux: Could not start capturing (VIDIOCCAPTURE failed)!\n" ); + + return ret; + } + + data->destination = surface; + + dfb_surface_attach( surface, v4l_videosurface_listener, + data, &data->reaction ); + + data->running = true; + + if (data->callback || (surface->config.caps & DSCAPS_INTERLACED)) + data->thread = direct_thread_create( DTT_CRITICAL, OverlayThread, data, "V4L Overlay" ); + + return DFB_OK; +} + +static DFBResult +v4l_to_surface_grab( CoreSurface *surface, DFBRectangle *rect, + IDirectFBVideoProvider_V4L_data *data ) +{ + int palette; + + D_DEBUG( "DirectFB/Video4Linux: %s...\n", __FUNCTION__ ); + + if (!data->vmbuf.frames) + return DFB_UNSUPPORTED; + + switch (surface->config.format) { + case DSPF_YUY2: + palette = VIDEO_PALETTE_YUYV; + break; + case DSPF_UYVY: + palette = VIDEO_PALETTE_UYVY; + break; + case DSPF_I420: + case DSPF_YV12: + palette = VIDEO_PALETTE_YUV420P; + break; + case DSPF_ARGB1555: + palette = VIDEO_PALETTE_RGB555; + break; + case DSPF_RGB16: + palette = VIDEO_PALETTE_RGB565; + break; + case DSPF_RGB24: + palette = VIDEO_PALETTE_RGB24; + break; + case DSPF_ARGB: + case DSPF_AiRGB: + case DSPF_RGB32: + palette = VIDEO_PALETTE_RGB32; + break; + default: + return DFB_UNSUPPORTED; + } + + data->vmmap.width = surface->config.size.w; + data->vmmap.height = surface->config.size.h; + data->vmmap.format = palette; + data->vmmap.frame = 0; + if (ioctl( data->fd, VIDIOCMCAPTURE, &data->vmmap ) < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux: Could not start capturing (VIDIOCMCAPTURE failed)!\n" ); + + return ret; + } + + if (!data->cleanup) + data->cleanup = dfb_core_cleanup_add( NULL, v4l_cleanup, data, true ); + + data->destination = surface; + + dfb_surface_attach( surface, v4l_systemsurface_listener, + data, &data->reaction ); + + data->running = true; + + data->thread = direct_thread_create( DTT_INPUT, GrabThread, data, "V4L Grabber" ); + + return DFB_OK; +} + +static DFBResult +v4l_stop( IDirectFBVideoProvider_V4L_data *data, bool detach ) +{ + CoreSurface *destination; + + D_DEBUG( "DirectFB/Video4Linux: %s...\n", __FUNCTION__ ); + + pthread_mutex_lock( &data->lock ); + + if (!data->running) { + pthread_mutex_unlock( &data->lock ); + return DFB_OK; + } + + if (data->thread) { + data->running = false; + direct_thread_join( data->thread ); + direct_thread_destroy( data->thread ); + data->thread = NULL; + } + +#ifdef DFB_HAVE_V4L2 + if (data->is_v4l2) { + /* turn off streaming */ + int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + int err = ioctl( data->fd, VIDIOC_STREAMOFF, &type ); + if (err) { + D_PERROR( "DirectFB/Video4Linux2: VIDIOC_STREAMOFF.\n" ); + /* don't quit here */ + } + } + else +#endif + { + if (!data->grab_mode) { + if (ioctl( data->fd, VIDIOCCAPTURE, &zero ) < 0) + D_PERROR( "DirectFB/Video4Linux: " + "Could not stop capturing (VIDIOCCAPTURE failed)!\n" ); + } + } + + destination = data->destination; + + if (!destination) { + pthread_mutex_unlock( &data->lock ); + return DFB_OK; + } + +#ifdef DFB_HAVE_V4L2 + if (data->is_v4l2) { + /* unmap all buffers, if necessary */ + if (data->framebuffer_or_system) { + int i; + for (i = 0; i < data->req.count; i++) { + struct v4l2_buffer *vidbuf = &data->vidbuf[i]; + D_DEBUG( "DirectFB/Video4Linux2: %d => 0x%08x, len:%d\n", i, (u32) data->ptr[i], vidbuf->length ); + if (munmap( data->ptr[i], vidbuf->length )) { + D_PERROR( "DirectFB/Video4Linux2: munmap().\n" ); + } + } + } + else { + dfb_surface_unlock_buffer( destination, &data->destinationlock ); + } + } + else +#endif + { + if (!data->grab_mode) + dfb_surface_unlock_buffer( destination, &data->destinationlock ); + } + + data->destination = NULL; + + pthread_mutex_unlock( &data->lock ); + + if (detach) + dfb_surface_detach( destination, &data->reaction ); + + return DFB_OK; +} + +static void +v4l_deinit( IDirectFBVideoProvider_V4L_data *data ) +{ + if (data->fd == -1) { + D_BUG( "v4l_deinit with 'fd == -1'" ); + return; + } + + v4l_stop( data, true ); + + munmap( data->buffer, data->vmbuf.size ); + close( data->fd ); + data->fd = -1; +} + +static void +v4l_cleanup( void *ctx, int emergency ) +{ + IDirectFBVideoProvider_V4L_data *data = + (IDirectFBVideoProvider_V4L_data*)ctx; + + if (emergency) + v4l_stop( data, false ); + else + v4l_deinit( data ); +} + +/* v4l2 specific stuff */ +#ifdef DFB_HAVE_V4L2 +static int +wait_for_buffer( int vid, struct v4l2_buffer *cur ) +{ + fd_set rdset; + struct timeval timeout; + int n, err; + +// D_DEBUG("DirectFB/Video4Linux2: %s...\n", __FUNCTION__); + + cur->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + FD_ZERO( &rdset ); + FD_SET( vid, &rdset ); + + timeout.tv_sec = 5; + timeout.tv_usec = 0; + + n = select( vid + 1, &rdset, NULL, NULL, &timeout ); + if (n == -1) { + D_PERROR( "DirectFB/Video4Linux2: select().\n" ); + return -1; /* fixme */ + } + else if (n == 0) { + D_PERROR( "DirectFB/Video4Linux2: select(), timeout.\n" ); + return -1; /* fixme */ + } + else if (FD_ISSET( vid, &rdset )) { + err = ioctl( vid, VIDIOC_DQBUF, cur ); + if (err) { + D_PERROR( "DirectFB/Video4Linux2: VIDIOC_DQBUF.\n" ); + return -1; /* fixme */ + } + } + return 0; +} + +static void * +V4L2_Thread( DirectThread *thread, void *ctx ) +{ + int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + int i, err; + + IDirectFBVideoProvider_V4L_data *data = (IDirectFBVideoProvider_V4L_data *) ctx; + CoreSurface *surface = data->destination; + void *src, *dst; + int dst_pitch, src_pitch, h; + + D_DEBUG( "DirectFB/Video4Linux2: %s started.\n", __FUNCTION__ ); + + src_pitch = DFB_BYTES_PER_LINE( surface->config.format, surface->config.size.w ); + + /* Queue all buffers */ + for (i = 0; i < data->req.count; i++) { + struct v4l2_buffer *vidbuf = &data->vidbuf[i]; + + if (!data->framebuffer_or_system) { + vidbuf->m.offset = data->destinationlock.offset; + } + + err = ioctl( data->fd, VIDIOC_QBUF, vidbuf ); + if (err) { + D_PERROR( "DirectFB/Video4Linux2: VIDIOC_QBUF.\n" ); + return NULL; + } + } + + /* start streaming */ + if (ioctl( data->fd, VIDIOC_STREAMON, &type )) { + D_PERROR( "DirectFB/Video4Linux2: VIDIOC_STREAMON.\n" ); + return NULL; /* fixme */ + } + + while (data->running) { + + struct v4l2_buffer cur; + + if (wait_for_buffer( data->fd, &cur )) { + return NULL; + } + + if (data->framebuffer_or_system) { + CoreSurfaceBufferLock lock; + + D_DEBUG( "DirectFB/Video4Linux2: index:%d, to system memory.\n", cur.index ); + + h = surface->config.size.h; + src = data->ptr[cur.index]; + + dfb_surface_lock_buffer( surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock ); + dst = lock.addr; + dst_pitch = lock.pitch; + while (h--) { + direct_memcpy( dst, src, src_pitch ); + dst += dst_pitch; + src += src_pitch; + } + if (surface->config.format == DSPF_I420) { + h = surface->config.size.h; + while (h--) { + direct_memcpy( dst, src, src_pitch >> 1 ); + dst += dst_pitch >> 1; + src += src_pitch >> 1; + } + } + else if (surface->config.format == DSPF_YV12) { + h = surface->config.size.h >> 1; + src += h * (src_pitch >> 1); + while (h--) { + direct_memcpy( dst, src, src_pitch >> 1 ); + dst += dst_pitch >> 1; + src += src_pitch >> 1; + } + h = surface->config.size.h >> 1; + src -= 2 * h * (src_pitch >> 1); + while (h--) { + direct_memcpy( dst, src, src_pitch >> 1 ); + dst += dst_pitch >> 1; + src += src_pitch >> 1; + } + } + else if (surface->config.format == DSPF_NV12 || + surface->config.format == DSPF_NV21) { + h = surface->config.size.h >> 1; + while (h--) { + direct_memcpy( dst, src, src_pitch ); + dst += dst_pitch; + src += src_pitch; + } + } + dfb_surface_unlock_buffer( surface, &lock ); + } + else { + D_DEBUG( "DirectFB/Video4Linux2: index:%d, to overlay surface\n", cur.index ); + } + + if (data->callback) + data->callback( data->ctx ); + + if (ioctl( data->fd, VIDIOC_QBUF, &cur )) { + D_PERROR( "DirectFB/Video4Linux2: VIDIOC_QBUF.\n" ); + return NULL; + } + } + + return NULL; +} + +static DFBResult +v4l2_playto( CoreSurface *surface, DFBRectangle *rect, IDirectFBVideoProvider_V4L_data *data ) +{ + int palette; + + int err; + int i; + + D_DEBUG( "DirectFB/Video4Linux2: %s...\n", __FUNCTION__ ); + + switch (surface->config.format) { + case DSPF_YUY2: + palette = V4L2_PIX_FMT_YUYV; + break; + case DSPF_UYVY: + palette = V4L2_PIX_FMT_UYVY; + break; + case DSPF_I420: + palette = V4L2_PIX_FMT_YUV420; + break; + case DSPF_YV12: + palette = V4L2_PIX_FMT_YVU420; + break; + case DSPF_NV12: + palette = V4L2_PIX_FMT_NV12; + break; + case DSPF_NV21: + palette = V4L2_PIX_FMT_NV21; + break; + case DSPF_RGB332: + palette = V4L2_PIX_FMT_RGB332; + break; + case DSPF_ARGB1555: + palette = V4L2_PIX_FMT_RGB555; + break; + case DSPF_RGB16: + palette = V4L2_PIX_FMT_RGB565; + break; + case DSPF_RGB24: + palette = V4L2_PIX_FMT_BGR24; + break; + case DSPF_ARGB: + case DSPF_AiRGB: + case DSPF_RGB32: + palette = V4L2_PIX_FMT_BGR32; + break; + default: + return DFB_UNSUPPORTED; + } + + err = dfb_surface_lock_buffer( surface, CSBR_BACK, CSAID_GPU, CSAF_WRITE, &data->destinationlock ); + if (err) + return err; + + data->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + data->fmt.fmt.pix.width = surface->config.size.w; + data->fmt.fmt.pix.height = surface->config.size.h; + data->fmt.fmt.pix.pixelformat = palette; + data->fmt.fmt.pix.bytesperline = data->destinationlock.pitch; + data->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; /* fixme: we can do field based capture, too */ + + D_DEBUG( "DirectFB/Video4Linux2: surface->config.size.w:%d, surface->config.size.h:%d.\n", surface->config.size.w, surface->config.size.h ); + + err = ioctl( data->fd, VIDIOC_S_FMT, &data->fmt ); + if (err) { + D_PERROR( "DirectFB/Video4Linux2: VIDIOC_S_FMT.\n" ); + dfb_surface_unlock_buffer( surface, &data->destinationlock ); + return err; + } + + if (data->fmt.fmt.pix.width != surface->config.size.w || data->fmt.fmt.pix.height != surface->config.size.h) { + D_PERROR( "DirectFB/Video4Linux2: driver cannot fulfill application request.\n" ); + dfb_surface_unlock_buffer( surface, &data->destinationlock ); + return DFB_UNSUPPORTED; /* fixme */ + } + + if (data->brightness.id) { + ioctl( data->fd, VIDIOC_G_CTRL, &data->brightness ); + } + if (data->contrast.id) { + ioctl( data->fd, VIDIOC_G_CTRL, &data->contrast ); + } + if (data->saturation.id) { + ioctl( data->fd, VIDIOC_G_CTRL, &data->saturation ); + } + if (data->hue.id) { + ioctl( data->fd, VIDIOC_G_CTRL, &data->hue ); + } + + if (surface->config.caps & DSCAPS_SYSTEMONLY) { + data->framebuffer_or_system = 1; + data->req.memory = V4L2_MEMORY_MMAP; + dfb_surface_unlock_buffer( surface, &data->destinationlock ); + } + else { + struct v4l2_framebuffer fb; + + data->framebuffer_or_system = 0; + data->req.memory = V4L2_MEMORY_OVERLAY; + + fb.base = (void *) dfb_gfxcard_memory_physical( NULL, 0 ); + fb.fmt.width = surface->config.size.w; + fb.fmt.height = surface->config.size.h; + fb.fmt.pixelformat = palette; + + D_DEBUG( "w:%d, h:%d, bpl:%d, base:0x%08lx\n", + fb.fmt.width, fb.fmt.height, fb.fmt.bytesperline, (unsigned long)fb.base ); + + if (ioctl( data->fd, VIDIOC_S_FBUF, &fb ) < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux2: VIDIOC_S_FBUF failed, must run being root!\n" ); + + dfb_surface_unlock_buffer( surface, &data->destinationlock ); + return ret; + } + } + + /* Ask Video Device for Buffers */ + data->req.count = NUMBER_OF_BUFFERS; + data->req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + err = ioctl( data->fd, VIDIOC_REQBUFS, &data->req ); + if (err < 0 || data->req.count < NUMBER_OF_BUFFERS) { + D_PERROR( "DirectFB/Video4Linux2: VIDIOC_REQBUFS: %d, %d.\n", err, data->req.count ); + if (!data->framebuffer_or_system) + dfb_surface_unlock_buffer( surface, &data->destinationlock ); + return err; + } + + /* Query each buffer and map it to the video device if necessary */ + for (i = 0; i < data->req.count; i++) { + struct v4l2_buffer *vidbuf = &data->vidbuf[i]; + + vidbuf->index = i; + vidbuf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + err = ioctl( data->fd, VIDIOC_QUERYBUF, vidbuf ); + if (err < 0) { + D_PERROR( "DirectFB/Video4Linux2: VIDIOC_QUERYBUF.\n" ); + if (!data->framebuffer_or_system) + dfb_surface_unlock_buffer( surface, &data->destinationlock ); + return err; + } + +/* + if (vidbuf->length == 0) { + D_PERROR( "DirectFB/Video4Linux2: length is zero!\n" ); + return -EINVAL; + } +*/ + if (data->framebuffer_or_system) { + data->ptr[i] = mmap( 0, vidbuf->length, PROT_READ | PROT_WRITE, MAP_SHARED, data->fd, vidbuf->m.offset ); + if (data->ptr[i] == MAP_FAILED) { + D_PERROR( "DirectFB/Video4Linux2: mmap().\n" ); + if (!data->framebuffer_or_system) + dfb_surface_unlock_buffer( surface, &data->destinationlock ); + return err; + } + } + D_DEBUG( "DirectFB/Video4Linux2: len:0x%08x, %d => 0x%08x\n", vidbuf->length, i, (u32) data->ptr[i] ); + } + + if (!data->cleanup) + data->cleanup = dfb_core_cleanup_add( NULL, v4l_cleanup, data, true ); + + data->destination = surface; + + dfb_surface_attach( surface, v4l_systemsurface_listener, data, &data->reaction ); + + data->running = true; + + data->thread = direct_thread_create( DTT_DEFAULT, V4L2_Thread, data, "Video4Linux 2" ); + + return DFB_OK; +} +#endif diff --git a/Source/DirectFB/interfaces/IDirectFBVideoProvider/videodev.h b/Source/DirectFB/interfaces/IDirectFBVideoProvider/videodev.h new file mode 100755 index 0000000..c5ad64f --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBVideoProvider/videodev.h @@ -0,0 +1,353 @@ +#ifndef __LINUX_VIDEODEV_H +#define __LINUX_VIDEODEV_H + +#include +#include + +#define HAVE_V4L2 1 +#include "videodev2.h" + +#define VID_TYPE_CAPTURE 1 /* Can capture */ +#define VID_TYPE_TUNER 2 /* Can tune */ +#define VID_TYPE_TELETEXT 4 /* Does teletext */ +#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */ +#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */ +#define VID_TYPE_CLIPPING 32 /* Can clip */ +#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */ +#define VID_TYPE_SCALES 128 /* Scalable */ +#define VID_TYPE_MONOCHROME 256 /* Monochrome only */ +#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */ +#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */ +#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */ +#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */ +#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */ + +struct video_capability +{ + char name[32]; + int type; + int channels; /* Num channels */ + int audios; /* Num audio devices */ + int maxwidth; /* Supported width */ + int maxheight; /* And height */ + int minwidth; /* Supported width */ + int minheight; /* And height */ +}; + + +struct video_channel +{ + int channel; + char name[32]; + int tuners; + __u32 flags; +#define VIDEO_VC_TUNER 1 /* Channel has a tuner */ +#define VIDEO_VC_AUDIO 2 /* Channel has audio */ + __u16 type; +#define VIDEO_TYPE_TV 1 +#define VIDEO_TYPE_CAMERA 2 + __u16 norm; /* Norm set by channel */ +}; + +struct video_tuner +{ + int tuner; + char name[32]; + unsigned long rangelow, rangehigh; /* Tuner range */ + __u32 flags; +#define VIDEO_TUNER_PAL 1 +#define VIDEO_TUNER_NTSC 2 +#define VIDEO_TUNER_SECAM 4 +#define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */ +#define VIDEO_TUNER_NORM 16 /* Tuner can set norm */ +#define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */ +#define VIDEO_TUNER_RDS_ON 256 /* Tuner is seeing an RDS datastream */ +#define VIDEO_TUNER_MBS_ON 512 /* Tuner is seeing an MBS datastream */ + __u16 mode; /* PAL/NTSC/SECAM/OTHER */ +#define VIDEO_MODE_PAL 0 +#define VIDEO_MODE_NTSC 1 +#define VIDEO_MODE_SECAM 2 +#define VIDEO_MODE_AUTO 3 + __u16 signal; /* Signal strength 16bit scale */ +}; + +struct video_picture +{ + __u16 brightness; + __u16 hue; + __u16 colour; + __u16 contrast; + __u16 whiteness; /* Black and white only */ + __u16 depth; /* Capture depth */ + __u16 palette; /* Palette in use */ +#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */ +#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */ +#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */ +#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */ +#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */ +#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */ +#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */ +#define VIDEO_PALETTE_YUYV 8 +#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */ +#define VIDEO_PALETTE_YUV420 10 +#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */ +#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */ +#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */ +#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */ +#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */ +#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */ +#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */ +#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */ +}; + +struct video_audio +{ + int audio; /* Audio channel */ + __u16 volume; /* If settable */ + __u16 bass, treble; + __u32 flags; +#define VIDEO_AUDIO_MUTE 1 +#define VIDEO_AUDIO_MUTABLE 2 +#define VIDEO_AUDIO_VOLUME 4 +#define VIDEO_AUDIO_BASS 8 +#define VIDEO_AUDIO_TREBLE 16 +#define VIDEO_AUDIO_BALANCE 32 + char name[16]; +#define VIDEO_SOUND_MONO 1 +#define VIDEO_SOUND_STEREO 2 +#define VIDEO_SOUND_LANG1 4 +#define VIDEO_SOUND_LANG2 8 + __u16 mode; + __u16 balance; /* Stereo balance */ + __u16 step; /* Step actual volume uses */ +}; + +struct video_clip +{ + __s32 x,y; + __s32 width, height; + struct video_clip *next; /* For user use/driver use only */ +}; + +struct video_window +{ + __u32 x,y; /* Position of window */ + __u32 width,height; /* Its size */ + __u32 chromakey; + __u32 flags; + struct video_clip *clips; /* Set only */ + int clipcount; +#define VIDEO_WINDOW_INTERLACE 1 +#define VIDEO_WINDOW_CHROMAKEY 16 /* Overlay by chromakey */ +#define VIDEO_CLIP_BITMAP -1 +/* bitmap is 1024x625, a '1' bit represents a clipped pixel */ +#define VIDEO_CLIPMAP_SIZE (128 * 625) +}; + +struct video_capture +{ + __u32 x,y; /* Offsets into image */ + __u32 width, height; /* Area to capture */ + __u16 decimation; /* Decimation divider */ + __u16 flags; /* Flags for capture */ +#define VIDEO_CAPTURE_ODD 0 /* Temporal */ +#define VIDEO_CAPTURE_EVEN 1 +}; + +struct video_buffer +{ + void *base; + int height,width; + int depth; + int bytesperline; +}; + +struct video_mmap +{ + unsigned int frame; /* Frame (0 - n) for double buffer */ + int height,width; + unsigned int format; /* should be VIDEO_PALETTE_* */ +}; + +struct video_key +{ + __u8 key[8]; + __u32 flags; +}; + + +#define VIDEO_MAX_FRAME 32 + +struct video_mbuf +{ + int size; /* Total memory to map */ + int frames; /* Frames */ + int offsets[VIDEO_MAX_FRAME]; +}; + + +#define VIDEO_NO_UNIT (-1) + + +struct video_unit +{ + int video; /* Video minor */ + int vbi; /* VBI minor */ + int radio; /* Radio minor */ + int audio; /* Audio minor */ + int teletext; /* Teletext minor */ +}; + +struct vbi_format { + __u32 sampling_rate; /* in Hz */ + __u32 samples_per_line; + __u32 sample_format; /* VIDEO_PALETTE_RAW only (1 byte) */ + __s32 start[2]; /* starting line for each frame */ + __u32 count[2]; /* count of lines for each frame */ + __u32 flags; +#define VBI_UNSYNC 1 /* can distingues between top/bottom field */ +#define VBI_INTERLACED 2 /* lines are interlaced */ +}; + +/* video_info is biased towards hardware mpeg encode/decode */ +/* but it could apply generically to any hardware compressor/decompressor */ +struct video_info +{ + __u32 frame_count; /* frames output since decode/encode began */ + __u32 h_size; /* current unscaled horizontal size */ + __u32 v_size; /* current unscaled veritcal size */ + __u32 smpte_timecode; /* current SMPTE timecode (for current GOP) */ + __u32 picture_type; /* current picture type */ + __u32 temporal_reference; /* current temporal reference */ + __u8 user_data[256]; /* user data last found in compressed stream */ + /* user_data[0] contains user data flags, user_data[1] has count */ +}; + +/* generic structure for setting playback modes */ +struct video_play_mode +{ + int mode; + int p1; + int p2; +}; + +/* for loading microcode / fpga programming */ +struct video_code +{ + char loadwhat[16]; /* name or tag of file being passed */ + int datasize; + __u8 *data; +}; + +#define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */ +#define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */ +#define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */ +#define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */ +#define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */ +#define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */ +#define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */ +#define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */ +#define VIDIOCGWIN _IOR('v',9, struct video_window) /* Get the video overlay window */ +#define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */ +#define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */ +#define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */ +#define VIDIOCKEY _IOR('v',13, struct video_key) /* Video key event - to dev 255 is to all - cuts capture on all DMA windows with this key (0xFFFFFFFF == all) */ +#define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */ +#define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */ +#define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */ +#define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */ +#define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */ +#define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */ +#define VIDIOCGMBUF _IOR('v',20, struct video_mbuf) /* Memory map buffer info */ +#define VIDIOCGUNIT _IOR('v',21, struct video_unit) /* Get attached units */ +#define VIDIOCGCAPTURE _IOR('v',22, struct video_capture) /* Get subcapture */ +#define VIDIOCSCAPTURE _IOW('v',23, struct video_capture) /* Set subcapture */ +#define VIDIOCSPLAYMODE _IOW('v',24, struct video_play_mode) /* Set output video mode/feature */ +#define VIDIOCSWRITEMODE _IOW('v',25, int) /* Set write mode */ +#define VIDIOCGPLAYINFO _IOR('v',26, struct video_info) /* Get current playback info from hardware */ +#define VIDIOCSMICROCODE _IOW('v',27, struct video_code) /* Load microcode into hardware */ +#define VIDIOCGVBIFMT _IOR('v',28, struct vbi_format) /* Get VBI information */ +#define VIDIOCSVBIFMT _IOW('v',29, struct vbi_format) /* Set VBI information */ + + +#define BASE_VIDIOCPRIVATE 192 /* 192-255 are private */ + +/* VIDIOCSWRITEMODE */ +#define VID_WRITE_MPEG_AUD 0 +#define VID_WRITE_MPEG_VID 1 +#define VID_WRITE_OSD 2 +#define VID_WRITE_TTX 3 +#define VID_WRITE_CC 4 +#define VID_WRITE_MJPEG 5 + +/* VIDIOCSPLAYMODE */ +#define VID_PLAY_VID_OUT_MODE 0 + /* p1: = VIDEO_MODE_PAL, VIDEO_MODE_NTSC, etc ... */ +#define VID_PLAY_GENLOCK 1 + /* p1: 0 = OFF, 1 = ON */ + /* p2: GENLOCK FINE DELAY value */ +#define VID_PLAY_NORMAL 2 +#define VID_PLAY_PAUSE 3 +#define VID_PLAY_SINGLE_FRAME 4 +#define VID_PLAY_FAST_FORWARD 5 +#define VID_PLAY_SLOW_MOTION 6 +#define VID_PLAY_IMMEDIATE_NORMAL 7 +#define VID_PLAY_SWITCH_CHANNELS 8 +#define VID_PLAY_FREEZE_FRAME 9 +#define VID_PLAY_STILL_MODE 10 +#define VID_PLAY_MASTER_MODE 11 + /* p1: see below */ +#define VID_PLAY_MASTER_NONE 1 +#define VID_PLAY_MASTER_VIDEO 2 +#define VID_PLAY_MASTER_AUDIO 3 +#define VID_PLAY_ACTIVE_SCANLINES 12 + /* p1 = first active; p2 = last active */ +#define VID_PLAY_RESET 13 +#define VID_PLAY_END_MARK 14 + + + +#define VID_HARDWARE_BT848 1 +#define VID_HARDWARE_QCAM_BW 2 +#define VID_HARDWARE_PMS 3 +#define VID_HARDWARE_QCAM_C 4 +#define VID_HARDWARE_PSEUDO 5 +#define VID_HARDWARE_SAA5249 6 +#define VID_HARDWARE_AZTECH 7 +#define VID_HARDWARE_SF16MI 8 +#define VID_HARDWARE_RTRACK 9 +#define VID_HARDWARE_ZOLTRIX 10 +#define VID_HARDWARE_SAA7146 11 +#define VID_HARDWARE_VIDEUM 12 /* Reserved for Winnov videum */ +#define VID_HARDWARE_RTRACK2 13 +#define VID_HARDWARE_PERMEDIA2 14 /* Reserved for Permedia2 */ +#define VID_HARDWARE_RIVA128 15 /* Reserved for RIVA 128 */ +#define VID_HARDWARE_PLANB 16 /* PowerMac motherboard video-in */ +#define VID_HARDWARE_BROADWAY 17 /* Broadway project */ +#define VID_HARDWARE_GEMTEK 18 +#define VID_HARDWARE_TYPHOON 19 +#define VID_HARDWARE_VINO 20 /* SGI Indy Vino */ +#define VID_HARDWARE_CADET 21 /* Cadet radio */ +#define VID_HARDWARE_TRUST 22 /* Trust FM Radio */ +#define VID_HARDWARE_TERRATEC 23 /* TerraTec ActiveRadio */ +#define VID_HARDWARE_CPIA 24 +#define VID_HARDWARE_ZR36120 25 /* Zoran ZR36120/ZR36125 */ +#define VID_HARDWARE_ZR36067 26 /* Zoran ZR36067/36060 */ +#define VID_HARDWARE_OV511 27 +#define VID_HARDWARE_ZR356700 28 /* Zoran 36700 series */ +#define VID_HARDWARE_W9966 29 +#define VID_HARDWARE_SE401 30 /* SE401 USB webcams */ +#define VID_HARDWARE_PWC 31 /* Philips webcams */ +#define VID_HARDWARE_MEYE 32 /* Sony Vaio MotionEye cameras */ +#define VID_HARDWARE_CPIA2 33 +#define VID_HARDWARE_VICAM 34 +#define VID_HARDWARE_SF16FMR2 35 +#define VID_HARDWARE_W9968CF 36 +#define VID_HARDWARE_SAA7114H 37 +#endif /* __LINUX_VIDEODEV_H */ + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff --git a/Source/DirectFB/interfaces/IDirectFBVideoProvider/videodev2.h b/Source/DirectFB/interfaces/IDirectFBVideoProvider/videodev2.h new file mode 100755 index 0000000..026b836 --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBVideoProvider/videodev2.h @@ -0,0 +1,897 @@ +#ifndef __LINUX_VIDEODEV2_H +#define __LINUX_VIDEODEV2_H +/* + * Video for Linux Two + * + * Header file for v4l or V4L2 drivers and applications, for + * Linux kernels 2.2.x or 2.4.x. + * + * See http://bytesex.org/v4l/ for API specs and other + * v4l2 documentation. + * + * Author: Bill Dirks + * Justin Schoeman + * et al. + */ + +/* + * M I S C E L L A N E O U S + */ + +/* Four-character-code (FOURCC) */ +#define v4l2_fourcc(a,b,c,d)\ + (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24)) + +/* + * E N U M S + */ +enum v4l2_field { + V4L2_FIELD_ANY = 0, /* driver can choose from none, + top, bottom, interlaced + depending on whatever it thinks + is approximate ... */ + V4L2_FIELD_NONE = 1, /* this device has no fields ... */ + V4L2_FIELD_TOP = 2, /* top field only */ + V4L2_FIELD_BOTTOM = 3, /* bottom field only */ + V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */ + V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one + buffer, top-bottom order */ + V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */ + V4L2_FIELD_ALTERNATE = 7, /* both fields alternating into + separate buffers */ +}; +#define V4L2_FIELD_HAS_TOP(field) \ + ((field) == V4L2_FIELD_TOP ||\ + (field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) +#define V4L2_FIELD_HAS_BOTTOM(field) \ + ((field) == V4L2_FIELD_BOTTOM ||\ + (field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) +#define V4L2_FIELD_HAS_BOTH(field) \ + ((field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) + +enum v4l2_buf_type { + V4L2_BUF_TYPE_VIDEO_CAPTURE = 1, + V4L2_BUF_TYPE_VIDEO_OUTPUT = 2, + V4L2_BUF_TYPE_VIDEO_OVERLAY = 3, + V4L2_BUF_TYPE_VBI_CAPTURE = 4, + V4L2_BUF_TYPE_VBI_OUTPUT = 5, + V4L2_BUF_TYPE_PRIVATE = 0x80, +}; + +enum v4l2_ctrl_type { + V4L2_CTRL_TYPE_INTEGER = 1, + V4L2_CTRL_TYPE_BOOLEAN = 2, + V4L2_CTRL_TYPE_MENU = 3, + V4L2_CTRL_TYPE_BUTTON = 4, +}; + +enum v4l2_tuner_type { + V4L2_TUNER_RADIO = 1, + V4L2_TUNER_ANALOG_TV = 2, +}; + +enum v4l2_memory { + V4L2_MEMORY_MMAP = 1, + V4L2_MEMORY_USERPTR = 2, + V4L2_MEMORY_OVERLAY = 3, +}; + +/* see also http://vektor.theorem.ca/graphics/ycbcr/ */ +enum v4l2_colorspace { + /* ITU-R 601 -- broadcast NTSC/PAL */ + V4L2_COLORSPACE_SMPTE170M = 1, + + /* 1125-Line (US) HDTV */ + V4L2_COLORSPACE_SMPTE240M = 2, + + /* HD and modern captures. */ + V4L2_COLORSPACE_REC709 = 3, + + /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */ + V4L2_COLORSPACE_BT878 = 4, + + /* These should be useful. Assume 601 extents. */ + V4L2_COLORSPACE_470_SYSTEM_M = 5, + V4L2_COLORSPACE_470_SYSTEM_BG = 6, + + /* I know there will be cameras that send this. So, this is + * unspecified chromaticities and full 0-255 on each of the + * Y'CbCr components + */ + V4L2_COLORSPACE_JPEG = 7, + + /* For RGB colourspaces, this is probably a good start. */ + V4L2_COLORSPACE_SRGB = 8, +}; + +enum v4l2_priority { + V4L2_PRIORITY_UNSET = 0, /* not initialized */ + V4L2_PRIORITY_BACKGROUND = 1, + V4L2_PRIORITY_INTERACTIVE = 2, + V4L2_PRIORITY_RECORD = 3, + V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE, +}; + +struct v4l2_rect { + __s32 left; + __s32 top; + __s32 width; + __s32 height; +}; + +struct v4l2_fract { + __u32 numerator; + __u32 denominator; +}; + +/* + * D R I V E R C A P A B I L I T I E S + */ +struct v4l2_capability +{ + __u8 driver[16]; /* i.e. "bttv" */ + __u8 card[32]; /* i.e. "Hauppauge WinTV" */ + __u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */ + __u32 version; /* should use KERNEL_VERSION() */ + __u32 capabilities; /* Device capabilities */ + __u32 reserved[4]; +}; + +/* Values for 'capabilities' field */ +#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */ +#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */ +#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */ +#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a VBI capture device */ +#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a VBI output device */ +#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */ + +#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ +#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ +#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */ + +#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ +#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ +#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ + +/* + * V I D E O I M A G E F O R M A T + */ + +struct v4l2_pix_format +{ + __u32 width; + __u32 height; + __u32 pixelformat; + enum v4l2_field field; + __u32 bytesperline; /* for padding, zero if unused */ + __u32 sizeimage; + enum v4l2_colorspace colorspace; + __u32 priv; /* private data, depends on pixelformat */ +}; + +/* Pixel format FOURCC depth Description */ +#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R','G','B','1') /* 8 RGB-3-3-2 */ +#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R','G','B','O') /* 16 RGB-5-5-5 */ +#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R','G','B','P') /* 16 RGB-5-6-5 */ +#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R','G','B','Q') /* 16 RGB-5-5-5 BE */ +#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R','G','B','R') /* 16 RGB-5-6-5 BE */ +#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B','G','R','3') /* 24 BGR-8-8-8 */ +#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R','G','B','3') /* 24 RGB-8-8-8 */ +#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B','G','R','4') /* 32 BGR-8-8-8-8 */ +#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R','G','B','4') /* 32 RGB-8-8-8-8 */ +#define V4L2_PIX_FMT_GREY v4l2_fourcc('G','R','E','Y') /* 8 Greyscale */ +#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y','V','U','9') /* 9 YVU 4:1:0 */ +#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y','V','1','2') /* 12 YVU 4:2:0 */ +#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y','U','Y','V') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U','Y','V','Y') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4','2','2','P') /* 16 YVU422 planar */ +#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4','1','1','P') /* 16 YVU411 planar */ +#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y','4','1','P') /* 12 YUV 4:1:1 */ + +/* two planes -- one Y, one Cr + Cb interleaved */ +#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N','V','1','2') /* 12 Y/CbCr 4:2:0 */ +#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N','V','2','1') /* 12 Y/CrCb 4:2:0 */ + +/* The following formats are not defined in the V4L2 specification */ +#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y','U','V','9') /* 9 YUV 4:1:0 */ +#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y','U','1','2') /* 12 YUV 4:2:0 */ +#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y','Y','U','V') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H','I','2','4') /* 8 8-bit color */ + +/* compressed formats */ +#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M','J','P','G') /* Motion-JPEG */ +#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J','P','E','G') /* JFIF JPEG */ +#define V4L2_PIX_FMT_DV v4l2_fourcc('d','v','s','d') /* 1394 */ +#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M','P','E','G') /* MPEG */ + +/* Vendor-specific formats */ +#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W','N','V','A') /* Winnov hw compress */ + +/* + * F O R M A T E N U M E R A T I O N + */ +struct v4l2_fmtdesc +{ + __u32 index; /* Format number */ + enum v4l2_buf_type type; /* buffer type */ + __u32 flags; + __u8 description[32]; /* Description string */ + __u32 pixelformat; /* Format fourcc */ + __u32 reserved[4]; +}; + +#define V4L2_FMT_FLAG_COMPRESSED 0x0001 + + +/* + * T I M E C O D E + */ +struct v4l2_timecode +{ + __u32 type; + __u32 flags; + __u8 frames; + __u8 seconds; + __u8 minutes; + __u8 hours; + __u8 userbits[4]; +}; + +/* Type */ +#define V4L2_TC_TYPE_24FPS 1 +#define V4L2_TC_TYPE_25FPS 2 +#define V4L2_TC_TYPE_30FPS 3 +#define V4L2_TC_TYPE_50FPS 4 +#define V4L2_TC_TYPE_60FPS 5 + +/* Flags */ +#define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */ +#define V4L2_TC_FLAG_COLORFRAME 0x0002 +#define V4L2_TC_USERBITS_field 0x000C +#define V4L2_TC_USERBITS_USERDEFINED 0x0000 +#define V4L2_TC_USERBITS_8BITCHARS 0x0008 +/* The above is based on SMPTE timecodes */ + + +/* + * C O M P R E S S I O N P A R A M E T E R S + */ +#if 0 +/* ### generic compression settings don't work, there is too much + * ### codec-specific stuff. Maybe reuse that for MPEG codec settings + * ### later ... */ +struct v4l2_compression +{ + __u32 quality; + __u32 keyframerate; + __u32 pframerate; + __u32 reserved[5]; + +/* what we'll need for MPEG, extracted from some postings on + the v4l list (Gert Vervoort, PlasmaJohn). + +system stream: + - type: elementary stream(ES), packatised elementary stream(s) (PES) + program stream(PS), transport stream(TS) + - system bitrate + - PS packet size (DVD: 2048 bytes, VCD: 2324 bytes) + - TS video PID + - TS audio PID + - TS PCR PID + - TS system information tables (PAT, PMT, CAT, NIT and SIT) + - (MPEG-1 systems stream vs. MPEG-2 program stream (TS not supported + by MPEG-1 systems) + +audio: + - type: MPEG (+Layer I,II,III), AC-3, LPCM + - bitrate + - sampling frequency (DVD: 48 Khz, VCD: 44.1 KHz, 32 kHz) + - Trick Modes? (ff, rew) + - Copyright + - Inverse Telecine + +video: + - picturesize (SIF, 1/2 D1, 2/3 D1, D1) and PAL/NTSC norm can be set + through excisting V4L2 controls + - noise reduction, parameters encoder specific? + - MPEG video version: MPEG-1, MPEG-2 + - GOP (Group Of Pictures) definition: + - N: number of frames per GOP + - M: distance between reference (I,P) frames + - open/closed GOP + - quantiser matrix: inter Q matrix (64 bytes) and intra Q matrix (64 bytes) + - quantiser scale: linear or logarithmic + - scanning: alternate or zigzag + - bitrate mode: CBR (constant bitrate) or VBR (variable bitrate). + - target video bitrate for CBR + - target video bitrate for VBR + - maximum video bitrate for VBR - min. quantiser value for VBR + - max. quantiser value for VBR + - adaptive quantisation value + - return the number of bytes per GOP or bitrate for bitrate monitoring + +*/ +}; +#endif + +struct v4l2_jpegcompression +{ + int quality; + + int APPn; /* Number of APP segment to be written, + * must be 0..15 */ + int APP_len; /* Length of data in JPEG APPn segment */ + char APP_data[60]; /* Data in the JPEG APPn segment. */ + + int COM_len; /* Length of data in JPEG COM segment */ + char COM_data[60]; /* Data in JPEG COM segment */ + + __u32 jpeg_markers; /* Which markers should go into the JPEG + * output. Unless you exactly know what + * you do, leave them untouched. + * Inluding less markers will make the + * resulting code smaller, but there will + * be fewer aplications which can read it. + * The presence of the APP and COM marker + * is influenced by APP_len and COM_len + * ONLY, not by this property! */ + +#define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */ +#define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */ +#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */ +#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */ +#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will + * allways use APP0 */ +}; + + +/* + * M E M O R Y - M A P P I N G B U F F E R S + */ +struct v4l2_requestbuffers +{ + __u32 count; + enum v4l2_buf_type type; + enum v4l2_memory memory; + __u32 reserved[2]; +}; + +struct v4l2_buffer +{ + __u32 index; + enum v4l2_buf_type type; + __u32 bytesused; + __u32 flags; + enum v4l2_field field; + struct timeval timestamp; + struct v4l2_timecode timecode; + __u32 sequence; + + /* memory location */ + enum v4l2_memory memory; + union { + __u32 offset; + unsigned long userptr; + } m; + __u32 length; + + __u32 reserved[2]; +}; + +/* Flags for 'flags' field */ +#define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */ +#define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */ +#define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */ +#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */ +#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */ +#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */ +#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */ + +/* + * O V E R L A Y P R E V I E W + */ +struct v4l2_framebuffer +{ + __u32 capability; + __u32 flags; +/* FIXME: in theory we should pass something like PCI device + memory + * region + offset instead of some physical address */ + void* base; + struct v4l2_pix_format fmt; +}; +/* Flags for the 'capability' field. Read only */ +#define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001 +#define V4L2_FBUF_CAP_CHROMAKEY 0x0002 +#define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004 +#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008 +/* Flags for the 'flags' field. */ +#define V4L2_FBUF_FLAG_PRIMARY 0x0001 +#define V4L2_FBUF_FLAG_OVERLAY 0x0002 +#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004 + +struct v4l2_clip +{ + struct v4l2_rect c; + struct v4l2_clip *next; +}; + +struct v4l2_window +{ + struct v4l2_rect w; + enum v4l2_field field; + __u32 chromakey; + struct v4l2_clip *clips; + __u32 clipcount; + void *bitmap; +}; + + +/* + * C A P T U R E P A R A M E T E R S + */ +struct v4l2_captureparm +{ + __u32 capability; /* Supported modes */ + __u32 capturemode; /* Current mode */ + struct v4l2_fract timeperframe; /* Time per frame in .1us units */ + __u32 extendedmode; /* Driver-specific extensions */ + __u32 readbuffers; /* # of buffers for read */ + __u32 reserved[4]; +}; +/* Flags for 'capability' and 'capturemode' fields */ +#define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */ +#define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */ + +struct v4l2_outputparm +{ + __u32 capability; /* Supported modes */ + __u32 outputmode; /* Current mode */ + struct v4l2_fract timeperframe; /* Time per frame in seconds */ + __u32 extendedmode; /* Driver-specific extensions */ + __u32 writebuffers; /* # of buffers for write */ + __u32 reserved[4]; +}; + +/* + * I N P U T I M A G E C R O P P I N G + */ + +struct v4l2_cropcap { + enum v4l2_buf_type type; + struct v4l2_rect bounds; + struct v4l2_rect defrect; + struct v4l2_fract pixelaspect; +}; + +struct v4l2_crop { + enum v4l2_buf_type type; + struct v4l2_rect c; +}; + +/* + * A N A L O G V I D E O S T A N D A R D + */ + +typedef __u64 v4l2_std_id; + +/* one bit for each */ +#define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001) +#define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002) +#define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004) +#define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008) +#define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010) +#define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020) +#define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040) +#define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080) + +#define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100) +#define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200) +#define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400) +#define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800) + +#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000) +#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) + +#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000) +#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000) +#define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000) +#define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000) +#define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000) +#define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000) +#define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000) + +/* ATSC/HDTV */ +#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000) +#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000) + +/* some common needed stuff */ +#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\ + V4L2_STD_PAL_B1 |\ + V4L2_STD_PAL_G) +#define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\ + V4L2_STD_PAL_D1 |\ + V4L2_STD_PAL_K) +#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\ + V4L2_STD_PAL_DK |\ + V4L2_STD_PAL_H |\ + V4L2_STD_PAL_I) +#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\ + V4L2_STD_NTSC_M_JP) +#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\ + V4L2_STD_SECAM_D |\ + V4L2_STD_SECAM_G |\ + V4L2_STD_SECAM_H |\ + V4L2_STD_SECAM_K |\ + V4L2_STD_SECAM_K1 |\ + V4L2_STD_SECAM_L) + +#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\ + V4L2_STD_PAL_60 |\ + V4L2_STD_NTSC) +#define V4L2_STD_625_50 (V4L2_STD_PAL |\ + V4L2_STD_PAL_N |\ + V4L2_STD_PAL_Nc |\ + V4L2_STD_SECAM) + +#define V4L2_STD_UNKNOWN 0 +#define V4L2_STD_ALL (V4L2_STD_525_60 |\ + V4L2_STD_625_50) + +struct v4l2_standard +{ + __u32 index; + v4l2_std_id id; + __u8 name[24]; + struct v4l2_fract frameperiod; /* Frames, not fields */ + __u32 framelines; + __u32 reserved[4]; +}; + + +/* + * V I D E O I N P U T S + */ +struct v4l2_input +{ + __u32 index; /* Which input */ + __u8 name[32]; /* Label */ + __u32 type; /* Type of input */ + __u32 audioset; /* Associated audios (bitfield) */ + __u32 tuner; /* Associated tuner */ + v4l2_std_id std; + __u32 status; + __u32 reserved[4]; +}; +/* Values for the 'type' field */ +#define V4L2_INPUT_TYPE_TUNER 1 +#define V4L2_INPUT_TYPE_CAMERA 2 + +/* field 'status' - general */ +#define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */ +#define V4L2_IN_ST_NO_SIGNAL 0x00000002 +#define V4L2_IN_ST_NO_COLOR 0x00000004 + +/* field 'status' - analog */ +#define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */ +#define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */ + +/* field 'status' - digital */ +#define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */ +#define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */ +#define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */ + +/* field 'status' - VCR and set-top box */ +#define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */ +#define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */ +#define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */ + +/* + * V I D E O O U T P U T S + */ +struct v4l2_output +{ + __u32 index; /* Which output */ + __u8 name[32]; /* Label */ + __u32 type; /* Type of output */ + __u32 audioset; /* Associated audios (bitfield) */ + __u32 modulator; /* Associated modulator */ + v4l2_std_id std; + __u32 reserved[4]; +}; +/* Values for the 'type' field */ +#define V4L2_OUTPUT_TYPE_MODULATOR 1 +#define V4L2_OUTPUT_TYPE_ANALOG 2 +#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 + +/* + * C O N T R O L S + */ +struct v4l2_control +{ + __u32 id; + __s32 value; +}; + +/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ +struct v4l2_queryctrl +{ + __u32 id; + enum v4l2_ctrl_type type; + __u8 name[32]; /* Whatever */ + __s32 minimum; /* Note signedness */ + __s32 maximum; + __s32 step; + __s32 default_value; + __u32 flags; + __u32 reserved[2]; +}; + +/* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */ +struct v4l2_querymenu +{ + __u32 id; + __u32 index; + __u8 name[32]; /* Whatever */ + __u32 reserved; +}; + +/* Control flags */ +#define V4L2_CTRL_FLAG_DISABLED 0x0001 +#define V4L2_CTRL_FLAG_GRABBED 0x0002 + +/* Control IDs defined by V4L2 */ +#define V4L2_CID_BASE 0x00980900 +/* IDs reserved for driver specific controls */ +#define V4L2_CID_PRIVATE_BASE 0x08000000 + +#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0) +#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1) +#define V4L2_CID_SATURATION (V4L2_CID_BASE+2) +#define V4L2_CID_HUE (V4L2_CID_BASE+3) +#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5) +#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6) +#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7) +#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8) +#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9) +#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10) +#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) +#define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12) +#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13) +#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14) +#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15) +#define V4L2_CID_GAMMA (V4L2_CID_BASE+16) +#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* ? Not sure */ +#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17) +#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18) +#define V4L2_CID_GAIN (V4L2_CID_BASE+19) +#define V4L2_CID_HFLIP (V4L2_CID_BASE+20) +#define V4L2_CID_VFLIP (V4L2_CID_BASE+21) +#define V4L2_CID_HCENTER (V4L2_CID_BASE+22) +#define V4L2_CID_VCENTER (V4L2_CID_BASE+23) +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+24) /* last CID + 1 */ + +/* + * T U N I N G + */ +struct v4l2_tuner +{ + __u32 index; + __u8 name[32]; + enum v4l2_tuner_type type; + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 rxsubchans; + __u32 audmode; + __s32 signal; + __s32 afc; + __u32 reserved[4]; +}; + +struct v4l2_modulator +{ + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 txsubchans; + __u32 reserved[4]; +}; + +/* Flags for the 'capability' field */ +#define V4L2_TUNER_CAP_LOW 0x0001 +#define V4L2_TUNER_CAP_NORM 0x0002 +#define V4L2_TUNER_CAP_STEREO 0x0010 +#define V4L2_TUNER_CAP_LANG2 0x0020 +#define V4L2_TUNER_CAP_SAP 0x0020 +#define V4L2_TUNER_CAP_LANG1 0x0040 + +/* Flags for the 'rxsubchans' field */ +#define V4L2_TUNER_SUB_MONO 0x0001 +#define V4L2_TUNER_SUB_STEREO 0x0002 +#define V4L2_TUNER_SUB_LANG2 0x0004 +#define V4L2_TUNER_SUB_SAP 0x0004 +#define V4L2_TUNER_SUB_LANG1 0x0008 + +/* Values for the 'audmode' field */ +#define V4L2_TUNER_MODE_MONO 0x0000 +#define V4L2_TUNER_MODE_STEREO 0x0001 +#define V4L2_TUNER_MODE_LANG2 0x0002 +#define V4L2_TUNER_MODE_SAP 0x0002 +#define V4L2_TUNER_MODE_LANG1 0x0003 + +struct v4l2_frequency +{ + __u32 tuner; + enum v4l2_tuner_type type; + __u32 frequency; + __u32 reserved[8]; +}; + +/* + * A U D I O + */ +struct v4l2_audio +{ + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 mode; + __u32 reserved[2]; +}; +/* Flags for the 'capability' field */ +#define V4L2_AUDCAP_STEREO 0x00001 +#define V4L2_AUDCAP_AVL 0x00002 + +/* Flags for the 'mode' field */ +#define V4L2_AUDMODE_AVL 0x00001 + +struct v4l2_audioout +{ + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 mode; + __u32 reserved[2]; +}; + +/* + * D A T A S E R V I C E S ( V B I ) + * + * Data services API by Michael Schimek + */ + +struct v4l2_vbi_format +{ + __u32 sampling_rate; /* in 1 Hz */ + __u32 offset; + __u32 samples_per_line; + __u32 sample_format; /* V4L2_PIX_FMT_* */ + __s32 start[2]; + __u32 count[2]; + __u32 flags; /* V4L2_VBI_* */ + __u32 reserved[2]; /* must be zero */ +}; + +/* VBI flags */ +#define V4L2_VBI_UNSYNC (1<< 0) +#define V4L2_VBI_INTERLACED (1<< 1) + + +/* + * A G G R E G A T E S T R U C T U R E S + */ + +/* Stream data format + */ +struct v4l2_format +{ + enum v4l2_buf_type type; + union + { + struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE + struct v4l2_window win; // V4L2_BUF_TYPE_VIDEO_OVERLAY + struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE + __u8 raw_data[200]; // user-defined + } fmt; +}; + + +/* Stream type-dependent parameters + */ +struct v4l2_streamparm +{ + enum v4l2_buf_type type; + union + { + struct v4l2_captureparm capture; + struct v4l2_outputparm output; + __u8 raw_data[200]; /* user-defined */ + } parm; +}; + + + +/* + * I O C T L C O D E S F O R V I D E O D E V I C E S + * + */ +#define VIDIOC_QUERYCAP _IOR ('V', 0, struct v4l2_capability) +#define VIDIOC_RESERVED _IO ('V', 1) +#define VIDIOC_ENUM_FMT _IOWR ('V', 2, struct v4l2_fmtdesc) +#define VIDIOC_G_FMT _IOWR ('V', 4, struct v4l2_format) +#define VIDIOC_S_FMT _IOWR ('V', 5, struct v4l2_format) +#if 0 +#define VIDIOC_G_COMP _IOR ('V', 6, struct v4l2_compression) +#define VIDIOC_S_COMP _IOW ('V', 7, struct v4l2_compression) +#endif +#define VIDIOC_REQBUFS _IOWR ('V', 8, struct v4l2_requestbuffers) +#define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer) +#define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer) +#define VIDIOC_S_FBUF _IOW ('V', 11, struct v4l2_framebuffer) +#define VIDIOC_OVERLAY _IOW ('V', 14, int) +#define VIDIOC_QBUF _IOWR ('V', 15, struct v4l2_buffer) +#define VIDIOC_DQBUF _IOWR ('V', 17, struct v4l2_buffer) +#define VIDIOC_STREAMON _IOW ('V', 18, int) +#define VIDIOC_STREAMOFF _IOW ('V', 19, int) +#define VIDIOC_G_PARM _IOWR ('V', 21, struct v4l2_streamparm) +#define VIDIOC_S_PARM _IOWR ('V', 22, struct v4l2_streamparm) +#define VIDIOC_G_STD _IOR ('V', 23, v4l2_std_id) +#define VIDIOC_S_STD _IOW ('V', 24, v4l2_std_id) +#define VIDIOC_ENUMSTD _IOWR ('V', 25, struct v4l2_standard) +#define VIDIOC_ENUMINPUT _IOWR ('V', 26, struct v4l2_input) +#define VIDIOC_G_CTRL _IOWR ('V', 27, struct v4l2_control) +#define VIDIOC_S_CTRL _IOWR ('V', 28, struct v4l2_control) +#define VIDIOC_G_TUNER _IOWR ('V', 29, struct v4l2_tuner) +#define VIDIOC_S_TUNER _IOW ('V', 30, struct v4l2_tuner) +#define VIDIOC_G_AUDIO _IOR ('V', 33, struct v4l2_audio) +#define VIDIOC_S_AUDIO _IOW ('V', 34, struct v4l2_audio) +#define VIDIOC_QUERYCTRL _IOWR ('V', 36, struct v4l2_queryctrl) +#define VIDIOC_QUERYMENU _IOWR ('V', 37, struct v4l2_querymenu) +#define VIDIOC_G_INPUT _IOR ('V', 38, int) +#define VIDIOC_S_INPUT _IOWR ('V', 39, int) +#define VIDIOC_G_OUTPUT _IOR ('V', 46, int) +#define VIDIOC_S_OUTPUT _IOWR ('V', 47, int) +#define VIDIOC_ENUMOUTPUT _IOWR ('V', 48, struct v4l2_output) +#define VIDIOC_G_AUDOUT _IOR ('V', 49, struct v4l2_audioout) +#define VIDIOC_S_AUDOUT _IOW ('V', 50, struct v4l2_audioout) +#define VIDIOC_G_MODULATOR _IOWR ('V', 54, struct v4l2_modulator) +#define VIDIOC_S_MODULATOR _IOW ('V', 55, struct v4l2_modulator) +#define VIDIOC_G_FREQUENCY _IOWR ('V', 56, struct v4l2_frequency) +#define VIDIOC_S_FREQUENCY _IOW ('V', 57, struct v4l2_frequency) +#define VIDIOC_CROPCAP _IOWR ('V', 58, struct v4l2_cropcap) +#define VIDIOC_G_CROP _IOWR ('V', 59, struct v4l2_crop) +#define VIDIOC_S_CROP _IOW ('V', 60, struct v4l2_crop) +#define VIDIOC_G_JPEGCOMP _IOR ('V', 61, struct v4l2_jpegcompression) +#define VIDIOC_S_JPEGCOMP _IOW ('V', 62, struct v4l2_jpegcompression) +#define VIDIOC_QUERYSTD _IOR ('V', 63, v4l2_std_id) +#define VIDIOC_TRY_FMT _IOWR ('V', 64, struct v4l2_format) +#define VIDIOC_ENUMAUDIO _IOWR ('V', 65, struct v4l2_audio) +#define VIDIOC_ENUMAUDOUT _IOWR ('V', 66, struct v4l2_audioout) +#define VIDIOC_G_PRIORITY _IOR ('V', 67, enum v4l2_priority) +#define VIDIOC_S_PRIORITY _IOW ('V', 68, enum v4l2_priority) + +/* for compatibility, will go away some day */ +#define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int) +#define VIDIOC_S_PARM_OLD _IOW ('V', 22, struct v4l2_streamparm) +#define VIDIOC_S_CTRL_OLD _IOW ('V', 28, struct v4l2_control) +#define VIDIOC_G_AUDIO_OLD _IOWR ('V', 33, struct v4l2_audio) +#define VIDIOC_G_AUDOUT_OLD _IOWR ('V', 49, struct v4l2_audioout) +#define VIDIOC_CROPCAP_OLD _IOR ('V', 58, struct v4l2_cropcap) + +#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ + +#endif /* __LINUX_VIDEODEV2_H */ + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ -- cgit